OSDN Git Service

Remove silent_mode. You get the same functionality with "pg_ctl -l
[pg-rex/syncrep.git] / src / backend / utils / misc / guc.c
1 /*--------------------------------------------------------------------
2  * guc.c
3  *
4  * Support for grand unified configuration scheme, including SET
5  * command, configuration file, and command line options.
6  * See src/backend/utils/misc/README for more information.
7  *
8  *
9  * Copyright (c) 2000-2011, PostgreSQL Global Development Group
10  * Written by Peter Eisentraut <peter_e@gmx.net>.
11  *
12  * IDENTIFICATION
13  *        src/backend/utils/misc/guc.c
14  *
15  *--------------------------------------------------------------------
16  */
17 #include "postgres.h"
18
19 #include <ctype.h>
20 #include <float.h>
21 #include <math.h>
22 #include <limits.h>
23 #include <unistd.h>
24 #include <sys/stat.h>
25 #ifdef HAVE_SYSLOG
26 #include <syslog.h>
27 #endif
28
29 #include "access/gin.h"
30 #include "access/transam.h"
31 #include "access/twophase.h"
32 #include "access/xact.h"
33 #include "catalog/namespace.h"
34 #include "commands/async.h"
35 #include "commands/prepare.h"
36 #include "commands/vacuum.h"
37 #include "commands/variable.h"
38 #include "commands/trigger.h"
39 #include "funcapi.h"
40 #include "libpq/auth.h"
41 #include "libpq/be-fsstubs.h"
42 #include "libpq/pqformat.h"
43 #include "miscadmin.h"
44 #include "optimizer/cost.h"
45 #include "optimizer/geqo.h"
46 #include "optimizer/paths.h"
47 #include "optimizer/planmain.h"
48 #include "parser/parse_expr.h"
49 #include "parser/parse_type.h"
50 #include "parser/parser.h"
51 #include "parser/scansup.h"
52 #include "pgstat.h"
53 #include "postmaster/autovacuum.h"
54 #include "postmaster/bgwriter.h"
55 #include "postmaster/postmaster.h"
56 #include "postmaster/syslogger.h"
57 #include "postmaster/walwriter.h"
58 #include "replication/syncrep.h"
59 #include "replication/walreceiver.h"
60 #include "replication/walsender.h"
61 #include "storage/bufmgr.h"
62 #include "storage/standby.h"
63 #include "storage/fd.h"
64 #include "storage/predicate.h"
65 #include "tcop/tcopprot.h"
66 #include "tsearch/ts_cache.h"
67 #include "utils/builtins.h"
68 #include "utils/bytea.h"
69 #include "utils/guc_tables.h"
70 #include "utils/memutils.h"
71 #include "utils/pg_locale.h"
72 #include "utils/plancache.h"
73 #include "utils/portal.h"
74 #include "utils/ps_status.h"
75 #include "utils/tzparser.h"
76 #include "utils/xml.h"
77
78 #ifndef PG_KRB_SRVTAB
79 #define PG_KRB_SRVTAB ""
80 #endif
81 #ifndef PG_KRB_SRVNAM
82 #define PG_KRB_SRVNAM ""
83 #endif
84
85 #define CONFIG_FILENAME "postgresql.conf"
86 #define HBA_FILENAME    "pg_hba.conf"
87 #define IDENT_FILENAME  "pg_ident.conf"
88
89 #ifdef EXEC_BACKEND
90 #define CONFIG_EXEC_PARAMS "global/config_exec_params"
91 #define CONFIG_EXEC_PARAMS_NEW "global/config_exec_params.new"
92 #endif
93
94 /* upper limit for GUC variables measured in kilobytes of memory */
95 /* note that various places assume the byte size fits in a "long" variable */
96 #if SIZEOF_SIZE_T > 4 && SIZEOF_LONG > 4
97 #define MAX_KILOBYTES   INT_MAX
98 #else
99 #define MAX_KILOBYTES   (INT_MAX / 1024)
100 #endif
101
102 /*
103  * Note: MAX_BACKENDS is limited to 2^23-1 because inval.c stores the
104  * backend ID as a 3-byte signed integer.  Even if that limitation were
105  * removed, we still could not exceed INT_MAX/4 because some places compute
106  * 4*MaxBackends without any overflow check.  This is rechecked in
107  * check_maxconnections, since MaxBackends is computed as MaxConnections
108  * plus autovacuum_max_workers plus one (for the autovacuum launcher).
109  */
110 #define MAX_BACKENDS    0x7fffff
111
112 #define KB_PER_MB (1024)
113 #define KB_PER_GB (1024*1024)
114
115 #define MS_PER_S 1000
116 #define S_PER_MIN 60
117 #define MS_PER_MIN (1000 * 60)
118 #define MIN_PER_H 60
119 #define S_PER_H (60 * 60)
120 #define MS_PER_H (1000 * 60 * 60)
121 #define MIN_PER_D (60 * 24)
122 #define S_PER_D (60 * 60 * 24)
123 #define MS_PER_D (1000 * 60 * 60 * 24)
124
125 /* XXX these should appear in other modules' header files */
126 extern bool Log_disconnections;
127 extern int      CommitDelay;
128 extern int      CommitSiblings;
129 extern char *default_tablespace;
130 extern char *temp_tablespaces;
131 extern bool synchronize_seqscans;
132 extern bool fullPageWrites;
133 extern int      ssl_renegotiation_limit;
134 extern char *SSLCipherSuites;
135
136 #ifdef TRACE_SORT
137 extern bool trace_sort;
138 #endif
139 #ifdef TRACE_SYNCSCAN
140 extern bool trace_syncscan;
141 #endif
142 #ifdef DEBUG_BOUNDED_SORT
143 extern bool optimize_bounded_sort;
144 #endif
145
146 static int      GUC_check_errcode_value;
147
148 /* global variables for check hook support */
149 char       *GUC_check_errmsg_string;
150 char       *GUC_check_errdetail_string;
151 char       *GUC_check_errhint_string;
152
153
154 static void set_config_sourcefile(const char *name, char *sourcefile,
155                                           int sourceline);
156 static bool call_bool_check_hook(struct config_bool * conf, bool *newval,
157                                          void **extra, GucSource source, int elevel);
158 static bool call_int_check_hook(struct config_int * conf, int *newval,
159                                         void **extra, GucSource source, int elevel);
160 static bool call_real_check_hook(struct config_real * conf, double *newval,
161                                          void **extra, GucSource source, int elevel);
162 static bool call_string_check_hook(struct config_string * conf, char **newval,
163                                            void **extra, GucSource source, int elevel);
164 static bool call_enum_check_hook(struct config_enum * conf, int *newval,
165                                          void **extra, GucSource source, int elevel);
166
167 static bool check_log_destination(char **newval, void **extra, GucSource source);
168 static void assign_log_destination(const char *newval, void *extra);
169
170 #ifdef HAVE_SYSLOG
171 static int      syslog_facility = LOG_LOCAL0;
172 #else
173 static int      syslog_facility = 0;
174 #endif
175
176 static void assign_syslog_facility(int newval, void *extra);
177 static void assign_syslog_ident(const char *newval, void *extra);
178 static void assign_session_replication_role(int newval, void *extra);
179 static bool check_temp_buffers(int *newval, void **extra, GucSource source);
180 static bool check_phony_autocommit(bool *newval, void **extra, GucSource source);
181 static bool check_custom_variable_classes(char **newval, void **extra, GucSource source);
182 static bool check_debug_assertions(bool *newval, void **extra, GucSource source);
183 static bool check_bonjour(bool *newval, void **extra, GucSource source);
184 static bool check_ssl(bool *newval, void **extra, GucSource source);
185 static bool check_stage_log_stats(bool *newval, void **extra, GucSource source);
186 static bool check_log_stats(bool *newval, void **extra, GucSource source);
187 static bool check_canonical_path(char **newval, void **extra, GucSource source);
188 static bool check_timezone_abbreviations(char **newval, void **extra, GucSource source);
189 static void assign_timezone_abbreviations(const char *newval, void *extra);
190 static const char *show_archive_command(void);
191 static void assign_tcp_keepalives_idle(int newval, void *extra);
192 static void assign_tcp_keepalives_interval(int newval, void *extra);
193 static void assign_tcp_keepalives_count(int newval, void *extra);
194 static const char *show_tcp_keepalives_idle(void);
195 static const char *show_tcp_keepalives_interval(void);
196 static const char *show_tcp_keepalives_count(void);
197 static bool check_maxconnections(int *newval, void **extra, GucSource source);
198 static void assign_maxconnections(int newval, void *extra);
199 static bool check_autovacuum_max_workers(int *newval, void **extra, GucSource source);
200 static void assign_autovacuum_max_workers(int newval, void *extra);
201 static bool check_effective_io_concurrency(int *newval, void **extra, GucSource source);
202 static void assign_effective_io_concurrency(int newval, void *extra);
203 static void assign_pgstat_temp_directory(const char *newval, void *extra);
204 static bool check_application_name(char **newval, void **extra, GucSource source);
205 static void assign_application_name(const char *newval, void *extra);
206 static const char *show_unix_socket_permissions(void);
207 static const char *show_log_file_mode(void);
208
209 static char *config_enum_get_options(struct config_enum * record,
210                                                 const char *prefix, const char *suffix,
211                                                 const char *separator);
212
213
214 /*
215  * Options for enum values defined in this module.
216  *
217  * NOTE! Option values may not contain double quotes!
218  */
219
220 static const struct config_enum_entry bytea_output_options[] = {
221         {"escape", BYTEA_OUTPUT_ESCAPE, false},
222         {"hex", BYTEA_OUTPUT_HEX, false},
223         {NULL, 0, false}
224 };
225
226 /*
227  * We have different sets for client and server message level options because
228  * they sort slightly different (see "log" level)
229  */
230 static const struct config_enum_entry client_message_level_options[] = {
231         {"debug", DEBUG2, true},
232         {"debug5", DEBUG5, false},
233         {"debug4", DEBUG4, false},
234         {"debug3", DEBUG3, false},
235         {"debug2", DEBUG2, false},
236         {"debug1", DEBUG1, false},
237         {"log", LOG, false},
238         {"info", INFO, true},
239         {"notice", NOTICE, false},
240         {"warning", WARNING, false},
241         {"error", ERROR, false},
242         {"fatal", FATAL, true},
243         {"panic", PANIC, true},
244         {NULL, 0, false}
245 };
246
247 static const struct config_enum_entry server_message_level_options[] = {
248         {"debug", DEBUG2, true},
249         {"debug5", DEBUG5, false},
250         {"debug4", DEBUG4, false},
251         {"debug3", DEBUG3, false},
252         {"debug2", DEBUG2, false},
253         {"debug1", DEBUG1, false},
254         {"info", INFO, false},
255         {"notice", NOTICE, false},
256         {"warning", WARNING, false},
257         {"error", ERROR, false},
258         {"log", LOG, false},
259         {"fatal", FATAL, false},
260         {"panic", PANIC, false},
261         {NULL, 0, false}
262 };
263
264 static const struct config_enum_entry intervalstyle_options[] = {
265         {"postgres", INTSTYLE_POSTGRES, false},
266         {"postgres_verbose", INTSTYLE_POSTGRES_VERBOSE, false},
267         {"sql_standard", INTSTYLE_SQL_STANDARD, false},
268         {"iso_8601", INTSTYLE_ISO_8601, false},
269         {NULL, 0, false}
270 };
271
272 static const struct config_enum_entry log_error_verbosity_options[] = {
273         {"terse", PGERROR_TERSE, false},
274         {"default", PGERROR_DEFAULT, false},
275         {"verbose", PGERROR_VERBOSE, false},
276         {NULL, 0, false}
277 };
278
279 static const struct config_enum_entry log_statement_options[] = {
280         {"none", LOGSTMT_NONE, false},
281         {"ddl", LOGSTMT_DDL, false},
282         {"mod", LOGSTMT_MOD, false},
283         {"all", LOGSTMT_ALL, false},
284         {NULL, 0, false}
285 };
286
287 static const struct config_enum_entry isolation_level_options[] = {
288         {"serializable", XACT_SERIALIZABLE, false},
289         {"repeatable read", XACT_REPEATABLE_READ, false},
290         {"read committed", XACT_READ_COMMITTED, false},
291         {"read uncommitted", XACT_READ_UNCOMMITTED, false},
292         {NULL, 0}
293 };
294
295 static const struct config_enum_entry session_replication_role_options[] = {
296         {"origin", SESSION_REPLICATION_ROLE_ORIGIN, false},
297         {"replica", SESSION_REPLICATION_ROLE_REPLICA, false},
298         {"local", SESSION_REPLICATION_ROLE_LOCAL, false},
299         {NULL, 0, false}
300 };
301
302 static const struct config_enum_entry syslog_facility_options[] = {
303 #ifdef HAVE_SYSLOG
304         {"local0", LOG_LOCAL0, false},
305         {"local1", LOG_LOCAL1, false},
306         {"local2", LOG_LOCAL2, false},
307         {"local3", LOG_LOCAL3, false},
308         {"local4", LOG_LOCAL4, false},
309         {"local5", LOG_LOCAL5, false},
310         {"local6", LOG_LOCAL6, false},
311         {"local7", LOG_LOCAL7, false},
312 #else
313         {"none", 0, false},
314 #endif
315         {NULL, 0}
316 };
317
318 static const struct config_enum_entry track_function_options[] = {
319         {"none", TRACK_FUNC_OFF, false},
320         {"pl", TRACK_FUNC_PL, false},
321         {"all", TRACK_FUNC_ALL, false},
322         {NULL, 0, false}
323 };
324
325 static const struct config_enum_entry xmlbinary_options[] = {
326         {"base64", XMLBINARY_BASE64, false},
327         {"hex", XMLBINARY_HEX, false},
328         {NULL, 0, false}
329 };
330
331 static const struct config_enum_entry xmloption_options[] = {
332         {"content", XMLOPTION_CONTENT, false},
333         {"document", XMLOPTION_DOCUMENT, false},
334         {NULL, 0, false}
335 };
336
337 /*
338  * Although only "on", "off", and "safe_encoding" are documented, we
339  * accept all the likely variants of "on" and "off".
340  */
341 static const struct config_enum_entry backslash_quote_options[] = {
342         {"safe_encoding", BACKSLASH_QUOTE_SAFE_ENCODING, false},
343         {"on", BACKSLASH_QUOTE_ON, false},
344         {"off", BACKSLASH_QUOTE_OFF, false},
345         {"true", BACKSLASH_QUOTE_ON, true},
346         {"false", BACKSLASH_QUOTE_OFF, true},
347         {"yes", BACKSLASH_QUOTE_ON, true},
348         {"no", BACKSLASH_QUOTE_OFF, true},
349         {"1", BACKSLASH_QUOTE_ON, true},
350         {"0", BACKSLASH_QUOTE_OFF, true},
351         {NULL, 0, false}
352 };
353
354 /*
355  * Although only "on", "off", and "partition" are documented, we
356  * accept all the likely variants of "on" and "off".
357  */
358 static const struct config_enum_entry constraint_exclusion_options[] = {
359         {"partition", CONSTRAINT_EXCLUSION_PARTITION, false},
360         {"on", CONSTRAINT_EXCLUSION_ON, false},
361         {"off", CONSTRAINT_EXCLUSION_OFF, false},
362         {"true", CONSTRAINT_EXCLUSION_ON, true},
363         {"false", CONSTRAINT_EXCLUSION_OFF, true},
364         {"yes", CONSTRAINT_EXCLUSION_ON, true},
365         {"no", CONSTRAINT_EXCLUSION_OFF, true},
366         {"1", CONSTRAINT_EXCLUSION_ON, true},
367         {"0", CONSTRAINT_EXCLUSION_OFF, true},
368         {NULL, 0, false}
369 };
370
371 /*
372  * Although only "on", "off", and "local" are documented, we
373  * accept all the likely variants of "on" and "off".
374  */
375 static const struct config_enum_entry synchronous_commit_options[] = {
376         {"local", SYNCHRONOUS_COMMIT_LOCAL_FLUSH, false},
377         {"on", SYNCHRONOUS_COMMIT_ON, false},
378         {"off", SYNCHRONOUS_COMMIT_OFF, false},
379         {"true", SYNCHRONOUS_COMMIT_ON, true},
380         {"false", SYNCHRONOUS_COMMIT_OFF, true},
381         {"yes", SYNCHRONOUS_COMMIT_ON, true},
382         {"no", SYNCHRONOUS_COMMIT_OFF, true},
383         {"1", SYNCHRONOUS_COMMIT_ON, true},
384         {"0", SYNCHRONOUS_COMMIT_OFF, true},
385         {NULL, 0, false}
386 };
387
388 /*
389  * Options for enum values stored in other modules
390  */
391 extern const struct config_enum_entry wal_level_options[];
392 extern const struct config_enum_entry sync_method_options[];
393
394 /*
395  * GUC option variables that are exported from this module
396  */
397 #ifdef USE_ASSERT_CHECKING
398 bool            assert_enabled = true;
399 #else
400 bool            assert_enabled = false;
401 #endif
402 bool            log_duration = false;
403 bool            Debug_print_plan = false;
404 bool            Debug_print_parse = false;
405 bool            Debug_print_rewritten = false;
406 bool            Debug_pretty_print = true;
407
408 bool            log_parser_stats = false;
409 bool            log_planner_stats = false;
410 bool            log_executor_stats = false;
411 bool            log_statement_stats = false;            /* this is sort of all three
412                                                                                                  * above together */
413 bool            log_btree_build_stats = false;
414
415 bool            check_function_bodies = true;
416 bool            default_with_oids = false;
417 bool            SQL_inheritance = true;
418
419 bool            Password_encryption = true;
420
421 int                     log_min_error_statement = ERROR;
422 int                     log_min_messages = WARNING;
423 int                     client_min_messages = NOTICE;
424 int                     log_min_duration_statement = -1;
425 int                     log_temp_files = -1;
426 int                     trace_recovery_messages = LOG;
427
428 int                     num_temp_buffers = 1024;
429
430 char       *data_directory;
431 char       *ConfigFileName;
432 char       *HbaFileName;
433 char       *IdentFileName;
434 char       *external_pid_file;
435
436 char       *pgstat_temp_directory;
437
438 char       *application_name;
439
440 int                     tcp_keepalives_idle;
441 int                     tcp_keepalives_interval;
442 int                     tcp_keepalives_count;
443
444 /*
445  * These variables are all dummies that don't do anything, except in some
446  * cases provide the value for SHOW to display.  The real state is elsewhere
447  * and is kept in sync by assign_hooks.
448  */
449 static char *log_destination_string;
450
451 static char *syslog_ident_str;
452 static bool phony_autocommit;
453 static bool session_auth_is_superuser;
454 static double phony_random_seed;
455 static char *client_encoding_string;
456 static char *datestyle_string;
457 static char *locale_collate;
458 static char *locale_ctype;
459 static char *server_encoding_string;
460 static char *server_version_string;
461 static int      server_version_num;
462 static char *timezone_string;
463 static char *log_timezone_string;
464 static char *timezone_abbreviations_string;
465 static char *XactIsoLevel_string;
466 static char *session_authorization_string;
467 static char *custom_variable_classes;
468 static int      max_function_args;
469 static int      max_index_keys;
470 static int      max_identifier_length;
471 static int      block_size;
472 static int      segment_size;
473 static int      wal_block_size;
474 static int      wal_segment_size;
475 static bool integer_datetimes;
476 static int      effective_io_concurrency;
477
478 /* should be static, but commands/variable.c needs to get at this */
479 char       *role_string;
480
481
482 /*
483  * Displayable names for context types (enum GucContext)
484  *
485  * Note: these strings are deliberately not localized.
486  */
487 const char *const GucContext_Names[] =
488 {
489          /* PGC_INTERNAL */ "internal",
490          /* PGC_POSTMASTER */ "postmaster",
491          /* PGC_SIGHUP */ "sighup",
492          /* PGC_BACKEND */ "backend",
493          /* PGC_SUSET */ "superuser",
494          /* PGC_USERSET */ "user"
495 };
496
497 /*
498  * Displayable names for source types (enum GucSource)
499  *
500  * Note: these strings are deliberately not localized.
501  */
502 const char *const GucSource_Names[] =
503 {
504          /* PGC_S_DEFAULT */ "default",
505          /* PGC_S_DYNAMIC_DEFAULT */ "default",
506          /* PGC_S_ENV_VAR */ "environment variable",
507          /* PGC_S_FILE */ "configuration file",
508          /* PGC_S_ARGV */ "command line",
509          /* PGC_S_DATABASE */ "database",
510          /* PGC_S_USER */ "user",
511          /* PGC_S_DATABASE_USER */ "database user",
512          /* PGC_S_CLIENT */ "client",
513          /* PGC_S_OVERRIDE */ "override",
514          /* PGC_S_INTERACTIVE */ "interactive",
515          /* PGC_S_TEST */ "test",
516          /* PGC_S_SESSION */ "session"
517 };
518
519 /*
520  * Displayable names for the groupings defined in enum config_group
521  */
522 const char *const config_group_names[] =
523 {
524         /* UNGROUPED */
525         gettext_noop("Ungrouped"),
526         /* FILE_LOCATIONS */
527         gettext_noop("File Locations"),
528         /* CONN_AUTH */
529         gettext_noop("Connections and Authentication"),
530         /* CONN_AUTH_SETTINGS */
531         gettext_noop("Connections and Authentication / Connection Settings"),
532         /* CONN_AUTH_SECURITY */
533         gettext_noop("Connections and Authentication / Security and Authentication"),
534         /* RESOURCES */
535         gettext_noop("Resource Usage"),
536         /* RESOURCES_MEM */
537         gettext_noop("Resource Usage / Memory"),
538         /* RESOURCES_KERNEL */
539         gettext_noop("Resource Usage / Kernel Resources"),
540         /* RESOURCES_VACUUM_DELAY */
541         gettext_noop("Resource Usage / Cost-Based Vacuum Delay"),
542         /* RESOURCES_BGWRITER */
543         gettext_noop("Resource Usage / Background Writer"),
544         /* RESOURCES_ASYNCHRONOUS */
545         gettext_noop("Resource Usage / Asynchronous Behavior"),
546         /* WAL */
547         gettext_noop("Write-Ahead Log"),
548         /* WAL_SETTINGS */
549         gettext_noop("Write-Ahead Log / Settings"),
550         /* WAL_CHECKPOINTS */
551         gettext_noop("Write-Ahead Log / Checkpoints"),
552         /* WAL_ARCHIVING */
553         gettext_noop("Write-Ahead Log / Archiving"),
554         /* WAL_REPLICATION */
555         gettext_noop("Write-Ahead Log / Streaming Replication"),
556         /* WAL_STANDBY_SERVERS */
557         gettext_noop("Write-Ahead Log / Standby Servers"),
558         /* QUERY_TUNING */
559         gettext_noop("Query Tuning"),
560         /* QUERY_TUNING_METHOD */
561         gettext_noop("Query Tuning / Planner Method Configuration"),
562         /* QUERY_TUNING_COST */
563         gettext_noop("Query Tuning / Planner Cost Constants"),
564         /* QUERY_TUNING_GEQO */
565         gettext_noop("Query Tuning / Genetic Query Optimizer"),
566         /* QUERY_TUNING_OTHER */
567         gettext_noop("Query Tuning / Other Planner Options"),
568         /* LOGGING */
569         gettext_noop("Reporting and Logging"),
570         /* LOGGING_WHERE */
571         gettext_noop("Reporting and Logging / Where to Log"),
572         /* LOGGING_WHEN */
573         gettext_noop("Reporting and Logging / When to Log"),
574         /* LOGGING_WHAT */
575         gettext_noop("Reporting and Logging / What to Log"),
576         /* STATS */
577         gettext_noop("Statistics"),
578         /* STATS_MONITORING */
579         gettext_noop("Statistics / Monitoring"),
580         /* STATS_COLLECTOR */
581         gettext_noop("Statistics / Query and Index Statistics Collector"),
582         /* AUTOVACUUM */
583         gettext_noop("Autovacuum"),
584         /* CLIENT_CONN */
585         gettext_noop("Client Connection Defaults"),
586         /* CLIENT_CONN_STATEMENT */
587         gettext_noop("Client Connection Defaults / Statement Behavior"),
588         /* CLIENT_CONN_LOCALE */
589         gettext_noop("Client Connection Defaults / Locale and Formatting"),
590         /* CLIENT_CONN_OTHER */
591         gettext_noop("Client Connection Defaults / Other Defaults"),
592         /* LOCK_MANAGEMENT */
593         gettext_noop("Lock Management"),
594         /* COMPAT_OPTIONS */
595         gettext_noop("Version and Platform Compatibility"),
596         /* COMPAT_OPTIONS_PREVIOUS */
597         gettext_noop("Version and Platform Compatibility / Previous PostgreSQL Versions"),
598         /* COMPAT_OPTIONS_CLIENT */
599         gettext_noop("Version and Platform Compatibility / Other Platforms and Clients"),
600         /* ERROR_HANDLING */
601         gettext_noop("Error Handling"),
602         /* PRESET_OPTIONS */
603         gettext_noop("Preset Options"),
604         /* CUSTOM_OPTIONS */
605         gettext_noop("Customized Options"),
606         /* DEVELOPER_OPTIONS */
607         gettext_noop("Developer Options"),
608         /* help_config wants this array to be null-terminated */
609         NULL
610 };
611
612 /*
613  * Displayable names for GUC variable types (enum config_type)
614  *
615  * Note: these strings are deliberately not localized.
616  */
617 const char *const config_type_names[] =
618 {
619          /* PGC_BOOL */ "bool",
620          /* PGC_INT */ "integer",
621          /* PGC_REAL */ "real",
622          /* PGC_STRING */ "string",
623          /* PGC_ENUM */ "enum"
624 };
625
626
627 /*
628  * Contents of GUC tables
629  *
630  * See src/backend/utils/misc/README for design notes.
631  *
632  * TO ADD AN OPTION:
633  *
634  * 1. Declare a global variable of type bool, int, double, or char*
635  *        and make use of it.
636  *
637  * 2. Decide at what times it's safe to set the option. See guc.h for
638  *        details.
639  *
640  * 3. Decide on a name, a default value, upper and lower bounds (if
641  *        applicable), etc.
642  *
643  * 4. Add a record below.
644  *
645  * 5. Add it to src/backend/utils/misc/postgresql.conf.sample, if
646  *        appropriate.
647  *
648  * 6. Don't forget to document the option (at least in config.sgml).
649  *
650  * 7. If it's a new GUC_LIST option you must edit pg_dumpall.c to ensure
651  *        it is not single quoted at dump time.
652  */
653
654
655 /******** option records follow ********/
656
657 static struct config_bool ConfigureNamesBool[] =
658 {
659         {
660                 {"enable_seqscan", PGC_USERSET, QUERY_TUNING_METHOD,
661                         gettext_noop("Enables the planner's use of sequential-scan plans."),
662                         NULL
663                 },
664                 &enable_seqscan,
665                 true,
666                 NULL, NULL, NULL
667         },
668         {
669                 {"enable_indexscan", PGC_USERSET, QUERY_TUNING_METHOD,
670                         gettext_noop("Enables the planner's use of index-scan plans."),
671                         NULL
672                 },
673                 &enable_indexscan,
674                 true,
675                 NULL, NULL, NULL
676         },
677         {
678                 {"enable_bitmapscan", PGC_USERSET, QUERY_TUNING_METHOD,
679                         gettext_noop("Enables the planner's use of bitmap-scan plans."),
680                         NULL
681                 },
682                 &enable_bitmapscan,
683                 true,
684                 NULL, NULL, NULL
685         },
686         {
687                 {"enable_tidscan", PGC_USERSET, QUERY_TUNING_METHOD,
688                         gettext_noop("Enables the planner's use of TID scan plans."),
689                         NULL
690                 },
691                 &enable_tidscan,
692                 true,
693                 NULL, NULL, NULL
694         },
695         {
696                 {"enable_sort", PGC_USERSET, QUERY_TUNING_METHOD,
697                         gettext_noop("Enables the planner's use of explicit sort steps."),
698                         NULL
699                 },
700                 &enable_sort,
701                 true,
702                 NULL, NULL, NULL
703         },
704         {
705                 {"enable_hashagg", PGC_USERSET, QUERY_TUNING_METHOD,
706                         gettext_noop("Enables the planner's use of hashed aggregation plans."),
707                         NULL
708                 },
709                 &enable_hashagg,
710                 true,
711                 NULL, NULL, NULL
712         },
713         {
714                 {"enable_material", PGC_USERSET, QUERY_TUNING_METHOD,
715                         gettext_noop("Enables the planner's use of materialization."),
716                         NULL
717                 },
718                 &enable_material,
719                 true,
720                 NULL, NULL, NULL
721         },
722         {
723                 {"enable_nestloop", PGC_USERSET, QUERY_TUNING_METHOD,
724                         gettext_noop("Enables the planner's use of nested-loop join plans."),
725                         NULL
726                 },
727                 &enable_nestloop,
728                 true,
729                 NULL, NULL, NULL
730         },
731         {
732                 {"enable_mergejoin", PGC_USERSET, QUERY_TUNING_METHOD,
733                         gettext_noop("Enables the planner's use of merge join plans."),
734                         NULL
735                 },
736                 &enable_mergejoin,
737                 true,
738                 NULL, NULL, NULL
739         },
740         {
741                 {"enable_hashjoin", PGC_USERSET, QUERY_TUNING_METHOD,
742                         gettext_noop("Enables the planner's use of hash join plans."),
743                         NULL
744                 },
745                 &enable_hashjoin,
746                 true,
747                 NULL, NULL, NULL
748         },
749         {
750                 {"geqo", PGC_USERSET, QUERY_TUNING_GEQO,
751                         gettext_noop("Enables genetic query optimization."),
752                         gettext_noop("This algorithm attempts to do planning without "
753                                                  "exhaustive searching.")
754                 },
755                 &enable_geqo,
756                 true,
757                 NULL, NULL, NULL
758         },
759         {
760                 /* Not for general use --- used by SET SESSION AUTHORIZATION */
761                 {"is_superuser", PGC_INTERNAL, UNGROUPED,
762                         gettext_noop("Shows whether the current user is a superuser."),
763                         NULL,
764                         GUC_REPORT | GUC_NO_SHOW_ALL | GUC_NO_RESET_ALL | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE
765                 },
766                 &session_auth_is_superuser,
767                 false,
768                 NULL, NULL, NULL
769         },
770         {
771                 {"bonjour", PGC_POSTMASTER, CONN_AUTH_SETTINGS,
772                         gettext_noop("Enables advertising the server via Bonjour."),
773                         NULL
774                 },
775                 &enable_bonjour,
776                 false,
777                 check_bonjour, NULL, NULL
778         },
779         {
780                 {"ssl", PGC_POSTMASTER, CONN_AUTH_SECURITY,
781                         gettext_noop("Enables SSL connections."),
782                         NULL
783                 },
784                 &EnableSSL,
785                 false,
786                 check_ssl, NULL, NULL
787         },
788         {
789                 {"fsync", PGC_SIGHUP, WAL_SETTINGS,
790                         gettext_noop("Forces synchronization of updates to disk."),
791                         gettext_noop("The server will use the fsync() system call in several places to make "
792                         "sure that updates are physically written to disk. This insures "
793                                                  "that a database cluster will recover to a consistent state after "
794                                                  "an operating system or hardware crash.")
795                 },
796                 &enableFsync,
797                 true,
798                 NULL, NULL, NULL
799         },
800         {
801                 {"zero_damaged_pages", PGC_SUSET, DEVELOPER_OPTIONS,
802                         gettext_noop("Continues processing past damaged page headers."),
803                         gettext_noop("Detection of a damaged page header normally causes PostgreSQL to "
804                                 "report an error, aborting the current transaction. Setting "
805                                                  "zero_damaged_pages to true causes the system to instead report a "
806                                                  "warning, zero out the damaged page, and continue processing. This "
807                                                  "behavior will destroy data, namely all the rows on the damaged page."),
808                         GUC_NOT_IN_SAMPLE
809                 },
810                 &zero_damaged_pages,
811                 false,
812                 NULL, NULL, NULL
813         },
814         {
815                 {"full_page_writes", PGC_SIGHUP, WAL_SETTINGS,
816                         gettext_noop("Writes full pages to WAL when first modified after a checkpoint."),
817                         gettext_noop("A page write in process during an operating system crash might be "
818                                                  "only partially written to disk.  During recovery, the row changes "
819                           "stored in WAL are not enough to recover.  This option writes "
820                                                  "pages when first modified after a checkpoint to WAL so full recovery "
821                                                  "is possible.")
822                 },
823                 &fullPageWrites,
824                 true,
825                 NULL, NULL, NULL
826         },
827         {
828                 {"log_checkpoints", PGC_SIGHUP, LOGGING_WHAT,
829                         gettext_noop("Logs each checkpoint."),
830                         NULL
831                 },
832                 &log_checkpoints,
833                 false,
834                 NULL, NULL, NULL
835         },
836         {
837                 {"log_connections", PGC_BACKEND, LOGGING_WHAT,
838                         gettext_noop("Logs each successful connection."),
839                         NULL
840                 },
841                 &Log_connections,
842                 false,
843                 NULL, NULL, NULL
844         },
845         {
846                 {"log_disconnections", PGC_BACKEND, LOGGING_WHAT,
847                         gettext_noop("Logs end of a session, including duration."),
848                         NULL
849                 },
850                 &Log_disconnections,
851                 false,
852                 NULL, NULL, NULL
853         },
854         {
855                 {"debug_assertions", PGC_USERSET, DEVELOPER_OPTIONS,
856                         gettext_noop("Turns on various assertion checks."),
857                         gettext_noop("This is a debugging aid."),
858                         GUC_NOT_IN_SAMPLE
859                 },
860                 &assert_enabled,
861 #ifdef USE_ASSERT_CHECKING
862                 true,
863 #else
864                 false,
865 #endif
866                 check_debug_assertions, NULL, NULL
867         },
868
869         {
870                 {"exit_on_error", PGC_USERSET, ERROR_HANDLING_OPTIONS,
871                         gettext_noop("Terminate session on any error."),
872                         NULL
873                 },
874                 &ExitOnAnyError,
875                 false,
876                 NULL, NULL, NULL
877         },
878         {
879                 {"restart_after_crash", PGC_SIGHUP, ERROR_HANDLING_OPTIONS,
880                         gettext_noop("Reinitialize after backend crash."),
881                         NULL
882                 },
883                 &restart_after_crash,
884                 true,
885                 NULL, NULL, NULL
886         },
887
888         {
889                 {"log_duration", PGC_SUSET, LOGGING_WHAT,
890                         gettext_noop("Logs the duration of each completed SQL statement."),
891                         NULL
892                 },
893                 &log_duration,
894                 false,
895                 NULL, NULL, NULL
896         },
897         {
898                 {"debug_print_parse", PGC_USERSET, LOGGING_WHAT,
899                         gettext_noop("Logs each query's parse tree."),
900                         NULL
901                 },
902                 &Debug_print_parse,
903                 false,
904                 NULL, NULL, NULL
905         },
906         {
907                 {"debug_print_rewritten", PGC_USERSET, LOGGING_WHAT,
908                         gettext_noop("Logs each query's rewritten parse tree."),
909                         NULL
910                 },
911                 &Debug_print_rewritten,
912                 false,
913                 NULL, NULL, NULL
914         },
915         {
916                 {"debug_print_plan", PGC_USERSET, LOGGING_WHAT,
917                         gettext_noop("Logs each query's execution plan."),
918                         NULL
919                 },
920                 &Debug_print_plan,
921                 false,
922                 NULL, NULL, NULL
923         },
924         {
925                 {"debug_pretty_print", PGC_USERSET, LOGGING_WHAT,
926                         gettext_noop("Indents parse and plan tree displays."),
927                         NULL
928                 },
929                 &Debug_pretty_print,
930                 true,
931                 NULL, NULL, NULL
932         },
933         {
934                 {"log_parser_stats", PGC_SUSET, STATS_MONITORING,
935                         gettext_noop("Writes parser performance statistics to the server log."),
936                         NULL
937                 },
938                 &log_parser_stats,
939                 false,
940                 check_stage_log_stats, NULL, NULL
941         },
942         {
943                 {"log_planner_stats", PGC_SUSET, STATS_MONITORING,
944                         gettext_noop("Writes planner performance statistics to the server log."),
945                         NULL
946                 },
947                 &log_planner_stats,
948                 false,
949                 check_stage_log_stats, NULL, NULL
950         },
951         {
952                 {"log_executor_stats", PGC_SUSET, STATS_MONITORING,
953                         gettext_noop("Writes executor performance statistics to the server log."),
954                         NULL
955                 },
956                 &log_executor_stats,
957                 false,
958                 check_stage_log_stats, NULL, NULL
959         },
960         {
961                 {"log_statement_stats", PGC_SUSET, STATS_MONITORING,
962                         gettext_noop("Writes cumulative performance statistics to the server log."),
963                         NULL
964                 },
965                 &log_statement_stats,
966                 false,
967                 check_log_stats, NULL, NULL
968         },
969 #ifdef BTREE_BUILD_STATS
970         {
971                 {"log_btree_build_stats", PGC_SUSET, DEVELOPER_OPTIONS,
972                         gettext_noop("No description available."),
973                         NULL,
974                         GUC_NOT_IN_SAMPLE
975                 },
976                 &log_btree_build_stats,
977                 false,
978                 NULL, NULL, NULL
979         },
980 #endif
981
982         {
983                 {"track_activities", PGC_SUSET, STATS_COLLECTOR,
984                         gettext_noop("Collects information about executing commands."),
985                         gettext_noop("Enables the collection of information on the currently "
986                                                  "executing command of each session, along with "
987                                                  "the time at which that command began execution.")
988                 },
989                 &pgstat_track_activities,
990                 true,
991                 NULL, NULL, NULL
992         },
993         {
994                 {"track_counts", PGC_SUSET, STATS_COLLECTOR,
995                         gettext_noop("Collects statistics on database activity."),
996                         NULL
997                 },
998                 &pgstat_track_counts,
999                 true,
1000                 NULL, NULL, NULL
1001         },
1002
1003         {
1004                 {"update_process_title", PGC_SUSET, STATS_COLLECTOR,
1005                         gettext_noop("Updates the process title to show the active SQL command."),
1006                         gettext_noop("Enables updating of the process title every time a new SQL command is received by the server.")
1007                 },
1008                 &update_process_title,
1009                 true,
1010                 NULL, NULL, NULL
1011         },
1012
1013         {
1014                 {"autovacuum", PGC_SIGHUP, AUTOVACUUM,
1015                         gettext_noop("Starts the autovacuum subprocess."),
1016                         NULL
1017                 },
1018                 &autovacuum_start_daemon,
1019                 true,
1020                 NULL, NULL, NULL
1021         },
1022
1023         {
1024                 {"trace_notify", PGC_USERSET, DEVELOPER_OPTIONS,
1025                         gettext_noop("Generates debugging output for LISTEN and NOTIFY."),
1026                         NULL,
1027                         GUC_NOT_IN_SAMPLE
1028                 },
1029                 &Trace_notify,
1030                 false,
1031                 NULL, NULL, NULL
1032         },
1033
1034 #ifdef LOCK_DEBUG
1035         {
1036                 {"trace_locks", PGC_SUSET, DEVELOPER_OPTIONS,
1037                         gettext_noop("No description available."),
1038                         NULL,
1039                         GUC_NOT_IN_SAMPLE
1040                 },
1041                 &Trace_locks,
1042                 false,
1043                 NULL, NULL, NULL
1044         },
1045         {
1046                 {"trace_userlocks", PGC_SUSET, DEVELOPER_OPTIONS,
1047                         gettext_noop("No description available."),
1048                         NULL,
1049                         GUC_NOT_IN_SAMPLE
1050                 },
1051                 &Trace_userlocks,
1052                 false,
1053                 NULL, NULL, NULL
1054         },
1055         {
1056                 {"trace_lwlocks", PGC_SUSET, DEVELOPER_OPTIONS,
1057                         gettext_noop("No description available."),
1058                         NULL,
1059                         GUC_NOT_IN_SAMPLE
1060                 },
1061                 &Trace_lwlocks,
1062                 false,
1063                 NULL, NULL, NULL
1064         },
1065         {
1066                 {"debug_deadlocks", PGC_SUSET, DEVELOPER_OPTIONS,
1067                         gettext_noop("No description available."),
1068                         NULL,
1069                         GUC_NOT_IN_SAMPLE
1070                 },
1071                 &Debug_deadlocks,
1072                 false,
1073                 NULL, NULL, NULL
1074         },
1075 #endif
1076
1077         {
1078                 {"log_lock_waits", PGC_SUSET, LOGGING_WHAT,
1079                         gettext_noop("Logs long lock waits."),
1080                         NULL
1081                 },
1082                 &log_lock_waits,
1083                 false,
1084                 NULL, NULL, NULL
1085         },
1086
1087         {
1088                 {"log_hostname", PGC_SIGHUP, LOGGING_WHAT,
1089                         gettext_noop("Logs the host name in the connection logs."),
1090                         gettext_noop("By default, connection logs only show the IP address "
1091                                                  "of the connecting host. If you want them to show the host name you "
1092                           "can turn this on, but depending on your host name resolution "
1093                            "setup it might impose a non-negligible performance penalty.")
1094                 },
1095                 &log_hostname,
1096                 false,
1097                 NULL, NULL, NULL
1098         },
1099         {
1100                 {"sql_inheritance", PGC_USERSET, COMPAT_OPTIONS_PREVIOUS,
1101                         gettext_noop("Causes subtables to be included by default in various commands."),
1102                         NULL
1103                 },
1104                 &SQL_inheritance,
1105                 true,
1106                 NULL, NULL, NULL
1107         },
1108         {
1109                 {"password_encryption", PGC_USERSET, CONN_AUTH_SECURITY,
1110                         gettext_noop("Encrypt passwords."),
1111                         gettext_noop("When a password is specified in CREATE USER or "
1112                            "ALTER USER without writing either ENCRYPTED or UNENCRYPTED, "
1113                                                  "this parameter determines whether the password is to be encrypted.")
1114                 },
1115                 &Password_encryption,
1116                 true,
1117                 NULL, NULL, NULL
1118         },
1119         {
1120                 {"transform_null_equals", PGC_USERSET, COMPAT_OPTIONS_CLIENT,
1121                         gettext_noop("Treats \"expr=NULL\" as \"expr IS NULL\"."),
1122                         gettext_noop("When turned on, expressions of the form expr = NULL "
1123                            "(or NULL = expr) are treated as expr IS NULL, that is, they "
1124                                 "return true if expr evaluates to the null value, and false "
1125                            "otherwise. The correct behavior of expr = NULL is to always "
1126                                                  "return null (unknown).")
1127                 },
1128                 &Transform_null_equals,
1129                 false,
1130                 NULL, NULL, NULL
1131         },
1132         {
1133                 {"db_user_namespace", PGC_SIGHUP, CONN_AUTH_SECURITY,
1134                         gettext_noop("Enables per-database user names."),
1135                         NULL
1136                 },
1137                 &Db_user_namespace,
1138                 false,
1139                 NULL, NULL, NULL
1140         },
1141         {
1142                 /* only here for backwards compatibility */
1143                 {"autocommit", PGC_USERSET, CLIENT_CONN_STATEMENT,
1144                         gettext_noop("This parameter doesn't do anything."),
1145                         gettext_noop("It's just here so that we won't choke on SET AUTOCOMMIT TO ON from 7.3-vintage clients."),
1146                         GUC_NO_SHOW_ALL | GUC_NOT_IN_SAMPLE
1147                 },
1148                 &phony_autocommit,
1149                 true,
1150                 check_phony_autocommit, NULL, NULL
1151         },
1152         {
1153                 {"default_transaction_read_only", PGC_USERSET, CLIENT_CONN_STATEMENT,
1154                         gettext_noop("Sets the default read-only status of new transactions."),
1155                         NULL
1156                 },
1157                 &DefaultXactReadOnly,
1158                 false,
1159                 NULL, NULL, NULL
1160         },
1161         {
1162                 {"transaction_read_only", PGC_USERSET, CLIENT_CONN_STATEMENT,
1163                         gettext_noop("Sets the current transaction's read-only status."),
1164                         NULL,
1165                         GUC_NO_RESET_ALL | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE
1166                 },
1167                 &XactReadOnly,
1168                 false,
1169                 check_transaction_read_only, NULL, NULL
1170         },
1171         {
1172                 {"default_transaction_deferrable", PGC_USERSET, CLIENT_CONN_STATEMENT,
1173                         gettext_noop("Sets the default deferrable status of new transactions."),
1174                         NULL
1175                 },
1176                 &DefaultXactDeferrable,
1177                 false,
1178                 NULL, NULL, NULL
1179         },
1180         {
1181                 {"transaction_deferrable", PGC_USERSET, CLIENT_CONN_STATEMENT,
1182                         gettext_noop("Whether to defer a read-only serializable transaction until it can be executed with no possible serialization failures."),
1183                         NULL,
1184                         GUC_NO_RESET_ALL | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE
1185                 },
1186                 &XactDeferrable,
1187                 false,
1188                 check_transaction_deferrable, NULL, NULL
1189         },
1190         {
1191                 {"check_function_bodies", PGC_USERSET, CLIENT_CONN_STATEMENT,
1192                         gettext_noop("Check function bodies during CREATE FUNCTION."),
1193                         NULL
1194                 },
1195                 &check_function_bodies,
1196                 true,
1197                 NULL, NULL, NULL
1198         },
1199         {
1200                 {"array_nulls", PGC_USERSET, COMPAT_OPTIONS_PREVIOUS,
1201                         gettext_noop("Enable input of NULL elements in arrays."),
1202                         gettext_noop("When turned on, unquoted NULL in an array input "
1203                                                  "value means a null value; "
1204                                                  "otherwise it is taken literally.")
1205                 },
1206                 &Array_nulls,
1207                 true,
1208                 NULL, NULL, NULL
1209         },
1210         {
1211                 {"default_with_oids", PGC_USERSET, COMPAT_OPTIONS_PREVIOUS,
1212                         gettext_noop("Create new tables with OIDs by default."),
1213                         NULL
1214                 },
1215                 &default_with_oids,
1216                 false,
1217                 NULL, NULL, NULL
1218         },
1219         {
1220                 {"logging_collector", PGC_POSTMASTER, LOGGING_WHERE,
1221                         gettext_noop("Start a subprocess to capture stderr output and/or csvlogs into log files."),
1222                         NULL
1223                 },
1224                 &Logging_collector,
1225                 false,
1226                 NULL, NULL, NULL
1227         },
1228         {
1229                 {"log_truncate_on_rotation", PGC_SIGHUP, LOGGING_WHERE,
1230                         gettext_noop("Truncate existing log files of same name during log rotation."),
1231                         NULL
1232                 },
1233                 &Log_truncate_on_rotation,
1234                 false,
1235                 NULL, NULL, NULL
1236         },
1237
1238 #ifdef TRACE_SORT
1239         {
1240                 {"trace_sort", PGC_USERSET, DEVELOPER_OPTIONS,
1241                         gettext_noop("Emit information about resource usage in sorting."),
1242                         NULL,
1243                         GUC_NOT_IN_SAMPLE
1244                 },
1245                 &trace_sort,
1246                 false,
1247                 NULL, NULL, NULL
1248         },
1249 #endif
1250
1251 #ifdef TRACE_SYNCSCAN
1252         /* this is undocumented because not exposed in a standard build */
1253         {
1254                 {"trace_syncscan", PGC_USERSET, DEVELOPER_OPTIONS,
1255                         gettext_noop("Generate debugging output for synchronized scanning."),
1256                         NULL,
1257                         GUC_NOT_IN_SAMPLE
1258                 },
1259                 &trace_syncscan,
1260                 false,
1261                 NULL, NULL, NULL
1262         },
1263 #endif
1264
1265 #ifdef DEBUG_BOUNDED_SORT
1266         /* this is undocumented because not exposed in a standard build */
1267         {
1268                 {
1269                         "optimize_bounded_sort", PGC_USERSET, QUERY_TUNING_METHOD,
1270                         gettext_noop("Enable bounded sorting using heap sort."),
1271                         NULL,
1272                         GUC_NOT_IN_SAMPLE
1273                 },
1274                 &optimize_bounded_sort,
1275                 true,
1276                 NULL, NULL, NULL
1277         },
1278 #endif
1279
1280 #ifdef WAL_DEBUG
1281         {
1282                 {"wal_debug", PGC_SUSET, DEVELOPER_OPTIONS,
1283                         gettext_noop("Emit WAL-related debugging output."),
1284                         NULL,
1285                         GUC_NOT_IN_SAMPLE
1286                 },
1287                 &XLOG_DEBUG,
1288                 false,
1289                 NULL, NULL, NULL
1290         },
1291 #endif
1292
1293         {
1294                 {"integer_datetimes", PGC_INTERNAL, PRESET_OPTIONS,
1295                         gettext_noop("Datetimes are integer based."),
1296                         NULL,
1297                         GUC_REPORT | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE
1298                 },
1299                 &integer_datetimes,
1300 #ifdef HAVE_INT64_TIMESTAMP
1301                 true,
1302 #else
1303                 false,
1304 #endif
1305                 NULL, NULL, NULL
1306         },
1307
1308         {
1309                 {"krb_caseins_users", PGC_SIGHUP, CONN_AUTH_SECURITY,
1310                         gettext_noop("Sets whether Kerberos and GSSAPI user names should be treated as case-insensitive."),
1311                         NULL
1312                 },
1313                 &pg_krb_caseins_users,
1314                 false,
1315                 NULL, NULL, NULL
1316         },
1317
1318         {
1319                 {"escape_string_warning", PGC_USERSET, COMPAT_OPTIONS_PREVIOUS,
1320                         gettext_noop("Warn about backslash escapes in ordinary string literals."),
1321                         NULL
1322                 },
1323                 &escape_string_warning,
1324                 true,
1325                 NULL, NULL, NULL
1326         },
1327
1328         {
1329                 {"standard_conforming_strings", PGC_USERSET, COMPAT_OPTIONS_PREVIOUS,
1330                         gettext_noop("Causes '...' strings to treat backslashes literally."),
1331                         NULL,
1332                         GUC_REPORT
1333                 },
1334                 &standard_conforming_strings,
1335                 true,
1336                 NULL, NULL, NULL
1337         },
1338
1339         {
1340                 {"synchronize_seqscans", PGC_USERSET, COMPAT_OPTIONS_PREVIOUS,
1341                         gettext_noop("Enable synchronized sequential scans."),
1342                         NULL
1343                 },
1344                 &synchronize_seqscans,
1345                 true,
1346                 NULL, NULL, NULL
1347         },
1348
1349         {
1350                 {"archive_mode", PGC_POSTMASTER, WAL_ARCHIVING,
1351                         gettext_noop("Allows archiving of WAL files using archive_command."),
1352                         NULL
1353                 },
1354                 &XLogArchiveMode,
1355                 false,
1356                 NULL, NULL, NULL
1357         },
1358
1359         {
1360                 {"hot_standby", PGC_POSTMASTER, WAL_STANDBY_SERVERS,
1361                         gettext_noop("Allows connections and queries during recovery."),
1362                         NULL
1363                 },
1364                 &EnableHotStandby,
1365                 false,
1366                 NULL, NULL, NULL
1367         },
1368
1369         {
1370                 {"hot_standby_feedback", PGC_SIGHUP, WAL_STANDBY_SERVERS,
1371                         gettext_noop("Allows feedback from a hot standby primary that will avoid query conflicts."),
1372                         NULL
1373                 },
1374                 &hot_standby_feedback,
1375                 false,
1376                 NULL, NULL, NULL
1377         },
1378
1379         {
1380                 {"allow_system_table_mods", PGC_POSTMASTER, DEVELOPER_OPTIONS,
1381                         gettext_noop("Allows modifications of the structure of system tables."),
1382                         NULL,
1383                         GUC_NOT_IN_SAMPLE
1384                 },
1385                 &allowSystemTableMods,
1386                 false,
1387                 NULL, NULL, NULL
1388         },
1389
1390         {
1391                 {"ignore_system_indexes", PGC_BACKEND, DEVELOPER_OPTIONS,
1392                         gettext_noop("Disables reading from system indexes."),
1393                         gettext_noop("It does not prevent updating the indexes, so it is safe "
1394                                                  "to use.  The worst consequence is slowness."),
1395                         GUC_NOT_IN_SAMPLE
1396                 },
1397                 &IgnoreSystemIndexes,
1398                 false,
1399                 NULL, NULL, NULL
1400         },
1401
1402         {
1403                 {"lo_compat_privileges", PGC_SUSET, COMPAT_OPTIONS_PREVIOUS,
1404                         gettext_noop("Enables backward compatibility mode for privilege checks on large objects."),
1405                         gettext_noop("Skips privilege checks when reading or modifying large objects, "
1406                                   "for compatibility with PostgreSQL releases prior to 9.0.")
1407                 },
1408                 &lo_compat_privileges,
1409                 false,
1410                 NULL, NULL, NULL
1411         },
1412
1413         {
1414                 {"quote_all_identifiers", PGC_USERSET, COMPAT_OPTIONS_PREVIOUS,
1415                         gettext_noop("When generating SQL fragments, quote all identifiers."),
1416                         NULL,
1417                 },
1418                 &quote_all_identifiers,
1419                 false,
1420                 NULL, NULL, NULL
1421         },
1422
1423         /* End-of-list marker */
1424         {
1425                 {NULL, 0, 0, NULL, NULL}, NULL, false, NULL, NULL, NULL
1426         }
1427 };
1428
1429
1430 static struct config_int ConfigureNamesInt[] =
1431 {
1432         {
1433                 {"archive_timeout", PGC_SIGHUP, WAL_ARCHIVING,
1434                         gettext_noop("Forces a switch to the next xlog file if a "
1435                                                  "new file has not been started within N seconds."),
1436                         NULL,
1437                         GUC_UNIT_S
1438                 },
1439                 &XLogArchiveTimeout,
1440                 0, 0, INT_MAX,
1441                 NULL, NULL, NULL
1442         },
1443         {
1444                 {"post_auth_delay", PGC_BACKEND, DEVELOPER_OPTIONS,
1445                         gettext_noop("Waits N seconds on connection startup after authentication."),
1446                         gettext_noop("This allows attaching a debugger to the process."),
1447                         GUC_NOT_IN_SAMPLE | GUC_UNIT_S
1448                 },
1449                 &PostAuthDelay,
1450                 0, 0, INT_MAX,
1451                 NULL, NULL, NULL
1452         },
1453         {
1454                 {"default_statistics_target", PGC_USERSET, QUERY_TUNING_OTHER,
1455                         gettext_noop("Sets the default statistics target."),
1456                         gettext_noop("This applies to table columns that have not had a "
1457                                 "column-specific target set via ALTER TABLE SET STATISTICS.")
1458                 },
1459                 &default_statistics_target,
1460                 100, 1, 10000,
1461                 NULL, NULL, NULL
1462         },
1463         {
1464                 {"from_collapse_limit", PGC_USERSET, QUERY_TUNING_OTHER,
1465                         gettext_noop("Sets the FROM-list size beyond which subqueries "
1466                                                  "are not collapsed."),
1467                         gettext_noop("The planner will merge subqueries into upper "
1468                                 "queries if the resulting FROM list would have no more than "
1469                                                  "this many items.")
1470                 },
1471                 &from_collapse_limit,
1472                 8, 1, INT_MAX,
1473                 NULL, NULL, NULL
1474         },
1475         {
1476                 {"join_collapse_limit", PGC_USERSET, QUERY_TUNING_OTHER,
1477                         gettext_noop("Sets the FROM-list size beyond which JOIN "
1478                                                  "constructs are not flattened."),
1479                         gettext_noop("The planner will flatten explicit JOIN "
1480                                                  "constructs into lists of FROM items whenever a "
1481                                                  "list of no more than this many items would result.")
1482                 },
1483                 &join_collapse_limit,
1484                 8, 1, INT_MAX,
1485                 NULL, NULL, NULL
1486         },
1487         {
1488                 {"geqo_threshold", PGC_USERSET, QUERY_TUNING_GEQO,
1489                         gettext_noop("Sets the threshold of FROM items beyond which GEQO is used."),
1490                         NULL
1491                 },
1492                 &geqo_threshold,
1493                 12, 2, INT_MAX,
1494                 NULL, NULL, NULL
1495         },
1496         {
1497                 {"geqo_effort", PGC_USERSET, QUERY_TUNING_GEQO,
1498                         gettext_noop("GEQO: effort is used to set the default for other GEQO parameters."),
1499                         NULL
1500                 },
1501                 &Geqo_effort,
1502                 DEFAULT_GEQO_EFFORT, MIN_GEQO_EFFORT, MAX_GEQO_EFFORT,
1503                 NULL, NULL, NULL
1504         },
1505         {
1506                 {"geqo_pool_size", PGC_USERSET, QUERY_TUNING_GEQO,
1507                         gettext_noop("GEQO: number of individuals in the population."),
1508                         gettext_noop("Zero selects a suitable default value.")
1509                 },
1510                 &Geqo_pool_size,
1511                 0, 0, INT_MAX,
1512                 NULL, NULL, NULL
1513         },
1514         {
1515                 {"geqo_generations", PGC_USERSET, QUERY_TUNING_GEQO,
1516                         gettext_noop("GEQO: number of iterations of the algorithm."),
1517                         gettext_noop("Zero selects a suitable default value.")
1518                 },
1519                 &Geqo_generations,
1520                 0, 0, INT_MAX,
1521                 NULL, NULL, NULL
1522         },
1523
1524         {
1525                 /* This is PGC_SUSET to prevent hiding from log_lock_waits. */
1526                 {"deadlock_timeout", PGC_SUSET, LOCK_MANAGEMENT,
1527                         gettext_noop("Sets the time to wait on a lock before checking for deadlock."),
1528                         NULL,
1529                         GUC_UNIT_MS
1530                 },
1531                 &DeadlockTimeout,
1532                 1000, 1, INT_MAX,
1533                 NULL, NULL, NULL
1534         },
1535
1536         {
1537                 {"max_standby_archive_delay", PGC_SIGHUP, WAL_STANDBY_SERVERS,
1538                         gettext_noop("Sets the maximum delay before canceling queries when a hot standby server is processing archived WAL data."),
1539                         NULL,
1540                         GUC_UNIT_MS
1541                 },
1542                 &max_standby_archive_delay,
1543                 30 * 1000, -1, INT_MAX,
1544                 NULL, NULL, NULL
1545         },
1546
1547         {
1548                 {"max_standby_streaming_delay", PGC_SIGHUP, WAL_STANDBY_SERVERS,
1549                         gettext_noop("Sets the maximum delay before canceling queries when a hot standby server is processing streamed WAL data."),
1550                         NULL,
1551                         GUC_UNIT_MS
1552                 },
1553                 &max_standby_streaming_delay,
1554                 30 * 1000, -1, INT_MAX,
1555                 NULL, NULL, NULL
1556         },
1557
1558         {
1559                 {"wal_receiver_status_interval", PGC_SIGHUP, WAL_STANDBY_SERVERS,
1560                         gettext_noop("Sets the maximum interval between WAL receiver status reports to the master."),
1561                         NULL,
1562                         GUC_UNIT_S
1563                 },
1564                 &wal_receiver_status_interval,
1565                 10, 0, INT_MAX / 1000,
1566                 NULL, NULL, NULL
1567         },
1568
1569         {
1570                 {"max_connections", PGC_POSTMASTER, CONN_AUTH_SETTINGS,
1571                         gettext_noop("Sets the maximum number of concurrent connections."),
1572                         NULL
1573                 },
1574                 &MaxConnections,
1575                 100, 1, MAX_BACKENDS,
1576                 check_maxconnections, assign_maxconnections, NULL
1577         },
1578
1579         {
1580                 {"superuser_reserved_connections", PGC_POSTMASTER, CONN_AUTH_SETTINGS,
1581                         gettext_noop("Sets the number of connection slots reserved for superusers."),
1582                         NULL
1583                 },
1584                 &ReservedBackends,
1585                 3, 0, MAX_BACKENDS,
1586                 NULL, NULL, NULL
1587         },
1588
1589         /*
1590          * We sometimes multiply the number of shared buffers by two without
1591          * checking for overflow, so we mustn't allow more than INT_MAX / 2.
1592          */
1593         {
1594                 {"shared_buffers", PGC_POSTMASTER, RESOURCES_MEM,
1595                         gettext_noop("Sets the number of shared memory buffers used by the server."),
1596                         NULL,
1597                         GUC_UNIT_BLOCKS
1598                 },
1599                 &NBuffers,
1600                 1024, 16, INT_MAX / 2,
1601                 NULL, NULL, NULL
1602         },
1603
1604         {
1605                 {"temp_buffers", PGC_USERSET, RESOURCES_MEM,
1606                         gettext_noop("Sets the maximum number of temporary buffers used by each session."),
1607                         NULL,
1608                         GUC_UNIT_BLOCKS
1609                 },
1610                 &num_temp_buffers,
1611                 1024, 100, INT_MAX / 2,
1612                 check_temp_buffers, NULL, NULL
1613         },
1614
1615         {
1616                 {"port", PGC_POSTMASTER, CONN_AUTH_SETTINGS,
1617                         gettext_noop("Sets the TCP port the server listens on."),
1618                         NULL
1619                 },
1620                 &PostPortNumber,
1621                 DEF_PGPORT, 1, 65535,
1622                 NULL, NULL, NULL
1623         },
1624
1625         {
1626                 {"unix_socket_permissions", PGC_POSTMASTER, CONN_AUTH_SETTINGS,
1627                         gettext_noop("Sets the access permissions of the Unix-domain socket."),
1628                         gettext_noop("Unix-domain sockets use the usual Unix file system "
1629                                                  "permission set. The parameter value is expected "
1630                                                  "to be a numeric mode specification in the form "
1631                                                  "accepted by the chmod and umask system calls. "
1632                                                  "(To use the customary octal format the number must "
1633                                                  "start with a 0 (zero).)")
1634                 },
1635                 &Unix_socket_permissions,
1636                 0777, 0000, 0777,
1637                 NULL, NULL, show_unix_socket_permissions
1638         },
1639
1640         {
1641                 {"log_file_mode", PGC_SIGHUP, LOGGING_WHERE,
1642                         gettext_noop("Sets the file permissions for log files."),
1643                         gettext_noop("The parameter value is expected "
1644                                                  "to be a numeric mode specification in the form "
1645                                                  "accepted by the chmod and umask system calls. "
1646                                                  "(To use the customary octal format the number must "
1647                                                  "start with a 0 (zero).)")
1648                 },
1649                 &Log_file_mode,
1650                 0600, 0000, 0777,
1651                 NULL, NULL, show_log_file_mode
1652         },
1653
1654         {
1655                 {"work_mem", PGC_USERSET, RESOURCES_MEM,
1656                         gettext_noop("Sets the maximum memory to be used for query workspaces."),
1657                         gettext_noop("This much memory can be used by each internal "
1658                                                  "sort operation and hash table before switching to "
1659                                                  "temporary disk files."),
1660                         GUC_UNIT_KB
1661                 },
1662                 &work_mem,
1663                 1024, 64, MAX_KILOBYTES,
1664                 NULL, NULL, NULL
1665         },
1666
1667         {
1668                 {"maintenance_work_mem", PGC_USERSET, RESOURCES_MEM,
1669                         gettext_noop("Sets the maximum memory to be used for maintenance operations."),
1670                         gettext_noop("This includes operations such as VACUUM and CREATE INDEX."),
1671                         GUC_UNIT_KB
1672                 },
1673                 &maintenance_work_mem,
1674                 16384, 1024, MAX_KILOBYTES,
1675                 NULL, NULL, NULL
1676         },
1677
1678         /*
1679          * We use the hopefully-safely-small value of 100kB as the compiled-in
1680          * default for max_stack_depth.  InitializeGUCOptions will increase it if
1681          * possible, depending on the actual platform-specific stack limit.
1682          */
1683         {
1684                 {"max_stack_depth", PGC_SUSET, RESOURCES_MEM,
1685                         gettext_noop("Sets the maximum stack depth, in kilobytes."),
1686                         NULL,
1687                         GUC_UNIT_KB
1688                 },
1689                 &max_stack_depth,
1690                 100, 100, MAX_KILOBYTES,
1691                 check_max_stack_depth, assign_max_stack_depth, NULL
1692         },
1693
1694         {
1695                 {"vacuum_cost_page_hit", PGC_USERSET, RESOURCES_VACUUM_DELAY,
1696                         gettext_noop("Vacuum cost for a page found in the buffer cache."),
1697                         NULL
1698                 },
1699                 &VacuumCostPageHit,
1700                 1, 0, 10000,
1701                 NULL, NULL, NULL
1702         },
1703
1704         {
1705                 {"vacuum_cost_page_miss", PGC_USERSET, RESOURCES_VACUUM_DELAY,
1706                         gettext_noop("Vacuum cost for a page not found in the buffer cache."),
1707                         NULL
1708                 },
1709                 &VacuumCostPageMiss,
1710                 10, 0, 10000,
1711                 NULL, NULL, NULL
1712         },
1713
1714         {
1715                 {"vacuum_cost_page_dirty", PGC_USERSET, RESOURCES_VACUUM_DELAY,
1716                         gettext_noop("Vacuum cost for a page dirtied by vacuum."),
1717                         NULL
1718                 },
1719                 &VacuumCostPageDirty,
1720                 20, 0, 10000,
1721                 NULL, NULL, NULL
1722         },
1723
1724         {
1725                 {"vacuum_cost_limit", PGC_USERSET, RESOURCES_VACUUM_DELAY,
1726                         gettext_noop("Vacuum cost amount available before napping."),
1727                         NULL
1728                 },
1729                 &VacuumCostLimit,
1730                 200, 1, 10000,
1731                 NULL, NULL, NULL
1732         },
1733
1734         {
1735                 {"vacuum_cost_delay", PGC_USERSET, RESOURCES_VACUUM_DELAY,
1736                         gettext_noop("Vacuum cost delay in milliseconds."),
1737                         NULL,
1738                         GUC_UNIT_MS
1739                 },
1740                 &VacuumCostDelay,
1741                 0, 0, 100,
1742                 NULL, NULL, NULL
1743         },
1744
1745         {
1746                 {"autovacuum_vacuum_cost_delay", PGC_SIGHUP, AUTOVACUUM,
1747                         gettext_noop("Vacuum cost delay in milliseconds, for autovacuum."),
1748                         NULL,
1749                         GUC_UNIT_MS
1750                 },
1751                 &autovacuum_vac_cost_delay,
1752                 20, -1, 100,
1753                 NULL, NULL, NULL
1754         },
1755
1756         {
1757                 {"autovacuum_vacuum_cost_limit", PGC_SIGHUP, AUTOVACUUM,
1758                         gettext_noop("Vacuum cost amount available before napping, for autovacuum."),
1759                         NULL
1760                 },
1761                 &autovacuum_vac_cost_limit,
1762                 -1, -1, 10000,
1763                 NULL, NULL, NULL
1764         },
1765
1766         {
1767                 {"max_files_per_process", PGC_POSTMASTER, RESOURCES_KERNEL,
1768                         gettext_noop("Sets the maximum number of simultaneously open files for each server process."),
1769                         NULL
1770                 },
1771                 &max_files_per_process,
1772                 1000, 25, INT_MAX,
1773                 NULL, NULL, NULL
1774         },
1775
1776         /*
1777          * See also CheckRequiredParameterValues() if this parameter changes
1778          */
1779         {
1780                 {"max_prepared_transactions", PGC_POSTMASTER, RESOURCES_MEM,
1781                         gettext_noop("Sets the maximum number of simultaneously prepared transactions."),
1782                         NULL
1783                 },
1784                 &max_prepared_xacts,
1785                 0, 0, MAX_BACKENDS,
1786                 NULL, NULL, NULL
1787         },
1788
1789 #ifdef LOCK_DEBUG
1790         {
1791                 {"trace_lock_oidmin", PGC_SUSET, DEVELOPER_OPTIONS,
1792                         gettext_noop("No description available."),
1793                         NULL,
1794                         GUC_NOT_IN_SAMPLE
1795                 },
1796                 &Trace_lock_oidmin,
1797                 FirstNormalObjectId, 0, INT_MAX,
1798                 NULL, NULL, NULL
1799         },
1800         {
1801                 {"trace_lock_table", PGC_SUSET, DEVELOPER_OPTIONS,
1802                         gettext_noop("No description available."),
1803                         NULL,
1804                         GUC_NOT_IN_SAMPLE
1805                 },
1806                 &Trace_lock_table,
1807                 0, 0, INT_MAX,
1808                 NULL, NULL, NULL
1809         },
1810 #endif
1811
1812         {
1813                 {"statement_timeout", PGC_USERSET, CLIENT_CONN_STATEMENT,
1814                         gettext_noop("Sets the maximum allowed duration of any statement."),
1815                         gettext_noop("A value of 0 turns off the timeout."),
1816                         GUC_UNIT_MS
1817                 },
1818                 &StatementTimeout,
1819                 0, 0, INT_MAX,
1820                 NULL, NULL, NULL
1821         },
1822
1823         {
1824                 {"vacuum_freeze_min_age", PGC_USERSET, CLIENT_CONN_STATEMENT,
1825                         gettext_noop("Minimum age at which VACUUM should freeze a table row."),
1826                         NULL
1827                 },
1828                 &vacuum_freeze_min_age,
1829                 50000000, 0, 1000000000,
1830                 NULL, NULL, NULL
1831         },
1832
1833         {
1834                 {"vacuum_freeze_table_age", PGC_USERSET, CLIENT_CONN_STATEMENT,
1835                         gettext_noop("Age at which VACUUM should scan whole table to freeze tuples."),
1836                         NULL
1837                 },
1838                 &vacuum_freeze_table_age,
1839                 150000000, 0, 2000000000,
1840                 NULL, NULL, NULL
1841         },
1842
1843         {
1844                 {"vacuum_defer_cleanup_age", PGC_SIGHUP, WAL_REPLICATION,
1845                         gettext_noop("Number of transactions by which VACUUM and HOT cleanup should be deferred, if any."),
1846                         NULL
1847                 },
1848                 &vacuum_defer_cleanup_age,
1849                 0, 0, 1000000,
1850                 NULL, NULL, NULL
1851         },
1852
1853         /*
1854          * See also CheckRequiredParameterValues() if this parameter changes
1855          */
1856         {
1857                 {"max_locks_per_transaction", PGC_POSTMASTER, LOCK_MANAGEMENT,
1858                         gettext_noop("Sets the maximum number of locks per transaction."),
1859                         gettext_noop("The shared lock table is sized on the assumption that "
1860                           "at most max_locks_per_transaction * max_connections distinct "
1861                                                  "objects will need to be locked at any one time.")
1862                 },
1863                 &max_locks_per_xact,
1864                 64, 10, INT_MAX,
1865                 NULL, NULL, NULL
1866         },
1867
1868         {
1869                 {"max_pred_locks_per_transaction", PGC_POSTMASTER, LOCK_MANAGEMENT,
1870                         gettext_noop("Sets the maximum number of predicate locks per transaction."),
1871                         gettext_noop("The shared predicate lock table is sized on the assumption that "
1872                                                  "at most max_pred_locks_per_transaction * max_connections distinct "
1873                                                  "objects will need to be locked at any one time.")
1874                 },
1875                 &max_predicate_locks_per_xact,
1876                 64, 10, INT_MAX,
1877                 NULL, NULL, NULL
1878         },
1879
1880         {
1881                 {"authentication_timeout", PGC_SIGHUP, CONN_AUTH_SECURITY,
1882                         gettext_noop("Sets the maximum allowed time to complete client authentication."),
1883                         NULL,
1884                         GUC_UNIT_S
1885                 },
1886                 &AuthenticationTimeout,
1887                 60, 1, 600,
1888                 NULL, NULL, NULL
1889         },
1890
1891         {
1892                 /* Not for general use */
1893                 {"pre_auth_delay", PGC_SIGHUP, DEVELOPER_OPTIONS,
1894                         gettext_noop("Waits N seconds on connection startup before authentication."),
1895                         gettext_noop("This allows attaching a debugger to the process."),
1896                         GUC_NOT_IN_SAMPLE | GUC_UNIT_S
1897                 },
1898                 &PreAuthDelay,
1899                 0, 0, 60,
1900                 NULL, NULL, NULL
1901         },
1902
1903         {
1904                 {"wal_keep_segments", PGC_SIGHUP, WAL_REPLICATION,
1905                         gettext_noop("Sets the number of WAL files held for standby servers."),
1906                         NULL
1907                 },
1908                 &wal_keep_segments,
1909                 0, 0, INT_MAX,
1910                 NULL, NULL, NULL
1911         },
1912
1913         {
1914                 {"checkpoint_segments", PGC_SIGHUP, WAL_CHECKPOINTS,
1915                         gettext_noop("Sets the maximum distance in log segments between automatic WAL checkpoints."),
1916                         NULL
1917                 },
1918                 &CheckPointSegments,
1919                 3, 1, INT_MAX,
1920                 NULL, NULL, NULL
1921         },
1922
1923         {
1924                 {"checkpoint_timeout", PGC_SIGHUP, WAL_CHECKPOINTS,
1925                         gettext_noop("Sets the maximum time between automatic WAL checkpoints."),
1926                         NULL,
1927                         GUC_UNIT_S
1928                 },
1929                 &CheckPointTimeout,
1930                 300, 30, 3600,
1931                 NULL, NULL, NULL
1932         },
1933
1934         {
1935                 {"checkpoint_warning", PGC_SIGHUP, WAL_CHECKPOINTS,
1936                         gettext_noop("Enables warnings if checkpoint segments are filled more "
1937                                                  "frequently than this."),
1938                         gettext_noop("Write a message to the server log if checkpoints "
1939                         "caused by the filling of checkpoint segment files happens more "
1940                                                  "frequently than this number of seconds. Zero turns off the warning."),
1941                         GUC_UNIT_S
1942                 },
1943                 &CheckPointWarning,
1944                 30, 0, INT_MAX,
1945                 NULL, NULL, NULL
1946         },
1947
1948         {
1949                 {"wal_buffers", PGC_POSTMASTER, WAL_SETTINGS,
1950                         gettext_noop("Sets the number of disk-page buffers in shared memory for WAL."),
1951                         NULL,
1952                         GUC_UNIT_XBLOCKS
1953                 },
1954                 &XLOGbuffers,
1955                 -1, -1, INT_MAX,
1956                 check_wal_buffers, NULL, NULL
1957         },
1958
1959         {
1960                 {"wal_writer_delay", PGC_SIGHUP, WAL_SETTINGS,
1961                         gettext_noop("WAL writer sleep time between WAL flushes."),
1962                         NULL,
1963                         GUC_UNIT_MS
1964                 },
1965                 &WalWriterDelay,
1966                 200, 1, 10000,
1967                 NULL, NULL, NULL
1968         },
1969
1970         {
1971                 /* see max_connections */
1972                 {"max_wal_senders", PGC_POSTMASTER, WAL_REPLICATION,
1973                         gettext_noop("Sets the maximum number of simultaneously running WAL sender processes."),
1974                         NULL
1975                 },
1976                 &max_wal_senders,
1977                 0, 0, MAX_BACKENDS,
1978                 NULL, NULL, NULL
1979         },
1980
1981         {
1982                 {"wal_sender_delay", PGC_SIGHUP, WAL_REPLICATION,
1983                         gettext_noop("WAL sender sleep time between WAL replications."),
1984                         NULL,
1985                         GUC_UNIT_MS
1986                 },
1987                 &WalSndDelay,
1988                 1000, 1, 10000,
1989                 NULL, NULL, NULL
1990         },
1991
1992         {
1993                 {"replication_timeout", PGC_SIGHUP, WAL_REPLICATION,
1994                         gettext_noop("Sets the maximum time to wait for WAL replication."),
1995                         NULL,
1996                         GUC_UNIT_MS
1997                 },
1998                 &replication_timeout,
1999                 60 * 1000, 0, INT_MAX,
2000                 NULL, NULL, NULL
2001         },
2002
2003         {
2004                 {"commit_delay", PGC_USERSET, WAL_SETTINGS,
2005                         gettext_noop("Sets the delay in microseconds between transaction commit and "
2006                                                  "flushing WAL to disk."),
2007                         NULL
2008                 },
2009                 &CommitDelay,
2010                 0, 0, 100000,
2011                 NULL, NULL, NULL
2012         },
2013
2014         {
2015                 {"commit_siblings", PGC_USERSET, WAL_SETTINGS,
2016                         gettext_noop("Sets the minimum concurrent open transactions before performing "
2017                                                  "commit_delay."),
2018                         NULL
2019                 },
2020                 &CommitSiblings,
2021                 5, 0, 1000,
2022                 NULL, NULL, NULL
2023         },
2024
2025         {
2026                 {"extra_float_digits", PGC_USERSET, CLIENT_CONN_LOCALE,
2027                         gettext_noop("Sets the number of digits displayed for floating-point values."),
2028                         gettext_noop("This affects real, double precision, and geometric data types. "
2029                          "The parameter value is added to the standard number of digits "
2030                                                  "(FLT_DIG or DBL_DIG as appropriate).")
2031                 },
2032                 &extra_float_digits,
2033                 0, -15, 3,
2034                 NULL, NULL, NULL
2035         },
2036
2037         {
2038                 {"log_min_duration_statement", PGC_SUSET, LOGGING_WHEN,
2039                         gettext_noop("Sets the minimum execution time above which "
2040                                                  "statements will be logged."),
2041                         gettext_noop("Zero prints all queries. -1 turns this feature off."),
2042                         GUC_UNIT_MS
2043                 },
2044                 &log_min_duration_statement,
2045                 -1, -1, INT_MAX,
2046                 NULL, NULL, NULL
2047         },
2048
2049         {
2050                 {"log_autovacuum_min_duration", PGC_SIGHUP, LOGGING_WHAT,
2051                         gettext_noop("Sets the minimum execution time above which "
2052                                                  "autovacuum actions will be logged."),
2053                         gettext_noop("Zero prints all actions. -1 turns autovacuum logging off."),
2054                         GUC_UNIT_MS
2055                 },
2056                 &Log_autovacuum_min_duration,
2057                 -1, -1, INT_MAX,
2058                 NULL, NULL, NULL
2059         },
2060
2061         {
2062                 {"bgwriter_delay", PGC_SIGHUP, RESOURCES_BGWRITER,
2063                         gettext_noop("Background writer sleep time between rounds."),
2064                         NULL,
2065                         GUC_UNIT_MS
2066                 },
2067                 &BgWriterDelay,
2068                 200, 10, 10000,
2069                 NULL, NULL, NULL
2070         },
2071
2072         {
2073                 {"bgwriter_lru_maxpages", PGC_SIGHUP, RESOURCES_BGWRITER,
2074                         gettext_noop("Background writer maximum number of LRU pages to flush per round."),
2075                         NULL
2076                 },
2077                 &bgwriter_lru_maxpages,
2078                 100, 0, 1000,
2079                 NULL, NULL, NULL
2080         },
2081
2082         {
2083                 {"effective_io_concurrency",
2084 #ifdef USE_PREFETCH
2085                         PGC_USERSET,
2086 #else
2087                         PGC_INTERNAL,
2088 #endif
2089                         RESOURCES_ASYNCHRONOUS,
2090                         gettext_noop("Number of simultaneous requests that can be handled efficiently by the disk subsystem."),
2091                         gettext_noop("For RAID arrays, this should be approximately the number of drive spindles in the array.")
2092                 },
2093                 &effective_io_concurrency,
2094 #ifdef USE_PREFETCH
2095                 1, 0, 1000,
2096 #else
2097                 0, 0, 0,
2098 #endif
2099                 check_effective_io_concurrency, assign_effective_io_concurrency, NULL
2100         },
2101
2102         {
2103                 {"log_rotation_age", PGC_SIGHUP, LOGGING_WHERE,
2104                         gettext_noop("Automatic log file rotation will occur after N minutes."),
2105                         NULL,
2106                         GUC_UNIT_MIN
2107                 },
2108                 &Log_RotationAge,
2109                 HOURS_PER_DAY * MINS_PER_HOUR, 0, INT_MAX / MINS_PER_HOUR,
2110                 NULL, NULL, NULL
2111         },
2112
2113         {
2114                 {"log_rotation_size", PGC_SIGHUP, LOGGING_WHERE,
2115                         gettext_noop("Automatic log file rotation will occur after N kilobytes."),
2116                         NULL,
2117                         GUC_UNIT_KB
2118                 },
2119                 &Log_RotationSize,
2120                 10 * 1024, 0, INT_MAX / 1024,
2121                 NULL, NULL, NULL
2122         },
2123
2124         {
2125                 {"max_function_args", PGC_INTERNAL, PRESET_OPTIONS,
2126                         gettext_noop("Shows the maximum number of function arguments."),
2127                         NULL,
2128                         GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE
2129                 },
2130                 &max_function_args,
2131                 FUNC_MAX_ARGS, FUNC_MAX_ARGS, FUNC_MAX_ARGS,
2132                 NULL, NULL, NULL
2133         },
2134
2135         {
2136                 {"max_index_keys", PGC_INTERNAL, PRESET_OPTIONS,
2137                         gettext_noop("Shows the maximum number of index keys."),
2138                         NULL,
2139                         GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE
2140                 },
2141                 &max_index_keys,
2142                 INDEX_MAX_KEYS, INDEX_MAX_KEYS, INDEX_MAX_KEYS,
2143                 NULL, NULL, NULL
2144         },
2145
2146         {
2147                 {"max_identifier_length", PGC_INTERNAL, PRESET_OPTIONS,
2148                         gettext_noop("Shows the maximum identifier length."),
2149                         NULL,
2150                         GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE
2151                 },
2152                 &max_identifier_length,
2153                 NAMEDATALEN - 1, NAMEDATALEN - 1, NAMEDATALEN - 1,
2154                 NULL, NULL, NULL
2155         },
2156
2157         {
2158                 {"block_size", PGC_INTERNAL, PRESET_OPTIONS,
2159                         gettext_noop("Shows the size of a disk block."),
2160                         NULL,
2161                         GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE
2162                 },
2163                 &block_size,
2164                 BLCKSZ, BLCKSZ, BLCKSZ,
2165                 NULL, NULL, NULL
2166         },
2167
2168         {
2169                 {"segment_size", PGC_INTERNAL, PRESET_OPTIONS,
2170                         gettext_noop("Shows the number of pages per disk file."),
2171                         NULL,
2172                         GUC_UNIT_BLOCKS | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE
2173                 },
2174                 &segment_size,
2175                 RELSEG_SIZE, RELSEG_SIZE, RELSEG_SIZE,
2176                 NULL, NULL, NULL
2177         },
2178
2179         {
2180                 {"wal_block_size", PGC_INTERNAL, PRESET_OPTIONS,
2181                         gettext_noop("Shows the block size in the write ahead log."),
2182                         NULL,
2183                         GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE
2184                 },
2185                 &wal_block_size,
2186                 XLOG_BLCKSZ, XLOG_BLCKSZ, XLOG_BLCKSZ,
2187                 NULL, NULL, NULL
2188         },
2189
2190         {
2191                 {"wal_segment_size", PGC_INTERNAL, PRESET_OPTIONS,
2192                         gettext_noop("Shows the number of pages per write ahead log segment."),
2193                         NULL,
2194                         GUC_UNIT_XBLOCKS | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE
2195                 },
2196                 &wal_segment_size,
2197                 (XLOG_SEG_SIZE / XLOG_BLCKSZ),
2198                 (XLOG_SEG_SIZE / XLOG_BLCKSZ),
2199                 (XLOG_SEG_SIZE / XLOG_BLCKSZ),
2200                 NULL, NULL, NULL
2201         },
2202
2203         {
2204                 {"autovacuum_naptime", PGC_SIGHUP, AUTOVACUUM,
2205                         gettext_noop("Time to sleep between autovacuum runs."),
2206                         NULL,
2207                         GUC_UNIT_S
2208                 },
2209                 &autovacuum_naptime,
2210                 60, 1, INT_MAX / 1000,
2211                 NULL, NULL, NULL
2212         },
2213         {
2214                 {"autovacuum_vacuum_threshold", PGC_SIGHUP, AUTOVACUUM,
2215                         gettext_noop("Minimum number of tuple updates or deletes prior to vacuum."),
2216                         NULL
2217                 },
2218                 &autovacuum_vac_thresh,
2219                 50, 0, INT_MAX,
2220                 NULL, NULL, NULL
2221         },
2222         {
2223                 {"autovacuum_analyze_threshold", PGC_SIGHUP, AUTOVACUUM,
2224                         gettext_noop("Minimum number of tuple inserts, updates or deletes prior to analyze."),
2225                         NULL
2226                 },
2227                 &autovacuum_anl_thresh,
2228                 50, 0, INT_MAX,
2229                 NULL, NULL, NULL
2230         },
2231         {
2232                 /* see varsup.c for why this is PGC_POSTMASTER not PGC_SIGHUP */
2233                 {"autovacuum_freeze_max_age", PGC_POSTMASTER, AUTOVACUUM,
2234                         gettext_noop("Age at which to autovacuum a table to prevent transaction ID wraparound."),
2235                         NULL
2236                 },
2237                 &autovacuum_freeze_max_age,
2238                 /* see pg_resetxlog if you change the upper-limit value */
2239                 200000000, 100000000, 2000000000,
2240                 NULL, NULL, NULL
2241         },
2242         {
2243                 /* see max_connections */
2244                 {"autovacuum_max_workers", PGC_POSTMASTER, AUTOVACUUM,
2245                         gettext_noop("Sets the maximum number of simultaneously running autovacuum worker processes."),
2246                         NULL
2247                 },
2248                 &autovacuum_max_workers,
2249                 3, 1, MAX_BACKENDS,
2250                 check_autovacuum_max_workers, assign_autovacuum_max_workers, NULL
2251         },
2252
2253         {
2254                 {"tcp_keepalives_idle", PGC_USERSET, CLIENT_CONN_OTHER,
2255                         gettext_noop("Time between issuing TCP keepalives."),
2256                         gettext_noop("A value of 0 uses the system default."),
2257                         GUC_UNIT_S
2258                 },
2259                 &tcp_keepalives_idle,
2260                 0, 0, INT_MAX,
2261                 NULL, assign_tcp_keepalives_idle, show_tcp_keepalives_idle
2262         },
2263
2264         {
2265                 {"tcp_keepalives_interval", PGC_USERSET, CLIENT_CONN_OTHER,
2266                         gettext_noop("Time between TCP keepalive retransmits."),
2267                         gettext_noop("A value of 0 uses the system default."),
2268                         GUC_UNIT_S
2269                 },
2270                 &tcp_keepalives_interval,
2271                 0, 0, INT_MAX,
2272                 NULL, assign_tcp_keepalives_interval, show_tcp_keepalives_interval
2273         },
2274
2275         {
2276                 {"ssl_renegotiation_limit", PGC_USERSET, CONN_AUTH_SECURITY,
2277                         gettext_noop("Set the amount of traffic to send and receive before renegotiating the encryption keys."),
2278                         NULL,
2279                         GUC_UNIT_KB,
2280                 },
2281                 &ssl_renegotiation_limit,
2282                 512 * 1024, 0, MAX_KILOBYTES,
2283                 NULL, NULL, NULL
2284         },
2285
2286         {
2287                 {"tcp_keepalives_count", PGC_USERSET, CLIENT_CONN_OTHER,
2288                         gettext_noop("Maximum number of TCP keepalive retransmits."),
2289                         gettext_noop("This controls the number of consecutive keepalive retransmits that can be "
2290                                                  "lost before a connection is considered dead. A value of 0 uses the "
2291                                                  "system default."),
2292                 },
2293                 &tcp_keepalives_count,
2294                 0, 0, INT_MAX,
2295                 NULL, assign_tcp_keepalives_count, show_tcp_keepalives_count
2296         },
2297
2298         {
2299                 {"gin_fuzzy_search_limit", PGC_USERSET, CLIENT_CONN_OTHER,
2300                         gettext_noop("Sets the maximum allowed result for exact search by GIN."),
2301                         NULL,
2302                         0
2303                 },
2304                 &GinFuzzySearchLimit,
2305                 0, 0, INT_MAX,
2306                 NULL, NULL, NULL
2307         },
2308
2309         {
2310                 {"effective_cache_size", PGC_USERSET, QUERY_TUNING_COST,
2311                         gettext_noop("Sets the planner's assumption about the size of the disk cache."),
2312                         gettext_noop("That is, the portion of the kernel's disk cache that "
2313                                                  "will be used for PostgreSQL data files. This is measured in disk "
2314                                                  "pages, which are normally 8 kB each."),
2315                         GUC_UNIT_BLOCKS,
2316                 },
2317                 &effective_cache_size,
2318                 DEFAULT_EFFECTIVE_CACHE_SIZE, 1, INT_MAX,
2319                 NULL, NULL, NULL
2320         },
2321
2322         {
2323                 /* Can't be set in postgresql.conf */
2324                 {"server_version_num", PGC_INTERNAL, PRESET_OPTIONS,
2325                         gettext_noop("Shows the server version as an integer."),
2326                         NULL,
2327                         GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE
2328                 },
2329                 &server_version_num,
2330                 PG_VERSION_NUM, PG_VERSION_NUM, PG_VERSION_NUM,
2331                 NULL, NULL, NULL
2332         },
2333
2334         {
2335                 {"log_temp_files", PGC_SUSET, LOGGING_WHAT,
2336                         gettext_noop("Log the use of temporary files larger than this number of kilobytes."),
2337                         gettext_noop("Zero logs all files. The default is -1 (turning this feature off)."),
2338                         GUC_UNIT_KB
2339                 },
2340                 &log_temp_files,
2341                 -1, -1, INT_MAX,
2342                 NULL, NULL, NULL
2343         },
2344
2345         {
2346                 {"track_activity_query_size", PGC_POSTMASTER, RESOURCES_MEM,
2347                         gettext_noop("Sets the size reserved for pg_stat_activity.current_query, in bytes."),
2348                         NULL,
2349                 },
2350                 &pgstat_track_activity_query_size,
2351                 1024, 100, 102400,
2352                 NULL, NULL, NULL
2353         },
2354
2355         /* End-of-list marker */
2356         {
2357                 {NULL, 0, 0, NULL, NULL}, NULL, 0, 0, 0, NULL, NULL, NULL
2358         }
2359 };
2360
2361
2362 static struct config_real ConfigureNamesReal[] =
2363 {
2364         {
2365                 {"seq_page_cost", PGC_USERSET, QUERY_TUNING_COST,
2366                         gettext_noop("Sets the planner's estimate of the cost of a "
2367                                                  "sequentially fetched disk page."),
2368                         NULL
2369                 },
2370                 &seq_page_cost,
2371                 DEFAULT_SEQ_PAGE_COST, 0, DBL_MAX,
2372                 NULL, NULL, NULL
2373         },
2374         {
2375                 {"random_page_cost", PGC_USERSET, QUERY_TUNING_COST,
2376                         gettext_noop("Sets the planner's estimate of the cost of a "
2377                                                  "nonsequentially fetched disk page."),
2378                         NULL
2379                 },
2380                 &random_page_cost,
2381                 DEFAULT_RANDOM_PAGE_COST, 0, DBL_MAX,
2382                 NULL, NULL, NULL
2383         },
2384         {
2385                 {"cpu_tuple_cost", PGC_USERSET, QUERY_TUNING_COST,
2386                         gettext_noop("Sets the planner's estimate of the cost of "
2387                                                  "processing each tuple (row)."),
2388                         NULL
2389                 },
2390                 &cpu_tuple_cost,
2391                 DEFAULT_CPU_TUPLE_COST, 0, DBL_MAX,
2392                 NULL, NULL, NULL
2393         },
2394         {
2395                 {"cpu_index_tuple_cost", PGC_USERSET, QUERY_TUNING_COST,
2396                         gettext_noop("Sets the planner's estimate of the cost of "
2397                                                  "processing each index entry during an index scan."),
2398                         NULL
2399                 },
2400                 &cpu_index_tuple_cost,
2401                 DEFAULT_CPU_INDEX_TUPLE_COST, 0, DBL_MAX,
2402                 NULL, NULL, NULL
2403         },
2404         {
2405                 {"cpu_operator_cost", PGC_USERSET, QUERY_TUNING_COST,
2406                         gettext_noop("Sets the planner's estimate of the cost of "
2407                                                  "processing each operator or function call."),
2408                         NULL
2409                 },
2410                 &cpu_operator_cost,
2411                 DEFAULT_CPU_OPERATOR_COST, 0, DBL_MAX,
2412                 NULL, NULL, NULL
2413         },
2414
2415         {
2416                 {"cursor_tuple_fraction", PGC_USERSET, QUERY_TUNING_OTHER,
2417                         gettext_noop("Sets the planner's estimate of the fraction of "
2418                                                  "a cursor's rows that will be retrieved."),
2419                         NULL
2420                 },
2421                 &cursor_tuple_fraction,
2422                 DEFAULT_CURSOR_TUPLE_FRACTION, 0.0, 1.0,
2423                 NULL, NULL, NULL
2424         },
2425
2426         {
2427                 {"geqo_selection_bias", PGC_USERSET, QUERY_TUNING_GEQO,
2428                         gettext_noop("GEQO: selective pressure within the population."),
2429                         NULL
2430                 },
2431                 &Geqo_selection_bias,
2432                 DEFAULT_GEQO_SELECTION_BIAS,
2433                 MIN_GEQO_SELECTION_BIAS, MAX_GEQO_SELECTION_BIAS,
2434                 NULL, NULL, NULL
2435         },
2436         {
2437                 {"geqo_seed", PGC_USERSET, QUERY_TUNING_GEQO,
2438                         gettext_noop("GEQO: seed for random path selection."),
2439                         NULL
2440                 },
2441                 &Geqo_seed,
2442                 0.0, 0.0, 1.0,
2443                 NULL, NULL, NULL
2444         },
2445
2446         {
2447                 {"bgwriter_lru_multiplier", PGC_SIGHUP, RESOURCES_BGWRITER,
2448                         gettext_noop("Multiple of the average buffer usage to free per round."),
2449                         NULL
2450                 },
2451                 &bgwriter_lru_multiplier,
2452                 2.0, 0.0, 10.0,
2453                 NULL, NULL, NULL
2454         },
2455
2456         {
2457                 {"seed", PGC_USERSET, UNGROUPED,
2458                         gettext_noop("Sets the seed for random-number generation."),
2459                         NULL,
2460                         GUC_NO_SHOW_ALL | GUC_NO_RESET_ALL | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE
2461                 },
2462                 &phony_random_seed,
2463                 0.0, -1.0, 1.0,
2464                 check_random_seed, assign_random_seed, show_random_seed
2465         },
2466
2467         {
2468                 {"autovacuum_vacuum_scale_factor", PGC_SIGHUP, AUTOVACUUM,
2469                         gettext_noop("Number of tuple updates or deletes prior to vacuum as a fraction of reltuples."),
2470                         NULL
2471                 },
2472                 &autovacuum_vac_scale,
2473                 0.2, 0.0, 100.0,
2474                 NULL, NULL, NULL
2475         },
2476         {
2477                 {"autovacuum_analyze_scale_factor", PGC_SIGHUP, AUTOVACUUM,
2478                         gettext_noop("Number of tuple inserts, updates or deletes prior to analyze as a fraction of reltuples."),
2479                         NULL
2480                 },
2481                 &autovacuum_anl_scale,
2482                 0.1, 0.0, 100.0,
2483                 NULL, NULL, NULL
2484         },
2485
2486         {
2487                 {"checkpoint_completion_target", PGC_SIGHUP, WAL_CHECKPOINTS,
2488                         gettext_noop("Time spent flushing dirty buffers during checkpoint, as fraction of checkpoint interval."),
2489                         NULL
2490                 },
2491                 &CheckPointCompletionTarget,
2492                 0.5, 0.0, 1.0,
2493                 NULL, NULL, NULL
2494         },
2495
2496         /* End-of-list marker */
2497         {
2498                 {NULL, 0, 0, NULL, NULL}, NULL, 0.0, 0.0, 0.0, NULL, NULL, NULL
2499         }
2500 };
2501
2502
2503 static struct config_string ConfigureNamesString[] =
2504 {
2505         {
2506                 {"archive_command", PGC_SIGHUP, WAL_ARCHIVING,
2507                         gettext_noop("Sets the shell command that will be called to archive a WAL file."),
2508                         NULL
2509                 },
2510                 &XLogArchiveCommand,
2511                 "",
2512                 NULL, NULL, show_archive_command
2513         },
2514
2515         {
2516                 {"client_encoding", PGC_USERSET, CLIENT_CONN_LOCALE,
2517                         gettext_noop("Sets the client's character set encoding."),
2518                         NULL,
2519                         GUC_IS_NAME | GUC_REPORT
2520                 },
2521                 &client_encoding_string,
2522                 "SQL_ASCII",
2523                 check_client_encoding, assign_client_encoding, NULL
2524         },
2525
2526         {
2527                 {"log_line_prefix", PGC_SIGHUP, LOGGING_WHAT,
2528                         gettext_noop("Controls information prefixed to each log line."),
2529                         gettext_noop("If blank, no prefix is used.")
2530                 },
2531                 &Log_line_prefix,
2532                 "",
2533                 NULL, NULL, NULL
2534         },
2535
2536         {
2537                 {"log_timezone", PGC_SIGHUP, LOGGING_WHAT,
2538                         gettext_noop("Sets the time zone to use in log messages."),
2539                         NULL
2540                 },
2541                 &log_timezone_string,
2542                 NULL,
2543                 check_log_timezone, assign_log_timezone, show_log_timezone
2544         },
2545
2546         {
2547                 {"DateStyle", PGC_USERSET, CLIENT_CONN_LOCALE,
2548                         gettext_noop("Sets the display format for date and time values."),
2549                         gettext_noop("Also controls interpretation of ambiguous "
2550                                                  "date inputs."),
2551                         GUC_LIST_INPUT | GUC_REPORT
2552                 },
2553                 &datestyle_string,
2554                 "ISO, MDY",
2555                 check_datestyle, assign_datestyle, NULL
2556         },
2557
2558         {
2559                 {"default_tablespace", PGC_USERSET, CLIENT_CONN_STATEMENT,
2560                         gettext_noop("Sets the default tablespace to create tables and indexes in."),
2561                         gettext_noop("An empty string selects the database's default tablespace."),
2562                         GUC_IS_NAME
2563                 },
2564                 &default_tablespace,
2565                 "",
2566                 check_default_tablespace, NULL, NULL
2567         },
2568
2569         {
2570                 {"temp_tablespaces", PGC_USERSET, CLIENT_CONN_STATEMENT,
2571                         gettext_noop("Sets the tablespace(s) to use for temporary tables and sort files."),
2572                         NULL,
2573                         GUC_LIST_INPUT | GUC_LIST_QUOTE
2574                 },
2575                 &temp_tablespaces,
2576                 "",
2577                 check_temp_tablespaces, assign_temp_tablespaces, NULL
2578         },
2579
2580         {
2581                 {"dynamic_library_path", PGC_SUSET, CLIENT_CONN_OTHER,
2582                         gettext_noop("Sets the path for dynamically loadable modules."),
2583                         gettext_noop("If a dynamically loadable module needs to be opened and "
2584                                                  "the specified name does not have a directory component (i.e., the "
2585                                                  "name does not contain a slash), the system will search this path for "
2586                                                  "the specified file."),
2587                         GUC_SUPERUSER_ONLY
2588                 },
2589                 &Dynamic_library_path,
2590                 "$libdir",
2591                 NULL, NULL, NULL
2592         },
2593
2594         {
2595                 {"krb_server_keyfile", PGC_SIGHUP, CONN_AUTH_SECURITY,
2596                         gettext_noop("Sets the location of the Kerberos server key file."),
2597                         NULL,
2598                         GUC_SUPERUSER_ONLY
2599                 },
2600                 &pg_krb_server_keyfile,
2601                 PG_KRB_SRVTAB,
2602                 NULL, NULL, NULL
2603         },
2604
2605         {
2606                 {"krb_srvname", PGC_SIGHUP, CONN_AUTH_SECURITY,
2607                         gettext_noop("Sets the name of the Kerberos service."),
2608                         NULL
2609                 },
2610                 &pg_krb_srvnam,
2611                 PG_KRB_SRVNAM,
2612                 NULL, NULL, NULL
2613         },
2614
2615         {
2616                 {"bonjour_name", PGC_POSTMASTER, CONN_AUTH_SETTINGS,
2617                         gettext_noop("Sets the Bonjour service name."),
2618                         NULL
2619                 },
2620                 &bonjour_name,
2621                 "",
2622                 NULL, NULL, NULL
2623         },
2624
2625         /* See main.c about why defaults for LC_foo are not all alike */
2626
2627         {
2628                 {"lc_collate", PGC_INTERNAL, CLIENT_CONN_LOCALE,
2629                         gettext_noop("Shows the collation order locale."),
2630                         NULL,
2631                         GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE
2632                 },
2633                 &locale_collate,
2634                 "C",
2635                 NULL, NULL, NULL
2636         },
2637
2638         {
2639                 {"lc_ctype", PGC_INTERNAL, CLIENT_CONN_LOCALE,
2640                         gettext_noop("Shows the character classification and case conversion locale."),
2641                         NULL,
2642                         GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE
2643                 },
2644                 &locale_ctype,
2645                 "C",
2646                 NULL, NULL, NULL
2647         },
2648
2649         {
2650                 {"lc_messages", PGC_SUSET, CLIENT_CONN_LOCALE,
2651                         gettext_noop("Sets the language in which messages are displayed."),
2652                         NULL
2653                 },
2654                 &locale_messages,
2655                 "",
2656                 check_locale_messages, assign_locale_messages, NULL
2657         },
2658
2659         {
2660                 {"lc_monetary", PGC_USERSET, CLIENT_CONN_LOCALE,
2661                         gettext_noop("Sets the locale for formatting monetary amounts."),
2662                         NULL
2663                 },
2664                 &locale_monetary,
2665                 "C",
2666                 check_locale_monetary, assign_locale_monetary, NULL
2667         },
2668
2669         {
2670                 {"lc_numeric", PGC_USERSET, CLIENT_CONN_LOCALE,
2671                         gettext_noop("Sets the locale for formatting numbers."),
2672                         NULL
2673                 },
2674                 &locale_numeric,
2675                 "C",
2676                 check_locale_numeric, assign_locale_numeric, NULL
2677         },
2678
2679         {
2680                 {"lc_time", PGC_USERSET, CLIENT_CONN_LOCALE,
2681                         gettext_noop("Sets the locale for formatting date and time values."),
2682                         NULL
2683                 },
2684                 &locale_time,
2685                 "C",
2686                 check_locale_time, assign_locale_time, NULL
2687         },
2688
2689         {
2690                 {"shared_preload_libraries", PGC_POSTMASTER, RESOURCES_KERNEL,
2691                         gettext_noop("Lists shared libraries to preload into server."),
2692                         NULL,
2693                         GUC_LIST_INPUT | GUC_LIST_QUOTE | GUC_SUPERUSER_ONLY
2694                 },
2695                 &shared_preload_libraries_string,
2696                 "",
2697                 NULL, NULL, NULL
2698         },
2699
2700         {
2701                 {"local_preload_libraries", PGC_BACKEND, CLIENT_CONN_OTHER,
2702                         gettext_noop("Lists shared libraries to preload into each backend."),
2703                         NULL,
2704                         GUC_LIST_INPUT | GUC_LIST_QUOTE
2705                 },
2706                 &local_preload_libraries_string,
2707                 "",
2708                 NULL, NULL, NULL
2709         },
2710
2711         {
2712                 {"search_path", PGC_USERSET, CLIENT_CONN_STATEMENT,
2713                         gettext_noop("Sets the schema search order for names that are not schema-qualified."),
2714                         NULL,
2715                         GUC_LIST_INPUT | GUC_LIST_QUOTE
2716                 },
2717                 &namespace_search_path,
2718                 "\"$user\",public",
2719                 check_search_path, assign_search_path, NULL
2720         },
2721
2722         {
2723                 /* Can't be set in postgresql.conf */
2724                 {"server_encoding", PGC_INTERNAL, CLIENT_CONN_LOCALE,
2725                         gettext_noop("Sets the server (database) character set encoding."),
2726                         NULL,
2727                         GUC_IS_NAME | GUC_REPORT | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE
2728                 },
2729                 &server_encoding_string,
2730                 "SQL_ASCII",
2731                 NULL, NULL, NULL
2732         },
2733
2734         {
2735                 /* Can't be set in postgresql.conf */
2736                 {"server_version", PGC_INTERNAL, PRESET_OPTIONS,
2737                         gettext_noop("Shows the server version."),
2738                         NULL,
2739                         GUC_REPORT | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE
2740                 },
2741                 &server_version_string,
2742                 PG_VERSION,
2743                 NULL, NULL, NULL
2744         },
2745
2746         {
2747                 /* Not for general use --- used by SET ROLE */
2748                 {"role", PGC_USERSET, UNGROUPED,
2749                         gettext_noop("Sets the current role."),
2750                         NULL,
2751                         GUC_IS_NAME | GUC_NO_SHOW_ALL | GUC_NO_RESET_ALL | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE | GUC_NOT_WHILE_SEC_REST
2752                 },
2753                 &role_string,
2754                 "none",
2755                 check_role, assign_role, show_role
2756         },
2757
2758         {
2759                 /* Not for general use --- used by SET SESSION AUTHORIZATION */
2760                 {"session_authorization", PGC_USERSET, UNGROUPED,
2761                         gettext_noop("Sets the session user name."),
2762                         NULL,
2763                         GUC_IS_NAME | GUC_REPORT | GUC_NO_SHOW_ALL | GUC_NO_RESET_ALL | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE | GUC_NOT_WHILE_SEC_REST
2764                 },
2765                 &session_authorization_string,
2766                 NULL,
2767                 check_session_authorization, assign_session_authorization, NULL
2768         },
2769
2770         {
2771                 {"log_destination", PGC_SIGHUP, LOGGING_WHERE,
2772                         gettext_noop("Sets the destination for server log output."),
2773                         gettext_noop("Valid values are combinations of \"stderr\", "
2774                                                  "\"syslog\", \"csvlog\", and \"eventlog\", "
2775                                                  "depending on the platform."),
2776                         GUC_LIST_INPUT
2777                 },
2778                 &log_destination_string,
2779                 "stderr",
2780                 check_log_destination, assign_log_destination, NULL
2781         },
2782         {
2783                 {"log_directory", PGC_SIGHUP, LOGGING_WHERE,
2784                         gettext_noop("Sets the destination directory for log files."),
2785                         gettext_noop("Can be specified as relative to the data directory "
2786                                                  "or as absolute path."),
2787                         GUC_SUPERUSER_ONLY
2788                 },
2789                 &Log_directory,
2790                 "pg_log",
2791                 check_canonical_path, NULL, NULL
2792         },
2793         {
2794                 {"log_filename", PGC_SIGHUP, LOGGING_WHERE,
2795                         gettext_noop("Sets the file name pattern for log files."),
2796                         NULL,
2797                         GUC_SUPERUSER_ONLY
2798                 },
2799                 &Log_filename,
2800                 "postgresql-%Y-%m-%d_%H%M%S.log",
2801                 NULL, NULL, NULL
2802         },
2803
2804         {
2805                 {"syslog_ident", PGC_SIGHUP, LOGGING_WHERE,
2806                         gettext_noop("Sets the program name used to identify PostgreSQL "
2807                                                  "messages in syslog."),
2808                         NULL
2809                 },
2810                 &syslog_ident_str,
2811                 "postgres",
2812                 NULL, assign_syslog_ident, NULL
2813         },
2814
2815         {
2816                 {"TimeZone", PGC_USERSET, CLIENT_CONN_LOCALE,
2817                         gettext_noop("Sets the time zone for displaying and interpreting time stamps."),
2818                         NULL,
2819                         GUC_REPORT
2820                 },
2821                 &timezone_string,
2822                 NULL,
2823                 check_timezone, assign_timezone, show_timezone
2824         },
2825         {
2826                 {"timezone_abbreviations", PGC_USERSET, CLIENT_CONN_LOCALE,
2827                         gettext_noop("Selects a file of time zone abbreviations."),
2828                         NULL
2829                 },
2830                 &timezone_abbreviations_string,
2831                 NULL,
2832                 check_timezone_abbreviations, assign_timezone_abbreviations, NULL
2833         },
2834
2835         {
2836                 {"transaction_isolation", PGC_USERSET, CLIENT_CONN_STATEMENT,
2837                         gettext_noop("Sets the current transaction's isolation level."),
2838                         NULL,
2839                         GUC_NO_RESET_ALL | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE
2840                 },
2841                 &XactIsoLevel_string,
2842                 "default",
2843                 check_XactIsoLevel, assign_XactIsoLevel, show_XactIsoLevel
2844         },
2845
2846         {
2847                 {"unix_socket_group", PGC_POSTMASTER, CONN_AUTH_SETTINGS,
2848                         gettext_noop("Sets the owning group of the Unix-domain socket."),
2849                         gettext_noop("The owning user of the socket is always the user "
2850                                                  "that starts the server.")
2851                 },
2852                 &Unix_socket_group,
2853                 "",
2854                 NULL, NULL, NULL
2855         },
2856
2857         {
2858                 {"unix_socket_directory", PGC_POSTMASTER, CONN_AUTH_SETTINGS,
2859                         gettext_noop("Sets the directory where the Unix-domain socket will be created."),
2860                         NULL,
2861                         GUC_SUPERUSER_ONLY
2862                 },
2863                 &UnixSocketDir,
2864                 "",
2865                 check_canonical_path, NULL, NULL
2866         },
2867
2868         {
2869                 {"listen_addresses", PGC_POSTMASTER, CONN_AUTH_SETTINGS,
2870                         gettext_noop("Sets the host name or IP address(es) to listen to."),
2871                         NULL,
2872                         GUC_LIST_INPUT
2873                 },
2874                 &ListenAddresses,
2875                 "localhost",
2876                 NULL, NULL, NULL
2877         },
2878
2879         {
2880                 {"custom_variable_classes", PGC_SIGHUP, CUSTOM_OPTIONS,
2881                         gettext_noop("Sets the list of known custom variable classes."),
2882                         NULL,
2883                         GUC_LIST_INPUT | GUC_LIST_QUOTE
2884                 },
2885                 &custom_variable_classes,
2886                 NULL,
2887                 check_custom_variable_classes, NULL, NULL
2888         },
2889
2890         {
2891                 {"data_directory", PGC_POSTMASTER, FILE_LOCATIONS,
2892                         gettext_noop("Sets the server's data directory."),
2893                         NULL,
2894                         GUC_SUPERUSER_ONLY
2895                 },
2896                 &data_directory,
2897                 NULL,
2898                 NULL, NULL, NULL
2899         },
2900
2901         {
2902                 {"config_file", PGC_POSTMASTER, FILE_LOCATIONS,
2903                         gettext_noop("Sets the server's main configuration file."),
2904                         NULL,
2905                         GUC_DISALLOW_IN_FILE | GUC_SUPERUSER_ONLY
2906                 },
2907                 &ConfigFileName,
2908                 NULL,
2909                 NULL, NULL, NULL
2910         },
2911
2912         {
2913                 {"hba_file", PGC_POSTMASTER, FILE_LOCATIONS,
2914                         gettext_noop("Sets the server's \"hba\" configuration file."),
2915                         NULL,
2916                         GUC_SUPERUSER_ONLY
2917                 },
2918                 &HbaFileName,
2919                 NULL,
2920                 NULL, NULL, NULL
2921         },
2922
2923         {
2924                 {"ident_file", PGC_POSTMASTER, FILE_LOCATIONS,
2925                         gettext_noop("Sets the server's \"ident\" configuration file."),
2926                         NULL,
2927                         GUC_SUPERUSER_ONLY
2928                 },
2929                 &IdentFileName,
2930                 NULL,
2931                 NULL, NULL, NULL
2932         },
2933
2934         {
2935                 {"external_pid_file", PGC_POSTMASTER, FILE_LOCATIONS,
2936                         gettext_noop("Writes the postmaster PID to the specified file."),
2937                         NULL,
2938                         GUC_SUPERUSER_ONLY
2939                 },
2940                 &external_pid_file,
2941                 NULL,
2942                 check_canonical_path, NULL, NULL
2943         },
2944
2945         {
2946                 {"stats_temp_directory", PGC_SIGHUP, STATS_COLLECTOR,
2947                         gettext_noop("Writes temporary statistics files to the specified directory."),
2948                         NULL,
2949                         GUC_SUPERUSER_ONLY
2950                 },
2951                 &pgstat_temp_directory,
2952                 "pg_stat_tmp",
2953                 check_canonical_path, assign_pgstat_temp_directory, NULL
2954         },
2955
2956         {
2957                 {"synchronous_standby_names", PGC_SIGHUP, WAL_REPLICATION,
2958                         gettext_noop("List of potential standby names to synchronize with."),
2959                         NULL,
2960                         GUC_LIST_INPUT
2961                 },
2962                 &SyncRepStandbyNames,
2963                 "",
2964                 check_synchronous_standby_names, NULL, NULL
2965         },
2966
2967         {
2968                 {"default_text_search_config", PGC_USERSET, CLIENT_CONN_LOCALE,
2969                         gettext_noop("Sets default text search configuration."),
2970                         NULL
2971                 },
2972                 &TSCurrentConfig,
2973                 "pg_catalog.simple",
2974                 check_TSCurrentConfig, assign_TSCurrentConfig, NULL
2975         },
2976
2977         {
2978                 {"ssl_ciphers", PGC_POSTMASTER, CONN_AUTH_SECURITY,
2979                         gettext_noop("Sets the list of allowed SSL ciphers."),
2980                         NULL,
2981                         GUC_SUPERUSER_ONLY
2982                 },
2983                 &SSLCipherSuites,
2984 #ifdef USE_SSL
2985                 "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH",
2986 #else
2987                 "none",
2988 #endif
2989                 NULL, NULL, NULL
2990         },
2991
2992         {
2993                 {"application_name", PGC_USERSET, LOGGING_WHAT,
2994                         gettext_noop("Sets the application name to be reported in statistics and logs."),
2995                         NULL,
2996                         GUC_IS_NAME | GUC_REPORT | GUC_NOT_IN_SAMPLE
2997                 },
2998                 &application_name,
2999                 "",
3000                 check_application_name, assign_application_name, NULL
3001         },
3002
3003         /* End-of-list marker */
3004         {
3005                 {NULL, 0, 0, NULL, NULL}, NULL, NULL, NULL, NULL, NULL
3006         }
3007 };
3008
3009
3010 static struct config_enum ConfigureNamesEnum[] =
3011 {
3012         {
3013                 {"backslash_quote", PGC_USERSET, COMPAT_OPTIONS_PREVIOUS,
3014                         gettext_noop("Sets whether \"\\'\" is allowed in string literals."),
3015                         NULL
3016                 },
3017                 &backslash_quote,
3018                 BACKSLASH_QUOTE_SAFE_ENCODING, backslash_quote_options,
3019                 NULL, NULL, NULL
3020         },
3021
3022         {
3023                 {"bytea_output", PGC_USERSET, CLIENT_CONN_STATEMENT,
3024                         gettext_noop("Sets the output format for bytea."),
3025                         NULL
3026                 },
3027                 &bytea_output,
3028                 BYTEA_OUTPUT_HEX, bytea_output_options,
3029                 NULL, NULL, NULL
3030         },
3031
3032         {
3033                 {"client_min_messages", PGC_USERSET, LOGGING_WHEN,
3034                         gettext_noop("Sets the message levels that are sent to the client."),
3035                         gettext_noop("Each level includes all the levels that follow it. The later"
3036                                                  " the level, the fewer messages are sent.")
3037                 },
3038                 &client_min_messages,
3039                 NOTICE, client_message_level_options,
3040                 NULL, NULL, NULL
3041         },
3042
3043         {
3044                 {"constraint_exclusion", PGC_USERSET, QUERY_TUNING_OTHER,
3045                         gettext_noop("Enables the planner to use constraints to optimize queries."),
3046                         gettext_noop("Table scans will be skipped if their constraints"
3047                                                  " guarantee that no rows match the query.")
3048                 },
3049                 &constraint_exclusion,
3050                 CONSTRAINT_EXCLUSION_PARTITION, constraint_exclusion_options,
3051                 NULL, NULL, NULL
3052         },
3053
3054         {
3055                 {"default_transaction_isolation", PGC_USERSET, CLIENT_CONN_STATEMENT,
3056                         gettext_noop("Sets the transaction isolation level of each new transaction."),
3057                         NULL
3058                 },
3059                 &DefaultXactIsoLevel,
3060                 XACT_READ_COMMITTED, isolation_level_options,
3061                 NULL, NULL, NULL
3062         },
3063
3064         {
3065                 {"IntervalStyle", PGC_USERSET, CLIENT_CONN_LOCALE,
3066                         gettext_noop("Sets the display format for interval values."),
3067                         NULL,
3068                         GUC_REPORT
3069                 },
3070                 &IntervalStyle,
3071                 INTSTYLE_POSTGRES, intervalstyle_options,
3072                 NULL, NULL, NULL
3073         },
3074
3075         {
3076                 {"log_error_verbosity", PGC_SUSET, LOGGING_WHAT,
3077                         gettext_noop("Sets the verbosity of logged messages."),
3078                         NULL
3079                 },
3080                 &Log_error_verbosity,
3081                 PGERROR_DEFAULT, log_error_verbosity_options,
3082                 NULL, NULL, NULL
3083         },
3084
3085         {
3086                 {"log_min_messages", PGC_SUSET, LOGGING_WHEN,
3087                         gettext_noop("Sets the message levels that are logged."),
3088                         gettext_noop("Each level includes all the levels that follow it. The later"
3089                                                  " the level, the fewer messages are sent.")
3090                 },
3091                 &log_min_messages,
3092                 WARNING, server_message_level_options,
3093                 NULL, NULL, NULL
3094         },
3095
3096         {
3097                 {"log_min_error_statement", PGC_SUSET, LOGGING_WHEN,
3098                         gettext_noop("Causes all statements generating error at or above this level to be logged."),
3099                         gettext_noop("Each level includes all the levels that follow it. The later"
3100                                                  " the level, the fewer messages are sent.")
3101                 },
3102                 &log_min_error_statement,
3103                 ERROR, server_message_level_options,
3104                 NULL, NULL, NULL
3105         },
3106
3107         {
3108                 {"log_statement", PGC_SUSET, LOGGING_WHAT,
3109                         gettext_noop("Sets the type of statements logged."),
3110                         NULL
3111                 },
3112                 &log_statement,
3113                 LOGSTMT_NONE, log_statement_options,
3114                 NULL, NULL, NULL
3115         },
3116
3117         {
3118                 {"syslog_facility", PGC_SIGHUP, LOGGING_WHERE,
3119                         gettext_noop("Sets the syslog \"facility\" to be used when syslog enabled."),
3120                         NULL
3121                 },
3122                 &syslog_facility,
3123 #ifdef HAVE_SYSLOG
3124                 LOG_LOCAL0,
3125 #else
3126                 0,
3127 #endif
3128                 syslog_facility_options,
3129                 NULL, assign_syslog_facility, NULL
3130         },
3131
3132         {
3133                 {"session_replication_role", PGC_SUSET, CLIENT_CONN_STATEMENT,
3134                         gettext_noop("Sets the session's behavior for triggers and rewrite rules."),
3135                         NULL
3136                 },
3137                 &SessionReplicationRole,
3138                 SESSION_REPLICATION_ROLE_ORIGIN, session_replication_role_options,
3139                 NULL, assign_session_replication_role, NULL
3140         },
3141
3142         {
3143                 {"synchronous_commit", PGC_USERSET, WAL_SETTINGS,
3144                         gettext_noop("Sets the current transaction's synchronization level."),
3145                         NULL
3146                 },
3147                 &synchronous_commit,
3148                 SYNCHRONOUS_COMMIT_ON, synchronous_commit_options,
3149                 NULL, NULL, NULL
3150         },
3151
3152         {
3153                 {"trace_recovery_messages", PGC_SIGHUP, DEVELOPER_OPTIONS,
3154                         gettext_noop("Enables logging of recovery-related debugging information."),
3155                         gettext_noop("Each level includes all the levels that follow it. The later"
3156                                                  " the level, the fewer messages are sent.")
3157                 },
3158                 &trace_recovery_messages,
3159
3160                 /*
3161                  * client_message_level_options allows too many values, really, but
3162                  * it's not worth having a separate options array for this.
3163                  */
3164                 LOG, client_message_level_options,
3165                 NULL, NULL, NULL
3166         },
3167
3168         {
3169                 {"track_functions", PGC_SUSET, STATS_COLLECTOR,
3170                         gettext_noop("Collects function-level statistics on database activity."),
3171                         NULL
3172                 },
3173                 &pgstat_track_functions,
3174                 TRACK_FUNC_OFF, track_function_options,
3175                 NULL, NULL, NULL
3176         },
3177
3178         {
3179                 {"wal_level", PGC_POSTMASTER, WAL_SETTINGS,
3180                         gettext_noop("Set the level of information written to the WAL."),
3181                         NULL
3182                 },
3183                 &wal_level,
3184                 WAL_LEVEL_MINIMAL, wal_level_options,
3185                 NULL, NULL, NULL
3186         },
3187
3188         {
3189                 {"wal_sync_method", PGC_SIGHUP, WAL_SETTINGS,
3190                         gettext_noop("Selects the method used for forcing WAL updates to disk."),
3191                         NULL
3192                 },
3193                 &sync_method,
3194                 DEFAULT_SYNC_METHOD, sync_method_options,
3195                 NULL, assign_xlog_sync_method, NULL
3196         },
3197
3198         {
3199                 {"xmlbinary", PGC_USERSET, CLIENT_CONN_STATEMENT,
3200                         gettext_noop("Sets how binary values are to be encoded in XML."),
3201                         NULL
3202                 },
3203                 &xmlbinary,
3204                 XMLBINARY_BASE64, xmlbinary_options,
3205                 NULL, NULL, NULL
3206         },
3207
3208         {
3209                 {"xmloption", PGC_USERSET, CLIENT_CONN_STATEMENT,
3210                         gettext_noop("Sets whether XML data in implicit parsing and serialization "
3211                                                  "operations is to be considered as documents or content fragments."),
3212                         NULL
3213                 },
3214                 &xmloption,
3215                 XMLOPTION_CONTENT, xmloption_options,
3216                 NULL, NULL, NULL
3217         },
3218
3219
3220         /* End-of-list marker */
3221         {
3222                 {NULL, 0, 0, NULL, NULL}, NULL, 0, NULL, NULL, NULL, NULL
3223         }
3224 };
3225
3226 /******** end of options list ********/
3227
3228
3229 /*
3230  * To allow continued support of obsolete names for GUC variables, we apply
3231  * the following mappings to any unrecognized name.  Note that an old name
3232  * should be mapped to a new one only if the new variable has very similar
3233  * semantics to the old.
3234  */
3235 static const char *const map_old_guc_names[] = {
3236         "sort_mem", "work_mem",
3237         "vacuum_mem", "maintenance_work_mem",
3238         NULL
3239 };
3240
3241
3242 /*
3243  * Actual lookup of variables is done through this single, sorted array.
3244  */
3245 static struct config_generic **guc_variables;
3246
3247 /* Current number of variables contained in the vector */
3248 static int      num_guc_variables;
3249
3250 /* Vector capacity */
3251 static int      size_guc_variables;
3252
3253
3254 static bool guc_dirty;                  /* TRUE if need to do commit/abort work */
3255
3256 static bool reporting_enabled;  /* TRUE to enable GUC_REPORT */
3257
3258 static int      GUCNestLevel = 0;       /* 1 when in main transaction */
3259
3260
3261 static int      guc_var_compare(const void *a, const void *b);
3262 static int      guc_name_compare(const char *namea, const char *nameb);
3263 static void InitializeGUCOptionsFromEnvironment(void);
3264 static void InitializeOneGUCOption(struct config_generic * gconf);
3265 static void push_old_value(struct config_generic * gconf, GucAction action);
3266 static void ReportGUCOption(struct config_generic * record);
3267 static void ShowGUCConfigOption(const char *name, DestReceiver *dest);
3268 static void ShowAllGUCConfig(DestReceiver *dest);
3269 static char *_ShowOption(struct config_generic * record, bool use_units);
3270 static bool validate_option_array_item(const char *name, const char *value,
3271                                                    bool skipIfNoPermissions);
3272
3273
3274 /*
3275  * Some infrastructure for checking malloc/strdup/realloc calls
3276  */
3277 static void *
3278 guc_malloc(int elevel, size_t size)
3279 {
3280         void       *data;
3281
3282         data = malloc(size);
3283         if (data == NULL)
3284                 ereport(elevel,
3285                                 (errcode(ERRCODE_OUT_OF_MEMORY),
3286                                  errmsg("out of memory")));
3287         return data;
3288 }
3289
3290 static void *
3291 guc_realloc(int elevel, void *old, size_t size)
3292 {
3293         void       *data;
3294
3295         data = realloc(old, size);
3296         if (data == NULL)
3297                 ereport(elevel,
3298                                 (errcode(ERRCODE_OUT_OF_MEMORY),
3299                                  errmsg("out of memory")));
3300         return data;
3301 }
3302
3303 static char *
3304 guc_strdup(int elevel, const char *src)
3305 {
3306         char       *data;
3307
3308         data = strdup(src);
3309         if (data == NULL)
3310                 ereport(elevel,
3311                                 (errcode(ERRCODE_OUT_OF_MEMORY),
3312                                  errmsg("out of memory")));
3313         return data;
3314 }
3315
3316
3317 /*
3318  * Detect whether strval is referenced anywhere in a GUC string item
3319  */
3320 static bool
3321 string_field_used(struct config_string * conf, char *strval)
3322 {
3323         GucStack   *stack;
3324
3325         if (strval == *(conf->variable) ||
3326                 strval == conf->reset_val ||
3327                 strval == conf->boot_val)
3328                 return true;
3329         for (stack = conf->gen.stack; stack; stack = stack->prev)
3330         {
3331                 if (strval == stack->prior.val.stringval ||
3332                         strval == stack->masked.val.stringval)
3333                         return true;
3334         }
3335         return false;
3336 }
3337
3338 /*
3339  * Support for assigning to a field of a string GUC item.  Free the prior
3340  * value if it's not referenced anywhere else in the item (including stacked
3341  * states).
3342  */
3343 static void
3344 set_string_field(struct config_string * conf, char **field, char *newval)
3345 {
3346         char       *oldval = *field;
3347
3348         /* Do the assignment */
3349         *field = newval;
3350
3351         /* Free old value if it's not NULL and isn't referenced anymore */
3352         if (oldval && !string_field_used(conf, oldval))
3353                 free(oldval);
3354 }
3355
3356 /*
3357  * Detect whether an "extra" struct is referenced anywhere in a GUC item
3358  */
3359 static bool
3360 extra_field_used(struct config_generic * gconf, void *extra)
3361 {
3362         GucStack   *stack;
3363
3364         if (extra == gconf->extra)
3365                 return true;
3366         switch (gconf->vartype)
3367         {
3368                 case PGC_BOOL:
3369                         if (extra == ((struct config_bool *) gconf)->reset_extra)
3370                                 return true;
3371                         break;
3372                 case PGC_INT:
3373                         if (extra == ((struct config_int *) gconf)->reset_extra)
3374                                 return true;
3375                         break;
3376                 case PGC_REAL:
3377                         if (extra == ((struct config_real *) gconf)->reset_extra)
3378                                 return true;
3379                         break;
3380                 case PGC_STRING:
3381                         if (extra == ((struct config_string *) gconf)->reset_extra)
3382                                 return true;
3383                         break;
3384                 case PGC_ENUM:
3385                         if (extra == ((struct config_enum *) gconf)->reset_extra)
3386                                 return true;
3387                         break;
3388         }
3389         for (stack = gconf->stack; stack; stack = stack->prev)
3390         {
3391                 if (extra == stack->prior.extra ||
3392                         extra == stack->masked.extra)
3393                         return true;
3394         }
3395
3396         return false;
3397 }
3398
3399 /*
3400  * Support for assigning to an "extra" field of a GUC item.  Free the prior
3401  * value if it's not referenced anywhere else in the item (including stacked
3402  * states).
3403  */
3404 static void
3405 set_extra_field(struct config_generic * gconf, void **field, void *newval)
3406 {
3407         void       *oldval = *field;
3408
3409         /* Do the assignment */
3410         *field = newval;
3411
3412         /* Free old value if it's not NULL and isn't referenced anymore */
3413         if (oldval && !extra_field_used(gconf, oldval))
3414                 free(oldval);
3415 }
3416
3417 /*
3418  * Support for copying a variable's active value into a stack entry.
3419  * The "extra" field associated with the active value is copied, too.
3420  *
3421  * NB: be sure stringval and extra fields of a new stack entry are
3422  * initialized to NULL before this is used, else we'll try to free() them.
3423  */
3424 static void
3425 set_stack_value(struct config_generic * gconf, config_var_value *val)
3426 {
3427         switch (gconf->vartype)
3428         {
3429                 case PGC_BOOL:
3430                         val->val.boolval =
3431                                 *((struct config_bool *) gconf)->variable;
3432                         break;
3433                 case PGC_INT:
3434                         val->val.intval =
3435                                 *((struct config_int *) gconf)->variable;
3436                         break;
3437                 case PGC_REAL:
3438                         val->val.realval =
3439                                 *((struct config_real *) gconf)->variable;
3440                         break;
3441                 case PGC_STRING:
3442                         set_string_field((struct config_string *) gconf,
3443                                                          &(val->val.stringval),
3444                                                          *((struct config_string *) gconf)->variable);
3445                         break;
3446                 case PGC_ENUM:
3447                         val->val.enumval =
3448                                 *((struct config_enum *) gconf)->variable;
3449                         break;
3450         }
3451         set_extra_field(gconf, &(val->extra), gconf->extra);
3452 }
3453
3454 /*
3455  * Support for discarding a no-longer-needed value in a stack entry.
3456  * The "extra" field associated with the stack entry is cleared, too.
3457  */
3458 static void
3459 discard_stack_value(struct config_generic * gconf, config_var_value *val)
3460 {
3461         switch (gconf->vartype)
3462         {
3463                 case PGC_BOOL:
3464                 case PGC_INT:
3465                 case PGC_REAL:
3466                 case PGC_ENUM:
3467                         /* no need to do anything */
3468                         break;
3469                 case PGC_STRING:
3470                         set_string_field((struct config_string *) gconf,
3471                                                          &(val->val.stringval),
3472                                                          NULL);
3473                         break;
3474         }
3475         set_extra_field(gconf, &(val->extra), NULL);
3476 }
3477
3478
3479 /*
3480  * Fetch the sorted array pointer (exported for help_config.c's use ONLY)
3481  */
3482 struct config_generic **
3483 get_guc_variables(void)
3484 {
3485         return guc_variables;
3486 }
3487
3488
3489 /*
3490  * Build the sorted array.      This is split out so that it could be
3491  * re-executed after startup (eg, we could allow loadable modules to
3492  * add vars, and then we'd need to re-sort).
3493  */
3494 void
3495 build_guc_variables(void)
3496 {
3497         int                     size_vars;
3498         int                     num_vars = 0;
3499         struct config_generic **guc_vars;
3500         int                     i;
3501
3502         for (i = 0; ConfigureNamesBool[i].gen.name; i++)
3503         {
3504                 struct config_bool *conf = &ConfigureNamesBool[i];
3505
3506                 /* Rather than requiring vartype to be filled in by hand, do this: */
3507                 conf->gen.vartype = PGC_BOOL;
3508                 num_vars++;
3509         }
3510
3511         for (i = 0; ConfigureNamesInt[i].gen.name; i++)
3512         {
3513                 struct config_int *conf = &ConfigureNamesInt[i];
3514
3515                 conf->gen.vartype = PGC_INT;
3516                 num_vars++;
3517         }
3518
3519         for (i = 0; ConfigureNamesReal[i].gen.name; i++)
3520         {
3521                 struct config_real *conf = &ConfigureNamesReal[i];
3522
3523                 conf->gen.vartype = PGC_REAL;
3524                 num_vars++;
3525         }
3526
3527         for (i = 0; ConfigureNamesString[i].gen.name; i++)
3528         {
3529                 struct config_string *conf = &ConfigureNamesString[i];
3530
3531                 conf->gen.vartype = PGC_STRING;
3532                 num_vars++;
3533         }
3534
3535         for (i = 0; ConfigureNamesEnum[i].gen.name; i++)
3536         {
3537                 struct config_enum *conf = &ConfigureNamesEnum[i];
3538
3539                 conf->gen.vartype = PGC_ENUM;
3540                 num_vars++;
3541         }
3542
3543         /*
3544          * Create table with 20% slack
3545          */
3546         size_vars = num_vars + num_vars / 4;
3547
3548         guc_vars = (struct config_generic **)
3549                 guc_malloc(FATAL, size_vars * sizeof(struct config_generic *));
3550
3551         num_vars = 0;
3552
3553         for (i = 0; ConfigureNamesBool[i].gen.name; i++)
3554                 guc_vars[num_vars++] = &ConfigureNamesBool[i].gen;
3555
3556         for (i = 0; ConfigureNamesInt[i].gen.name; i++)
3557                 guc_vars[num_vars++] = &ConfigureNamesInt[i].gen;
3558
3559         for (i = 0; ConfigureNamesReal[i].gen.name; i++)
3560                 guc_vars[num_vars++] = &ConfigureNamesReal[i].gen;
3561
3562         for (i = 0; ConfigureNamesString[i].gen.name; i++)
3563                 guc_vars[num_vars++] = &ConfigureNamesString[i].gen;
3564
3565         for (i = 0; ConfigureNamesEnum[i].gen.name; i++)
3566                 guc_vars[num_vars++] = &ConfigureNamesEnum[i].gen;
3567
3568         if (guc_variables)
3569                 free(guc_variables);
3570         guc_variables = guc_vars;
3571         num_guc_variables = num_vars;
3572         size_guc_variables = size_vars;
3573         qsort((void *) guc_variables, num_guc_variables,
3574                   sizeof(struct config_generic *), guc_var_compare);
3575 }
3576
3577 /*
3578  * Add a new GUC variable to the list of known variables. The
3579  * list is expanded if needed.
3580  */
3581 static bool
3582 add_guc_variable(struct config_generic * var, int elevel)
3583 {
3584         if (num_guc_variables + 1 >= size_guc_variables)
3585         {
3586                 /*
3587                  * Increase the vector by 25%
3588                  */
3589                 int                     size_vars = size_guc_variables + size_guc_variables / 4;
3590                 struct config_generic **guc_vars;
3591
3592                 if (size_vars == 0)
3593                 {
3594                         size_vars = 100;
3595                         guc_vars = (struct config_generic **)
3596                                 guc_malloc(elevel, size_vars * sizeof(struct config_generic *));
3597                 }
3598                 else
3599                 {
3600                         guc_vars = (struct config_generic **)
3601                                 guc_realloc(elevel, guc_variables, size_vars * sizeof(struct config_generic *));
3602                 }
3603
3604                 if (guc_vars == NULL)
3605                         return false;           /* out of memory */
3606
3607                 guc_variables = guc_vars;
3608                 size_guc_variables = size_vars;
3609         }
3610         guc_variables[num_guc_variables++] = var;
3611         qsort((void *) guc_variables, num_guc_variables,
3612                   sizeof(struct config_generic *), guc_var_compare);
3613         return true;
3614 }
3615
3616 /*
3617  * Create and add a placeholder variable. It's presumed to belong
3618  * to a valid custom variable class at this point.
3619  */
3620 static struct config_generic *
3621 add_placeholder_variable(const char *name, int elevel)
3622 {
3623         size_t          sz = sizeof(struct config_string) + sizeof(char *);
3624         struct config_string *var;
3625         struct config_generic *gen;
3626
3627         var = (struct config_string *) guc_malloc(elevel, sz);
3628         if (var == NULL)
3629                 return NULL;
3630         memset(var, 0, sz);
3631         gen = &var->gen;
3632
3633         gen->name = guc_strdup(elevel, name);
3634         if (gen->name == NULL)
3635         {
3636                 free(var);
3637                 return NULL;
3638         }
3639
3640         gen->context = PGC_USERSET;
3641         gen->group = CUSTOM_OPTIONS;
3642         gen->short_desc = "GUC placeholder variable";
3643         gen->flags = GUC_NO_SHOW_ALL | GUC_NOT_IN_SAMPLE | GUC_CUSTOM_PLACEHOLDER;
3644         gen->vartype = PGC_STRING;
3645
3646         /*
3647          * The char* is allocated at the end of the struct since we have no
3648          * 'static' place to point to.  Note that the current value, as well as
3649          * the boot and reset values, start out NULL.
3650          */
3651         var->variable = (char **) (var + 1);
3652
3653         if (!add_guc_variable((struct config_generic *) var, elevel))
3654         {
3655                 free((void *) gen->name);
3656                 free(var);
3657                 return NULL;
3658         }
3659
3660         return gen;
3661 }
3662
3663 /*
3664  * Detect whether the portion of "name" before dotPos matches any custom
3665  * variable class name listed in custom_var_classes.  The latter must be
3666  * formatted the way that assign_custom_variable_classes does it, ie,
3667  * no whitespace.  NULL is valid for custom_var_classes.
3668  */
3669 static bool
3670 is_custom_class(const char *name, int dotPos, const char *custom_var_classes)
3671 {
3672         bool            result = false;
3673         const char *ccs = custom_var_classes;
3674
3675         if (ccs != NULL)
3676         {
3677                 const char *start = ccs;
3678
3679                 for (;; ++ccs)
3680                 {
3681                         char            c = *ccs;
3682
3683                         if (c == '\0' || c == ',')
3684                         {
3685                                 if (dotPos == ccs - start && strncmp(start, name, dotPos) == 0)
3686                                 {
3687                                         result = true;
3688                                         break;
3689                                 }
3690                                 if (c == '\0')
3691                                         break;
3692                                 start = ccs + 1;
3693                         }
3694                 }
3695         }
3696         return result;
3697 }
3698
3699 /*
3700  * Look up option NAME.  If it exists, return a pointer to its record,
3701  * else return NULL.  If create_placeholders is TRUE, we'll create a
3702  * placeholder record for a valid-looking custom variable name.
3703  */
3704 static struct config_generic *
3705 find_option(const char *name, bool create_placeholders, int elevel)
3706 {
3707         const char **key = &name;
3708         struct config_generic **res;
3709         int                     i;
3710
3711         Assert(name);
3712
3713         /*
3714          * By equating const char ** with struct config_generic *, we are assuming
3715          * the name field is first in config_generic.
3716          */
3717         res = (struct config_generic **) bsearch((void *) &key,
3718                                                                                          (void *) guc_variables,
3719                                                                                          num_guc_variables,
3720                                                                                          sizeof(struct config_generic *),
3721                                                                                          guc_var_compare);
3722         if (res)
3723                 return *res;
3724
3725         /*
3726          * See if the name is an obsolete name for a variable.  We assume that the
3727          * set of supported old names is short enough that a brute-force search is
3728          * the best way.
3729          */
3730         for (i = 0; map_old_guc_names[i] != NULL; i += 2)
3731         {
3732                 if (guc_name_compare(name, map_old_guc_names[i]) == 0)
3733                         return find_option(map_old_guc_names[i + 1], false, elevel);
3734         }
3735
3736         if (create_placeholders)
3737         {
3738                 /*
3739                  * Check if the name is qualified, and if so, check if the qualifier
3740                  * matches any custom variable class.  If so, add a placeholder.
3741                  */
3742                 const char *dot = strchr(name, GUC_QUALIFIER_SEPARATOR);
3743
3744                 if (dot != NULL &&
3745                         is_custom_class(name, dot - name, custom_variable_classes))
3746                         return add_placeholder_variable(name, elevel);
3747         }
3748
3749         /* Unknown name */
3750         return NULL;
3751 }
3752
3753
3754 /*
3755  * comparator for qsorting and bsearching guc_variables array
3756  */
3757 static int
3758 guc_var_compare(const void *a, const void *b)
3759 {
3760         struct config_generic *confa = *(struct config_generic **) a;
3761         struct config_generic *confb = *(struct config_generic **) b;
3762
3763         return guc_name_compare(confa->name, confb->name);
3764 }
3765
3766 /*
3767  * the bare comparison function for GUC names
3768  */
3769 static int
3770 guc_name_compare(const char *namea, const char *nameb)
3771 {
3772         /*
3773          * The temptation to use strcasecmp() here must be resisted, because the
3774          * array ordering has to remain stable across setlocale() calls. So, build
3775          * our own with a simple ASCII-only downcasing.
3776          */
3777         while (*namea && *nameb)
3778         {
3779                 char            cha = *namea++;
3780                 char            chb = *nameb++;
3781
3782                 if (cha >= 'A' && cha <= 'Z')
3783                         cha += 'a' - 'A';
3784                 if (chb >= 'A' && chb <= 'Z')
3785                         chb += 'a' - 'A';
3786                 if (cha != chb)
3787                         return cha - chb;
3788         }
3789         if (*namea)
3790                 return 1;                               /* a is longer */
3791         if (*nameb)
3792                 return -1;                              /* b is longer */
3793         return 0;
3794 }
3795
3796
3797 /*
3798  * Initialize GUC options during program startup.
3799  *
3800  * Note that we cannot read the config file yet, since we have not yet
3801  * processed command-line switches.
3802  */
3803 void
3804 InitializeGUCOptions(void)
3805 {
3806         int                     i;
3807
3808         /*
3809          * Before log_line_prefix could possibly receive a nonempty setting, make
3810          * sure that timezone processing is minimally alive (see elog.c).
3811          */
3812         pg_timezone_pre_initialize();
3813
3814         /*
3815          * Build sorted array of all GUC variables.
3816          */
3817         build_guc_variables();
3818
3819         /*
3820          * Load all variables with their compiled-in defaults, and initialize
3821          * status fields as needed.
3822          */
3823         for (i = 0; i < num_guc_variables; i++)
3824         {
3825                 InitializeOneGUCOption(guc_variables[i]);
3826         }
3827
3828         guc_dirty = false;
3829
3830         reporting_enabled = false;
3831
3832         /*
3833          * Prevent any attempt to override the transaction modes from
3834          * non-interactive sources.
3835          */
3836         SetConfigOption("transaction_isolation", "default",
3837                                         PGC_POSTMASTER, PGC_S_OVERRIDE);
3838         SetConfigOption("transaction_read_only", "no",
3839                                         PGC_POSTMASTER, PGC_S_OVERRIDE);
3840         SetConfigOption("transaction_deferrable", "no",
3841                                         PGC_POSTMASTER, PGC_S_OVERRIDE);
3842
3843         /*
3844          * For historical reasons, some GUC parameters can receive defaults from
3845          * environment variables.  Process those settings.
3846          */
3847         InitializeGUCOptionsFromEnvironment();
3848 }
3849
3850 /*
3851  * Assign any GUC values that can come from the server's environment.
3852  *
3853  * This is called from InitializeGUCOptions, and also from ProcessConfigFile
3854  * to deal with the possibility that a setting has been removed from
3855  * postgresql.conf and should now get a value from the environment.
3856  * (The latter is a kludge that should probably go away someday; if so,
3857  * fold this back into InitializeGUCOptions.)
3858  */
3859 static void
3860 InitializeGUCOptionsFromEnvironment(void)
3861 {
3862         char       *env;
3863         long            stack_rlimit;
3864
3865         env = getenv("PGPORT");
3866         if (env != NULL)
3867                 SetConfigOption("port", env, PGC_POSTMASTER, PGC_S_ENV_VAR);
3868
3869         env = getenv("PGDATESTYLE");
3870         if (env != NULL)
3871                 SetConfigOption("datestyle", env, PGC_POSTMASTER, PGC_S_ENV_VAR);
3872
3873         env = getenv("PGCLIENTENCODING");
3874         if (env != NULL)
3875                 SetConfigOption("client_encoding", env, PGC_POSTMASTER, PGC_S_ENV_VAR);
3876
3877         /*
3878          * rlimit isn't exactly an "environment variable", but it behaves about
3879          * the same.  If we can identify the platform stack depth rlimit, increase
3880          * default stack depth setting up to whatever is safe (but at most 2MB).
3881          */
3882         stack_rlimit = get_stack_depth_rlimit();
3883         if (stack_rlimit > 0)
3884         {
3885                 long            new_limit = (stack_rlimit - STACK_DEPTH_SLOP) / 1024L;
3886
3887                 if (new_limit > 100)
3888                 {
3889                         char            limbuf[16];
3890
3891                         new_limit = Min(new_limit, 2048);
3892                         sprintf(limbuf, "%ld", new_limit);
3893                         SetConfigOption("max_stack_depth", limbuf,
3894                                                         PGC_POSTMASTER, PGC_S_ENV_VAR);
3895                 }
3896         }
3897 }
3898
3899 /*
3900  * Initialize one GUC option variable to its compiled-in default.
3901  *
3902  * Note: the reason for calling check_hooks is not that we think the boot_val
3903  * might fail, but that the hooks might wish to compute an "extra" struct.
3904  */
3905 static void
3906 InitializeOneGUCOption(struct config_generic * gconf)
3907 {
3908         gconf->status = 0;
3909         gconf->reset_source = PGC_S_DEFAULT;
3910         gconf->source = PGC_S_DEFAULT;
3911         gconf->stack = NULL;
3912         gconf->extra = NULL;
3913         gconf->sourcefile = NULL;
3914         gconf->sourceline = 0;
3915
3916         switch (gconf->vartype)
3917         {
3918                 case PGC_BOOL:
3919                         {
3920                                 struct config_bool *conf = (struct config_bool *) gconf;
3921                                 bool            newval = conf->boot_val;
3922                                 void       *extra = NULL;
3923
3924                                 if (!call_bool_check_hook(conf, &newval, &extra,
3925                                                                                   PGC_S_DEFAULT, LOG))
3926                                         elog(FATAL, "failed to initialize %s to %d",
3927                                                  conf->gen.name, (int) newval);
3928                                 if (conf->assign_hook)
3929                                         (*conf->assign_hook) (newval, extra);
3930                                 *conf->variable = conf->reset_val = newval;
3931                                 conf->gen.extra = conf->reset_extra = extra;
3932                                 break;
3933                         }
3934                 case PGC_INT:
3935                         {
3936                                 struct config_int *conf = (struct config_int *) gconf;
3937                                 int                     newval = conf->boot_val;
3938                                 void       *extra = NULL;
3939
3940                                 Assert(newval >= conf->min);
3941                                 Assert(newval <= conf->max);
3942                                 if (!call_int_check_hook(conf, &newval, &extra,
3943                                                                                  PGC_S_DEFAULT, LOG))
3944                                         elog(FATAL, "failed to initialize %s to %d",
3945                                                  conf->gen.name, newval);
3946                                 if (conf->assign_hook)
3947                                         (*conf->assign_hook) (newval, extra);
3948                                 *conf->variable = conf->reset_val = newval;
3949                                 conf->gen.extra = conf->reset_extra = extra;
3950                                 break;
3951                         }
3952                 case PGC_REAL:
3953                         {
3954                                 struct config_real *conf = (struct config_real *) gconf;
3955                                 double          newval = conf->boot_val;
3956                                 void       *extra = NULL;
3957
3958                                 Assert(newval >= conf->min);
3959                                 Assert(newval <= conf->max);
3960                                 if (!call_real_check_hook(conf, &newval, &extra,
3961                                                                                   PGC_S_DEFAULT, LOG))
3962                                         elog(FATAL, "failed to initialize %s to %g",
3963                                                  conf->gen.name, newval);
3964                                 if (conf->assign_hook)
3965                                         (*conf->assign_hook) (newval, extra);
3966                                 *conf->variable = conf->reset_val = newval;
3967                                 conf->gen.extra = conf->reset_extra = extra;
3968                                 break;
3969                         }
3970                 case PGC_STRING:
3971                         {
3972                                 struct config_string *conf = (struct config_string *) gconf;
3973                                 char       *newval;
3974                                 void       *extra = NULL;
3975
3976                                 /* non-NULL boot_val must always get strdup'd */
3977                                 if (conf->boot_val != NULL)
3978                                         newval = guc_strdup(FATAL, conf->boot_val);
3979                                 else
3980                                         newval = NULL;
3981
3982                                 if (!call_string_check_hook(conf, &newval, &extra,
3983                                                                                         PGC_S_DEFAULT, LOG))
3984                                         elog(FATAL, "failed to initialize %s to \"%s\"",
3985                                                  conf->gen.name, newval ? newval : "");
3986                                 if (conf->assign_hook)
3987                                         (*conf->assign_hook) (newval, extra);
3988                                 *conf->variable = conf->reset_val = newval;
3989                                 conf->gen.extra = conf->reset_extra = extra;
3990                                 break;
3991                         }
3992                 case PGC_ENUM:
3993                         {
3994                                 struct config_enum *conf = (struct config_enum *) gconf;
3995                                 int                     newval = conf->boot_val;
3996                                 void       *extra = NULL;
3997
3998                                 if (!call_enum_check_hook(conf, &newval, &extra,
3999                                                                                   PGC_S_DEFAULT, LOG))
4000                                         elog(FATAL, "failed to initialize %s to %d",
4001                                                  conf->gen.name, newval);
4002                                 if (conf->assign_hook)
4003                                         (*conf->assign_hook) (newval, extra);
4004                                 *conf->variable = conf->reset_val = newval;
4005                                 conf->gen.extra = conf->reset_extra = extra;
4006                                 break;
4007                         }
4008         }
4009 }
4010
4011
4012 /*
4013  * Select the configuration files and data directory to be used, and
4014  * do the initial read of postgresql.conf.
4015  *
4016  * This is called after processing command-line switches.
4017  *              userDoption is the -D switch value if any (NULL if unspecified).
4018  *              progname is just for use in error messages.
4019  *
4020  * Returns true on success; on failure, prints a suitable error message
4021  * to stderr and returns false.
4022  */
4023 bool
4024 SelectConfigFiles(const char *userDoption, const char *progname)
4025 {
4026         char       *configdir;
4027         char       *fname;
4028         struct stat stat_buf;
4029
4030         /* configdir is -D option, or $PGDATA if no -D */
4031         if (userDoption)
4032                 configdir = make_absolute_path(userDoption);
4033         else
4034                 configdir = make_absolute_path(getenv("PGDATA"));
4035
4036         /*
4037          * Find the configuration file: if config_file was specified on the
4038          * command line, use it, else use configdir/postgresql.conf.  In any case
4039          * ensure the result is an absolute path, so that it will be interpreted
4040          * the same way by future backends.
4041          */
4042         if (ConfigFileName)
4043                 fname = make_absolute_path(ConfigFileName);
4044         else if (configdir)
4045         {
4046                 fname = guc_malloc(FATAL,
4047                                                    strlen(configdir) + strlen(CONFIG_FILENAME) + 2);
4048                 sprintf(fname, "%s/%s", configdir, CONFIG_FILENAME);
4049         }
4050         else
4051         {
4052                 write_stderr("%s does not know where to find the server configuration file.\n"
4053                                          "You must specify the --config-file or -D invocation "
4054                                          "option or set the PGDATA environment variable.\n",
4055                                          progname);
4056                 return false;
4057         }
4058
4059         /*
4060          * Set the ConfigFileName GUC variable to its final value, ensuring that
4061          * it can't be overridden later.
4062          */
4063         SetConfigOption("config_file", fname, PGC_POSTMASTER, PGC_S_OVERRIDE);
4064         free(fname);
4065
4066         /*
4067          * Now read the config file for the first time.
4068          */
4069         if (stat(ConfigFileName, &stat_buf) != 0)
4070         {
4071                 write_stderr("%s cannot access the server configuration file \"%s\": %s\n",
4072                                          progname, ConfigFileName, strerror(errno));
4073                 return false;
4074         }
4075
4076         ProcessConfigFile(PGC_POSTMASTER);
4077
4078         /*
4079          * If the data_directory GUC variable has been set, use that as DataDir;
4080          * otherwise use configdir if set; else punt.
4081          *
4082          * Note: SetDataDir will copy and absolute-ize its argument, so we don't
4083          * have to.
4084          */
4085         if (data_directory)
4086                 SetDataDir(data_directory);
4087         else if (configdir)
4088                 SetDataDir(configdir);
4089         else
4090         {
4091                 write_stderr("%s does not know where to find the database system data.\n"
4092                                          "This can be specified as \"data_directory\" in \"%s\", "
4093                                          "or by the -D invocation option, or by the "
4094                                          "PGDATA environment variable.\n",
4095                                          progname, ConfigFileName);
4096                 return false;
4097         }
4098
4099         /*
4100          * Reflect the final DataDir value back into the data_directory GUC var.
4101          * (If you are wondering why we don't just make them a single variable,
4102          * it's because the EXEC_BACKEND case needs DataDir to be transmitted to
4103          * child backends specially.  XXX is that still true?  Given that we now
4104          * chdir to DataDir, EXEC_BACKEND can read the config file without knowing
4105          * DataDir in advance.)
4106          */
4107         SetConfigOption("data_directory", DataDir, PGC_POSTMASTER, PGC_S_OVERRIDE);
4108
4109         /*
4110          * Figure out where pg_hba.conf is, and make sure the path is absolute.
4111          */
4112         if (HbaFileName)
4113                 fname = make_absolute_path(HbaFileName);
4114         else if (configdir)
4115         {
4116                 fname = guc_malloc(FATAL,
4117                                                    strlen(configdir) + strlen(HBA_FILENAME) + 2);
4118                 sprintf(fname, "%s/%s", configdir, HBA_FILENAME);
4119         }
4120         else
4121         {
4122                 write_stderr("%s does not know where to find the \"hba\" configuration file.\n"
4123                                          "This can be specified as \"hba_file\" in \"%s\", "
4124                                          "or by the -D invocation option, or by the "
4125                                          "PGDATA environment variable.\n",
4126                                          progname, ConfigFileName);
4127                 return false;
4128         }
4129         SetConfigOption("hba_file", fname, PGC_POSTMASTER, PGC_S_OVERRIDE);
4130         free(fname);
4131
4132         /*
4133          * Likewise for pg_ident.conf.
4134          */
4135         if (IdentFileName)
4136                 fname = make_absolute_path(IdentFileName);
4137         else if (configdir)
4138         {
4139                 fname = guc_malloc(FATAL,
4140                                                    strlen(configdir) + strlen(IDENT_FILENAME) + 2);
4141                 sprintf(fname, "%s/%s", configdir, IDENT_FILENAME);
4142         }
4143         else
4144         {
4145                 write_stderr("%s does not know where to find the \"ident\" configuration file.\n"
4146                                          "This can be specified as \"ident_file\" in \"%s\", "
4147                                          "or by the -D invocation option, or by the "
4148                                          "PGDATA environment variable.\n",
4149                                          progname, ConfigFileName);
4150                 return false;
4151         }
4152         SetConfigOption("ident_file", fname, PGC_POSTMASTER, PGC_S_OVERRIDE);
4153         free(fname);
4154
4155         free(configdir);
4156
4157         return true;
4158 }
4159
4160
4161 /*
4162  * Reset all options to their saved default values (implements RESET ALL)
4163  */
4164 void
4165 ResetAllOptions(void)
4166 {
4167         int                     i;
4168
4169         for (i = 0; i < num_guc_variables; i++)
4170         {
4171                 struct config_generic *gconf = guc_variables[i];
4172
4173                 /* Don't reset non-SET-able values */
4174                 if (gconf->context != PGC_SUSET &&
4175                         gconf->context != PGC_USERSET)
4176                         continue;
4177                 /* Don't reset if special exclusion from RESET ALL */
4178                 if (gconf->flags & GUC_NO_RESET_ALL)
4179                         continue;
4180                 /* No need to reset if wasn't SET */
4181                 if (gconf->source <= PGC_S_OVERRIDE)
4182                         continue;
4183
4184                 /* Save old value to support transaction abort */
4185                 push_old_value(gconf, GUC_ACTION_SET);
4186
4187                 switch (gconf->vartype)
4188                 {
4189                         case PGC_BOOL:
4190                                 {
4191                                         struct config_bool *conf = (struct config_bool *) gconf;
4192
4193                                         if (conf->assign_hook)
4194                                                 (*conf->assign_hook) (conf->reset_val,
4195                                                                                           conf->reset_extra);
4196                                         *conf->variable = conf->reset_val;
4197                                         set_extra_field(&conf->gen, &conf->gen.extra,
4198                                                                         conf->reset_extra);
4199                                         break;
4200                                 }
4201                         case PGC_INT:
4202                                 {
4203                                         struct config_int *conf = (struct config_int *) gconf;
4204
4205                                         if (conf->assign_hook)
4206                                                 (*conf->assign_hook) (conf->reset_val,
4207                                                                                           conf->reset_extra);
4208                                         *conf->variable = conf->reset_val;
4209                                         set_extra_field(&conf->gen, &conf->gen.extra,
4210                                                                         conf->reset_extra);
4211                                         break;
4212                                 }
4213                         case PGC_REAL:
4214                                 {
4215                                         struct config_real *conf = (struct config_real *) gconf;
4216
4217                                         if (conf->assign_hook)
4218                                                 (*conf->assign_hook) (conf->reset_val,
4219                                                                                           conf->reset_extra);
4220                                         *conf->variable = conf->reset_val;
4221                                         set_extra_field(&conf->gen, &conf->gen.extra,
4222                                                                         conf->reset_extra);
4223                                         break;
4224                                 }
4225                         case PGC_STRING:
4226                                 {
4227                                         struct config_string *conf = (struct config_string *) gconf;
4228
4229                                         if (conf->assign_hook)
4230                                                 (*conf->assign_hook) (conf->reset_val,
4231                                                                                           conf->reset_extra);
4232                                         set_string_field(conf, conf->variable, conf->reset_val);
4233                                         set_extra_field(&conf->gen, &conf->gen.extra,
4234                                                                         conf->reset_extra);
4235                                         break;
4236                                 }
4237                         case PGC_ENUM:
4238                                 {
4239                                         struct config_enum *conf = (struct config_enum *) gconf;
4240
4241                                         if (conf->assign_hook)
4242                                                 (*conf->assign_hook) (conf->reset_val,
4243                                                                                           conf->reset_extra);
4244                                         *conf->variable = conf->reset_val;
4245                                         set_extra_field(&conf->gen, &conf->gen.extra,
4246                                                                         conf->reset_extra);
4247                                         break;
4248                                 }
4249                 }
4250
4251                 gconf->source = gconf->reset_source;
4252
4253                 if (gconf->flags & GUC_REPORT)
4254                         ReportGUCOption(gconf);
4255         }
4256 }
4257
4258
4259 /*
4260  * push_old_value
4261  *              Push previous state during transactional assignment to a GUC variable.
4262  */
4263 static void
4264 push_old_value(struct config_generic * gconf, GucAction action)
4265 {
4266         GucStack   *stack;
4267
4268         /* If we're not inside a nest level, do nothing */
4269         if (GUCNestLevel == 0)
4270                 return;
4271
4272         /* Do we already have a stack entry of the current nest level? */
4273         stack = gconf->stack;
4274         if (stack && stack->nest_level >= GUCNestLevel)
4275         {
4276                 /* Yes, so adjust its state if necessary */
4277                 Assert(stack->nest_level == GUCNestLevel);
4278                 switch (action)
4279                 {
4280                         case GUC_ACTION_SET:
4281                                 /* SET overrides any prior action at same nest level */
4282                                 if (stack->state == GUC_SET_LOCAL)
4283                                 {
4284                                         /* must discard old masked value */
4285                                         discard_stack_value(gconf, &stack->masked);
4286                                 }
4287                                 stack->state = GUC_SET;
4288                                 break;
4289                         case GUC_ACTION_LOCAL:
4290                                 if (stack->state == GUC_SET)
4291                                 {
4292                                         /* SET followed by SET LOCAL, remember SET's value */
4293                                         set_stack_value(gconf, &stack->masked);
4294                                         stack->state = GUC_SET_LOCAL;
4295                                 }
4296                                 /* in all other cases, no change to stack entry */
4297                                 break;
4298                         case GUC_ACTION_SAVE:
4299                                 /* Could only have a prior SAVE of same variable */
4300                                 Assert(stack->state == GUC_SAVE);
4301                                 break;
4302                 }
4303                 Assert(guc_dirty);              /* must be set already */
4304                 return;
4305         }
4306
4307         /*
4308          * Push a new stack entry
4309          *
4310          * We keep all the stack entries in TopTransactionContext for simplicity.
4311          */
4312         stack = (GucStack *) MemoryContextAllocZero(TopTransactionContext,
4313                                                                                                 sizeof(GucStack));
4314
4315         stack->prev = gconf->stack;
4316         stack->nest_level = GUCNestLevel;
4317         switch (action)
4318         {
4319                 case GUC_ACTION_SET:
4320                         stack->state = GUC_SET;
4321                         break;
4322                 case GUC_ACTION_LOCAL:
4323                         stack->state = GUC_LOCAL;
4324                         break;
4325                 case GUC_ACTION_SAVE:
4326                         stack->state = GUC_SAVE;
4327                         break;
4328         }
4329         stack->source = gconf->source;
4330         set_stack_value(gconf, &stack->prior);
4331
4332         gconf->stack = stack;
4333
4334         /* Ensure we remember to pop at end of xact */
4335         guc_dirty = true;
4336 }
4337
4338
4339 /*
4340  * Do GUC processing at main transaction start.
4341  */
4342 void
4343 AtStart_GUC(void)
4344 {
4345         /*
4346          * The nest level should be 0 between transactions; if it isn't, somebody
4347          * didn't call AtEOXact_GUC, or called it with the wrong nestLevel.  We
4348          * throw a warning but make no other effort to clean up.
4349          */
4350         if (GUCNestLevel != 0)
4351                 elog(WARNING, "GUC nest level = %d at transaction start",
4352                          GUCNestLevel);
4353         GUCNestLevel = 1;
4354 }
4355
4356 /*
4357  * Enter a new nesting level for GUC values.  This is called at subtransaction
4358  * start and when entering a function that has proconfig settings.      NOTE that
4359  * we must not risk error here, else subtransaction start will be unhappy.
4360  */
4361 int
4362 NewGUCNestLevel(void)
4363 {
4364         return ++GUCNestLevel;
4365 }
4366
4367 /*
4368  * Do GUC processing at transaction or subtransaction commit or abort, or
4369  * when exiting a function that has proconfig settings.  (The name is thus
4370  * a bit of a misnomer; perhaps it should be ExitGUCNestLevel or some such.)
4371  * During abort, we discard all GUC settings that were applied at nesting
4372  * levels >= nestLevel.  nestLevel == 1 corresponds to the main transaction.
4373  */
4374 void
4375 AtEOXact_GUC(bool isCommit, int nestLevel)
4376 {
4377         bool            still_dirty;
4378         int                     i;
4379
4380         /*
4381          * Note: it's possible to get here with GUCNestLevel == nestLevel-1 during
4382          * abort, if there is a failure during transaction start before
4383          * AtStart_GUC is called.
4384          */
4385         Assert(nestLevel > 0 &&
4386                    (nestLevel <= GUCNestLevel ||
4387                         (nestLevel == GUCNestLevel + 1 && !isCommit)));
4388
4389         /* Quick exit if nothing's changed in this transaction */
4390         if (!guc_dirty)
4391         {
4392                 GUCNestLevel = nestLevel - 1;
4393                 return;
4394         }
4395
4396         still_dirty = false;
4397         for (i = 0; i < num_guc_variables; i++)
4398         {
4399                 struct config_generic *gconf = guc_variables[i];
4400                 GucStack   *stack;
4401
4402                 /*
4403                  * Process and pop each stack entry within the nest level.      To
4404                  * simplify fmgr_security_definer(), we allow failure exit from a
4405                  * function-with-SET-options to be recovered at the surrounding
4406                  * transaction or subtransaction abort; so there could be more than
4407                  * one stack entry to pop.
4408                  */
4409                 while ((stack = gconf->stack) != NULL &&
4410                            stack->nest_level >= nestLevel)
4411                 {
4412                         GucStack   *prev = stack->prev;
4413                         bool            restorePrior = false;
4414                         bool            restoreMasked = false;
4415                         bool            changed;
4416
4417                         /*
4418                          * In this next bit, if we don't set either restorePrior or
4419                          * restoreMasked, we must "discard" any unwanted fields of the
4420                          * stack entries to avoid leaking memory.  If we do set one of
4421                          * those flags, unused fields will be cleaned up after restoring.
4422                          */
4423                         if (!isCommit)          /* if abort, always restore prior value */
4424                                 restorePrior = true;
4425                         else if (stack->state == GUC_SAVE)
4426                                 restorePrior = true;
4427                         else if (stack->nest_level == 1)
4428                         {
4429                                 /* transaction commit */
4430                                 if (stack->state == GUC_SET_LOCAL)
4431                                         restoreMasked = true;
4432                                 else if (stack->state == GUC_SET)
4433                                 {
4434                                         /* we keep the current active value */
4435                                         discard_stack_value(gconf, &stack->prior);
4436                                 }
4437                                 else    /* must be GUC_LOCAL */
4438                                         restorePrior = true;
4439                         }
4440                         else if (prev == NULL ||
4441                                          prev->nest_level < stack->nest_level - 1)
4442                         {
4443                                 /* decrement entry's level and do not pop it */
4444                                 stack->nest_level--;
4445                                 continue;
4446                         }
4447                         else
4448                         {
4449                                 /*
4450                                  * We have to merge this stack entry into prev. See README for
4451                                  * discussion of this bit.
4452                                  */
4453                                 switch (stack->state)
4454                                 {
4455                                         case GUC_SAVE:
4456                                                 Assert(false);  /* can't get here */
4457
4458                                         case GUC_SET:
4459                                                 /* next level always becomes SET */
4460                                                 discard_stack_value(gconf, &stack->prior);
4461                                                 if (prev->state == GUC_SET_LOCAL)
4462                                                         discard_stack_value(gconf, &prev->masked);
4463                                                 prev->state = GUC_SET;
4464                                                 break;
4465
4466                                         case GUC_LOCAL:
4467                                                 if (prev->state == GUC_SET)
4468                                                 {
4469                                                         /* LOCAL migrates down */
4470                                                         prev->masked = stack->prior;
4471                                                         prev->state = GUC_SET_LOCAL;
4472                                                 }
4473                                                 else
4474                                                 {
4475                                                         /* else just forget this stack level */
4476                                                         discard_stack_value(gconf, &stack->prior);
4477                                                 }
4478                                                 break;
4479
4480                                         case GUC_SET_LOCAL:
4481                                                 /* prior state at this level no longer wanted */
4482                                                 discard_stack_value(gconf, &stack->prior);
4483                                                 /* copy down the masked state */
4484                                                 if (prev->state == GUC_SET_LOCAL)
4485                                                         discard_stack_value(gconf, &prev->masked);
4486                                                 prev->masked = stack->masked;
4487                                                 prev->state = GUC_SET_LOCAL;
4488                                                 break;
4489                                 }
4490                         }
4491
4492                         changed = false;
4493
4494                         if (restorePrior || restoreMasked)
4495                         {
4496                                 /* Perform appropriate restoration of the stacked value */
4497                                 config_var_value newvalue;
4498                                 GucSource       newsource;
4499
4500                                 if (restoreMasked)
4501                                 {
4502                                         newvalue = stack->masked;
4503                                         newsource = PGC_S_SESSION;
4504                                 }
4505                                 else
4506                                 {
4507                                         newvalue = stack->prior;
4508                                         newsource = stack->source;
4509                                 }
4510
4511                                 switch (gconf->vartype)
4512                                 {
4513                                         case PGC_BOOL:
4514                                                 {
4515                                                         struct config_bool *conf = (struct config_bool *) gconf;
4516                                                         bool            newval = newvalue.val.boolval;
4517                                                         void       *newextra = newvalue.extra;
4518
4519                                                         if (*conf->variable != newval ||
4520                                                                 conf->gen.extra != newextra)
4521                                                         {
4522                                                                 if (conf->assign_hook)
4523                                                                         (*conf->assign_hook) (newval, newextra);
4524                                                                 *conf->variable = newval;
4525                                                                 set_extra_field(&conf->gen, &conf->gen.extra,
4526                                                                                                 newextra);
4527                                                                 changed = true;
4528                                                         }
4529                                                         break;
4530                                                 }
4531                                         case PGC_INT:
4532                                                 {
4533                                                         struct config_int *conf = (struct config_int *) gconf;
4534                                                         int                     newval = newvalue.val.intval;
4535                                                         void       *newextra = newvalue.extra;
4536
4537                                                         if (*conf->variable != newval ||
4538                                                                 conf->gen.extra != newextra)
4539                                                         {
4540                                                                 if (conf->assign_hook)
4541                                                                         (*conf->assign_hook) (newval, newextra);
4542                                                                 *conf->variable = newval;
4543                                                                 set_extra_field(&conf->gen, &conf->gen.extra,
4544                                                                                                 newextra);
4545                                                                 changed = true;
4546                                                         }
4547                                                         break;
4548                                                 }
4549                                         case PGC_REAL:
4550                                                 {
4551                                                         struct config_real *conf = (struct config_real *) gconf;
4552                                                         double          newval = newvalue.val.realval;
4553                                                         void       *newextra = newvalue.extra;
4554
4555                                                         if (*conf->variable != newval ||
4556                                                                 conf->gen.extra != newextra)
4557                                                         {
4558                                                                 if (conf->assign_hook)
4559                                                                         (*conf->assign_hook) (newval, newextra);
4560                                                                 *conf->variable = newval;
4561                                                                 set_extra_field(&conf->gen, &conf->gen.extra,
4562                                                                                                 newextra);
4563                                                                 changed = true;
4564                                                         }
4565                                                         break;
4566                                                 }
4567                                         case PGC_STRING:
4568                                                 {
4569                                                         struct config_string *conf = (struct config_string *) gconf;
4570                                                         char       *newval = newvalue.val.stringval;
4571                                                         void       *newextra = newvalue.extra;
4572
4573                                                         if (*conf->variable != newval ||
4574                                                                 conf->gen.extra != newextra)
4575                                                         {
4576                                                                 if (conf->assign_hook)
4577                                                                         (*conf->assign_hook) (newval, newextra);
4578                                                                 set_string_field(conf, conf->variable, newval);
4579                                                                 set_extra_field(&conf->gen, &conf->gen.extra,
4580                                                                                                 newextra);
4581                                                                 changed = true;
4582                                                         }
4583
4584                                                         /*
4585                                                          * Release stacked values if not used anymore. We
4586                                                          * could use discard_stack_value() here, but since
4587                                                          * we have type-specific code anyway, might as
4588                                                          * well inline it.
4589                                                          */
4590                                                         set_string_field(conf, &stack->prior.val.stringval, NULL);
4591                                                         set_string_field(conf, &stack->masked.val.stringval, NULL);
4592                                                         break;
4593                                                 }
4594                                         case PGC_ENUM:
4595                                                 {
4596                                                         struct config_enum *conf = (struct config_enum *) gconf;
4597                                                         int                     newval = newvalue.val.enumval;
4598                                                         void       *newextra = newvalue.extra;
4599
4600                                                         if (*conf->variable != newval ||
4601                                                                 conf->gen.extra != newextra)
4602                                                         {
4603                                                                 if (conf->assign_hook)
4604                                                                         (*conf->assign_hook) (newval, newextra);
4605                                                                 *conf->variable = newval;
4606                                                                 set_extra_field(&conf->gen, &conf->gen.extra,
4607                                                                                                 newextra);
4608                                                                 changed = true;
4609                                                         }
4610                                                         break;
4611                                                 }
4612                                 }
4613
4614                                 /*
4615                                  * Release stacked extra values if not used anymore.
4616                                  */
4617                                 set_extra_field(gconf, &(stack->prior.extra), NULL);
4618                                 set_extra_field(gconf, &(stack->masked.extra), NULL);
4619
4620                                 gconf->source = newsource;
4621                         }
4622
4623                         /* Finish popping the state stack */
4624                         gconf->stack = prev;
4625                         pfree(stack);
4626
4627                         /* Report new value if we changed it */
4628                         if (changed && (gconf->flags & GUC_REPORT))
4629                                 ReportGUCOption(gconf);
4630                 }                                               /* end of stack-popping loop */
4631
4632                 if (stack != NULL)
4633                         still_dirty = true;
4634         }
4635
4636         /* If there are no remaining stack entries, we can reset guc_dirty */
4637         guc_dirty = still_dirty;
4638
4639         /* Update nesting level */
4640         GUCNestLevel = nestLevel - 1;
4641 }
4642
4643
4644 /*
4645  * Start up automatic reporting of changes to variables marked GUC_REPORT.
4646  * This is executed at completion of backend startup.
4647  */
4648 void
4649 BeginReportingGUCOptions(void)
4650 {
4651         int                     i;
4652
4653         /*
4654          * Don't do anything unless talking to an interactive frontend of protocol
4655          * 3.0 or later.
4656          */
4657         if (whereToSendOutput != DestRemote ||
4658                 PG_PROTOCOL_MAJOR(FrontendProtocol) < 3)
4659                 return;
4660
4661         reporting_enabled = true;
4662
4663         /* Transmit initial values of interesting variables */
4664         for (i = 0; i < num_guc_variables; i++)
4665         {
4666                 struct config_generic *conf = guc_variables[i];
4667
4668                 if (conf->flags & GUC_REPORT)
4669                         ReportGUCOption(conf);
4670         }
4671 }
4672
4673 /*
4674  * ReportGUCOption: if appropriate, transmit option value to frontend
4675  */
4676 static void
4677 ReportGUCOption(struct config_generic * record)
4678 {
4679         if (reporting_enabled && (record->flags & GUC_REPORT))
4680         {
4681                 char       *val = _ShowOption(record, false);
4682                 StringInfoData msgbuf;
4683
4684                 pq_beginmessage(&msgbuf, 'S');
4685                 pq_sendstring(&msgbuf, record->name);
4686                 pq_sendstring(&msgbuf, val);
4687                 pq_endmessage(&msgbuf);
4688
4689                 pfree(val);
4690         }
4691 }
4692
4693 /*
4694  * Try to parse value as an integer.  The accepted formats are the
4695  * usual decimal, octal, or hexadecimal formats, optionally followed by
4696  * a unit name if "flags" indicates a unit is allowed.
4697  *
4698  * If the string parses okay, return true, else false.
4699  * If okay and result is not NULL, return the value in *result.
4700  * If not okay and hintmsg is not NULL, *hintmsg is set to a suitable
4701  *      HINT message, or NULL if no hint provided.
4702  */
4703 bool
4704 parse_int(const char *value, int *result, int flags, const char **hintmsg)
4705 {
4706         int64           val;
4707         char       *endptr;
4708
4709         /* To suppress compiler warnings, always set output params */
4710         if (result)
4711                 *result = 0;
4712         if (hintmsg)
4713                 *hintmsg = NULL;
4714
4715         /* We assume here that int64 is at least as wide as long */
4716         errno = 0;
4717         val = strtol(value, &endptr, 0);
4718
4719         if (endptr == value)
4720                 return false;                   /* no HINT for integer syntax error */
4721
4722         if (errno == ERANGE || val != (int64) ((int32) val))
4723         {
4724                 if (hintmsg)
4725                         *hintmsg = gettext_noop("Value exceeds integer range.");
4726                 return false;
4727         }
4728
4729         /* allow whitespace between integer and unit */
4730         while (isspace((unsigned char) *endptr))
4731                 endptr++;
4732
4733         /* Handle possible unit */
4734         if (*endptr != '\0')
4735         {
4736                 /*
4737                  * Note: the multiple-switch coding technique here is a bit tedious,
4738                  * but seems necessary to avoid intermediate-value overflows.
4739                  */
4740                 if (flags & GUC_UNIT_MEMORY)
4741                 {
4742                         /* Set hint for use if no match or trailing garbage */
4743                         if (hintmsg)
4744                                 *hintmsg = gettext_noop("Valid units for this parameter are \"kB\", \"MB\", and \"GB\".");
4745
4746 #if BLCKSZ < 1024 || BLCKSZ > (1024*1024)
4747 #error BLCKSZ must be between 1KB and 1MB
4748 #endif
4749 #if XLOG_BLCKSZ < 1024 || XLOG_BLCKSZ > (1024*1024)
4750 #error XLOG_BLCKSZ must be between 1KB and 1MB
4751 #endif
4752
4753                         if (strncmp(endptr, "kB", 2) == 0)
4754                         {
4755                                 endptr += 2;
4756                                 switch (flags & GUC_UNIT_MEMORY)
4757                                 {
4758                                         case GUC_UNIT_BLOCKS:
4759                                                 val /= (BLCKSZ / 1024);
4760                                                 break;
4761                                         case GUC_UNIT_XBLOCKS:
4762                                                 val /= (XLOG_BLCKSZ / 1024);
4763                                                 break;
4764                                 }
4765                         }
4766                         else if (strncmp(endptr, "MB", 2) == 0)
4767                         {
4768                                 endptr += 2;
4769                                 switch (flags & GUC_UNIT_MEMORY)
4770                                 {
4771                                         case GUC_UNIT_KB:
4772                                                 val *= KB_PER_MB;
4773                                                 break;
4774                                         case GUC_UNIT_BLOCKS:
4775                                                 val *= KB_PER_MB / (BLCKSZ / 1024);
4776                                                 break;
4777                                         case GUC_UNIT_XBLOCKS:
4778                                                 val *= KB_PER_MB / (XLOG_BLCKSZ / 1024);
4779                                                 break;
4780                                 }
4781                         }
4782                         else if (strncmp(endptr, "GB", 2) == 0)
4783                         {
4784                                 endptr += 2;
4785                                 switch (flags & GUC_UNIT_MEMORY)
4786                                 {
4787                                         case GUC_UNIT_KB:
4788                                                 val *= KB_PER_GB;
4789                                                 break;
4790                                         case GUC_UNIT_BLOCKS:
4791                                                 val *= KB_PER_GB / (BLCKSZ / 1024);
4792                                                 break;
4793                                         case GUC_UNIT_XBLOCKS:
4794                                                 val *= KB_PER_GB / (XLOG_BLCKSZ / 1024);
4795                                                 break;
4796                                 }
4797                         }
4798                 }
4799                 else if (flags & GUC_UNIT_TIME)
4800                 {
4801                         /* Set hint for use if no match or trailing garbage */
4802                         if (hintmsg)
4803                                 *hintmsg = gettext_noop("Valid units for this parameter are \"ms\", \"s\", \"min\", \"h\", and \"d\".");
4804
4805                         if (strncmp(endptr, "ms", 2) == 0)
4806                         {
4807                                 endptr += 2;
4808                                 switch (flags & GUC_UNIT_TIME)
4809                                 {
4810                                         case GUC_UNIT_S:
4811                                                 val /= MS_PER_S;
4812                                                 break;
4813                                         case GUC_UNIT_MIN:
4814                                                 val /= MS_PER_MIN;
4815                                                 break;
4816                                 }
4817                         }
4818                         else if (strncmp(endptr, "s", 1) == 0)
4819                         {
4820                                 endptr += 1;
4821                                 switch (flags & GUC_UNIT_TIME)
4822                                 {
4823                                         case GUC_UNIT_MS:
4824                                                 val *= MS_PER_S;
4825                                                 break;
4826                                         case GUC_UNIT_MIN:
4827                                                 val /= S_PER_MIN;
4828                                                 break;
4829                                 }
4830                         }
4831                         else if (strncmp(endptr, "min", 3) == 0)
4832                         {
4833                                 endptr += 3;
4834                                 switch (flags & GUC_UNIT_TIME)
4835                                 {
4836                                         case GUC_UNIT_MS:
4837                                                 val *= MS_PER_MIN;
4838                                                 break;
4839                                         case GUC_UNIT_S:
4840                                                 val *= S_PER_MIN;
4841                                                 break;
4842                                 }
4843                         }
4844                         else if (strncmp(endptr, "h", 1) == 0)
4845                         {
4846                                 endptr += 1;
4847                                 switch (flags & GUC_UNIT_TIME)
4848                                 {
4849                                         case GUC_UNIT_MS:
4850                                                 val *= MS_PER_H;
4851                                                 break;
4852                                         case GUC_UNIT_S:
4853                                                 val *= S_PER_H;
4854                                                 break;
4855                                         case GUC_UNIT_MIN:
4856                                                 val *= MIN_PER_H;
4857                                                 break;
4858                                 }
4859                         }
4860                         else if (strncmp(endptr, "d", 1) == 0)
4861                         {
4862                                 endptr += 1;
4863                                 switch (flags & GUC_UNIT_TIME)
4864                                 {
4865                                         case GUC_UNIT_MS:
4866                                                 val *= MS_PER_D;
4867                                                 break;
4868                                         case GUC_UNIT_S:
4869                                                 val *= S_PER_D;
4870                                                 break;
4871                                         case GUC_UNIT_MIN:
4872                                                 val *= MIN_PER_D;
4873                                                 break;
4874                                 }
4875                         }
4876                 }
4877
4878                 /* allow whitespace after unit */
4879                 while (isspace((unsigned char) *endptr))
4880                         endptr++;
4881
4882                 if (*endptr != '\0')
4883                         return false;           /* appropriate hint, if any, already set */
4884
4885                 /* Check for overflow due to units conversion */
4886                 if (val != (int64) ((int32) val))
4887                 {
4888                         if (hintmsg)
4889                                 *hintmsg = gettext_noop("Value exceeds integer range.");
4890                         return false;
4891                 }
4892         }
4893
4894         if (result)
4895                 *result = (int) val;
4896         return true;
4897 }
4898
4899
4900
4901 /*
4902  * Try to parse value as a floating point number in the usual format.
4903  * If the string parses okay, return true, else false.
4904  * If okay and result is not NULL, return the value in *result.
4905  */
4906 bool
4907 parse_real(const char *value, double *result)
4908 {
4909         double          val;
4910         char       *endptr;
4911
4912         if (result)
4913                 *result = 0;                    /* suppress compiler warning */
4914
4915         errno = 0;
4916         val = strtod(value, &endptr);
4917         if (endptr == value || errno == ERANGE)
4918                 return false;
4919
4920         /* allow whitespace after number */
4921         while (isspace((unsigned char) *endptr))
4922                 endptr++;
4923         if (*endptr != '\0')
4924                 return false;
4925
4926         if (result)
4927                 *result = val;
4928         return true;
4929 }
4930
4931
4932 /*
4933  * Lookup the name for an enum option with the selected value.
4934  * Should only ever be called with known-valid values, so throws
4935  * an elog(ERROR) if the enum option is not found.
4936  *
4937  * The returned string is a pointer to static data and not
4938  * allocated for modification.
4939  */
4940 const char *
4941 config_enum_lookup_by_value(struct config_enum * record, int val)
4942 {
4943         const struct config_enum_entry *entry;
4944
4945         for (entry = record->options; entry && entry->name; entry++)
4946         {
4947                 if (entry->val == val)
4948                         return entry->name;
4949         }
4950
4951         elog(ERROR, "could not find enum option %d for %s",
4952                  val, record->gen.name);
4953         return NULL;                            /* silence compiler */
4954 }
4955
4956
4957 /*
4958  * Lookup the value for an enum option with the selected name
4959  * (case-insensitive).
4960  * If the enum option is found, sets the retval value and returns
4961  * true. If it's not found, return FALSE and retval is set to 0.
4962  */
4963 bool
4964 config_enum_lookup_by_name(struct config_enum * record, const char *value,
4965                                                    int *retval)
4966 {
4967         const struct config_enum_entry *entry;
4968
4969         for (entry = record->options; entry && entry->name; entry++)
4970         {
4971                 if (pg_strcasecmp(value, entry->name) == 0)
4972                 {
4973                         *retval = entry->val;
4974                         return TRUE;
4975                 }
4976         }
4977
4978         *retval = 0;
4979         return FALSE;
4980 }
4981
4982
4983 /*
4984  * Return a list of all available options for an enum, excluding
4985  * hidden ones, separated by the given separator.
4986  * If prefix is non-NULL, it is added before the first enum value.
4987  * If suffix is non-NULL, it is added to the end of the string.
4988  */
4989 static char *
4990 config_enum_get_options(struct config_enum * record, const char *prefix,
4991                                                 const char *suffix, const char *separator)
4992 {
4993         const struct config_enum_entry *entry;
4994         StringInfoData retstr;
4995         int                     seplen;
4996
4997         initStringInfo(&retstr);
4998         appendStringInfoString(&retstr, prefix);
4999
5000         seplen = strlen(separator);
5001         for (entry = record->options; entry && entry->name; entry++)
5002         {
5003                 if (!entry->hidden)
5004                 {
5005                         appendStringInfoString(&retstr, entry->name);
5006                         appendBinaryStringInfo(&retstr, separator, seplen);
5007                 }
5008         }
5009
5010         /*
5011          * All the entries may have been hidden, leaving the string empty if no
5012          * prefix was given. This indicates a broken GUC setup, since there is no
5013          * use for an enum without any values, so we just check to make sure we
5014          * don't write to invalid memory instead of actually trying to do
5015          * something smart with it.
5016          */
5017         if (retstr.len >= seplen)
5018         {
5019                 /* Replace final separator */
5020                 retstr.data[retstr.len - seplen] = '\0';
5021                 retstr.len -= seplen;
5022         }
5023
5024         appendStringInfoString(&retstr, suffix);
5025
5026         return retstr.data;
5027 }
5028
5029
5030 /*
5031  * Sets option `name' to given value. The value should be a string
5032  * which is going to be parsed and converted to the appropriate data
5033  * type.  The context and source parameters indicate in which context this
5034  * function is being called so it can apply the access restrictions
5035  * properly.
5036  *
5037  * If value is NULL, set the option to its default value (normally the
5038  * reset_val, but if source == PGC_S_DEFAULT we instead use the boot_val).
5039  *
5040  * action indicates whether to set the value globally in the session, locally
5041  * to the current top transaction, or just for the duration of a function call.
5042  *
5043  * If changeVal is false then don't really set the option but do all
5044  * the checks to see if it would work.
5045  *
5046  * If there is an error (non-existing option, invalid value) then an
5047  * ereport(ERROR) is thrown *unless* this is called in a context where we
5048  * don't want to ereport (currently, startup or SIGHUP config file reread).
5049  * In that case we write a suitable error message via ereport(LOG) and
5050  * return false. This is working around the deficiencies in the ereport
5051  * mechanism, so don't blame me.  In all other cases, the function
5052  * returns true, including cases where the input is valid but we chose
5053  * not to apply it because of context or source-priority considerations.
5054  *
5055  * See also SetConfigOption for an external interface.
5056  */
5057 bool
5058 set_config_option(const char *name, const char *value,
5059                                   GucContext context, GucSource source,
5060                                   GucAction action, bool changeVal)
5061 {
5062         struct config_generic *record;
5063         int                     elevel;
5064         bool            prohibitValueChange = false;
5065         bool            makeDefault;
5066
5067         if (context == PGC_SIGHUP || source == PGC_S_DEFAULT)
5068         {
5069                 /*
5070                  * To avoid cluttering the log, only the postmaster bleats loudly
5071                  * about problems with the config file.
5072                  */
5073                 elevel = IsUnderPostmaster ? DEBUG3 : LOG;
5074         }
5075         else if (source == PGC_S_DATABASE || source == PGC_S_USER ||
5076                          source == PGC_S_DATABASE_USER)
5077                 elevel = WARNING;
5078         else
5079                 elevel = ERROR;
5080
5081         record = find_option(name, true, elevel);
5082         if (record == NULL)
5083         {
5084                 ereport(elevel,
5085                                 (errcode(ERRCODE_UNDEFINED_OBJECT),
5086                            errmsg("unrecognized configuration parameter \"%s\"", name)));
5087                 return false;
5088         }
5089
5090         /*
5091          * If source is postgresql.conf, mark the found record with
5092          * GUC_IS_IN_FILE. This is for the convenience of ProcessConfigFile.  Note
5093          * that we do it even if changeVal is false, since ProcessConfigFile wants
5094          * the marking to occur during its testing pass.
5095          */
5096         if (source == PGC_S_FILE)
5097                 record->status |= GUC_IS_IN_FILE;
5098
5099         /*
5100          * Check if the option can be set at this time. See guc.h for the precise
5101          * rules.
5102          */
5103         switch (record->context)
5104         {
5105                 case PGC_INTERNAL:
5106                         if (context == PGC_SIGHUP)
5107                         {
5108                                 /*
5109                                  * Historically we've just silently ignored attempts to set
5110                                  * PGC_INTERNAL variables from the config file.  Maybe it'd be
5111                                  * better to use the prohibitValueChange logic for this?
5112                                  */
5113                                 return true;
5114                         }
5115                         else if (context != PGC_INTERNAL)
5116                         {
5117                                 ereport(elevel,
5118                                                 (errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
5119                                                  errmsg("parameter \"%s\" cannot be changed",
5120                                                                 name)));
5121                                 return false;
5122                         }
5123                         break;
5124                 case PGC_POSTMASTER:
5125                         if (context == PGC_SIGHUP)
5126                         {
5127                                 /*
5128                                  * We are re-reading a PGC_POSTMASTER variable from
5129                                  * postgresql.conf.  We can't change the setting, so we should
5130                                  * give a warning if the DBA tries to change it.  However,
5131                                  * because of variant formats, canonicalization by check
5132                                  * hooks, etc, we can't just compare the given string directly
5133                                  * to what's stored.  Set a flag to check below after we have
5134                                  * the final storable value.
5135                                  *
5136                                  * During the "checking" pass we just do nothing, to avoid
5137                                  * printing the warning twice.
5138                                  */
5139                                 if (!changeVal)
5140                                         return true;
5141
5142                                 prohibitValueChange = true;
5143                         }
5144                         else if (context != PGC_POSTMASTER)
5145                         {
5146                                 ereport(elevel,
5147                                                 (errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
5148                                                  errmsg("parameter \"%s\" cannot be changed without restarting the server",
5149                                                                 name)));
5150                                 return false;
5151                         }
5152                         break;
5153                 case PGC_SIGHUP:
5154                         if (context != PGC_SIGHUP && context != PGC_POSTMASTER)
5155                         {
5156                                 ereport(elevel,
5157                                                 (errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
5158                                                  errmsg("parameter \"%s\" cannot be changed now",
5159                                                                 name)));
5160                                 return false;
5161                         }
5162
5163                         /*
5164                          * Hmm, the idea of the SIGHUP context is "ought to be global, but
5165                          * can be changed after postmaster start". But there's nothing
5166                          * that prevents a crafty administrator from sending SIGHUP
5167                          * signals to individual backends only.
5168                          */
5169                         break;
5170                 case PGC_BACKEND:
5171                         if (context == PGC_SIGHUP)
5172                         {
5173                                 /*
5174                                  * If a PGC_BACKEND parameter is changed in the config file,
5175                                  * we want to accept the new value in the postmaster (whence
5176                                  * it will propagate to subsequently-started backends), but
5177                                  * ignore it in existing backends.      This is a tad klugy, but
5178                                  * necessary because we don't re-read the config file during
5179                                  * backend start.
5180                                  */
5181                                 if (IsUnderPostmaster)
5182                                         return true;
5183                         }
5184                         else if (context != PGC_POSTMASTER && context != PGC_BACKEND &&
5185                                          source != PGC_S_CLIENT)
5186                         {
5187                                 ereport(elevel,
5188                                                 (errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
5189                                                  errmsg("parameter \"%s\" cannot be set after connection start",
5190                                                                 name)));
5191                                 return false;
5192                         }
5193                         break;
5194                 case PGC_SUSET:
5195                         if (context == PGC_USERSET || context == PGC_BACKEND)
5196                         {
5197                                 ereport(elevel,
5198                                                 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
5199                                                  errmsg("permission denied to set parameter \"%s\"",
5200                                                                 name)));
5201                                 return false;
5202                         }
5203                         break;
5204                 case PGC_USERSET:
5205                         /* always okay */
5206                         break;
5207         }
5208
5209         /*
5210          * Disallow changing GUC_NOT_WHILE_SEC_REST values if we are inside a
5211          * security restriction context.  We can reject this regardless of the GUC
5212          * context or source, mainly because sources that it might be reasonable
5213          * to override for won't be seen while inside a function.
5214          *
5215          * Note: variables marked GUC_NOT_WHILE_SEC_REST should usually be marked
5216          * GUC_NO_RESET_ALL as well, because ResetAllOptions() doesn't check this.
5217          * An exception might be made if the reset value is assumed to be "safe".
5218          *
5219          * Note: this flag is currently used for "session_authorization" and
5220          * "role".      We need to prohibit changing these inside a local userid
5221          * context because when we exit it, GUC won't be notified, leaving things
5222          * out of sync.  (This could be fixed by forcing a new GUC nesting level,
5223          * but that would change behavior in possibly-undesirable ways.)  Also, we
5224          * prohibit changing these in a security-restricted operation because
5225          * otherwise RESET could be used to regain the session user's privileges.
5226          */
5227         if (record->flags & GUC_NOT_WHILE_SEC_REST)
5228         {
5229                 if (InLocalUserIdChange())
5230                 {
5231                         /*
5232                          * Phrasing of this error message is historical, but it's the most
5233                          * common case.
5234                          */
5235                         ereport(elevel,
5236                                         (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
5237                                          errmsg("cannot set parameter \"%s\" within security-definer function",
5238                                                         name)));
5239                         return false;
5240                 }
5241                 if (InSecurityRestrictedOperation())
5242                 {
5243                         ereport(elevel,
5244                                         (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
5245                                          errmsg("cannot set parameter \"%s\" within security-restricted operation",
5246                                                         name)));
5247                         return false;
5248                 }
5249         }
5250
5251         /*
5252          * Should we set reset/stacked values?  (If so, the behavior is not
5253          * transactional.)      This is done either when we get a default value from
5254          * the database's/user's/client's default settings or when we reset a
5255          * value to its default.
5256          */
5257         makeDefault = changeVal && (source <= PGC_S_OVERRIDE) &&
5258                 ((value != NULL) || source == PGC_S_DEFAULT);
5259
5260         /*
5261          * Ignore attempted set if overridden by previously processed setting.
5262          * However, if changeVal is false then plow ahead anyway since we are
5263          * trying to find out if the value is potentially good, not actually use
5264          * it. Also keep going if makeDefault is true, since we may want to set
5265          * the reset/stacked values even if we can't set the variable itself.
5266          */
5267         if (record->source > source)
5268         {
5269                 if (changeVal && !makeDefault)
5270                 {
5271                         elog(DEBUG3, "\"%s\": setting ignored because previous source is higher priority",
5272                                  name);
5273                         return true;
5274                 }
5275                 changeVal = false;
5276         }
5277
5278         /*
5279          * Evaluate value and set variable.
5280          */
5281         switch (record->vartype)
5282         {
5283                 case PGC_BOOL:
5284                         {
5285                                 struct config_bool *conf = (struct config_bool *) record;
5286                                 bool            newval;
5287                                 void       *newextra = NULL;
5288
5289                                 if (value)
5290                                 {
5291                                         if (!parse_bool(value, &newval))
5292                                         {
5293                                                 ereport(elevel,
5294                                                                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5295                                                   errmsg("parameter \"%s\" requires a Boolean value",
5296                                                                  name)));
5297                                                 return false;
5298                                         }
5299                                         if (!call_bool_check_hook(conf, &newval, &newextra,
5300                                                                                           source, elevel))
5301                                                 return false;
5302                                 }
5303                                 else if (source == PGC_S_DEFAULT)
5304                                 {
5305                                         newval = conf->boot_val;
5306                                         if (!call_bool_check_hook(conf, &newval, &newextra,
5307                                                                                           source, elevel))
5308                                                 return false;
5309                                 }
5310                                 else
5311                                 {
5312                                         newval = conf->reset_val;
5313                                         newextra = conf->reset_extra;
5314                                         source = conf->gen.reset_source;
5315                                 }
5316
5317                                 if (prohibitValueChange)
5318                                 {
5319                                         if (*conf->variable != newval)
5320                                                 ereport(elevel,
5321                                                                 (errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
5322                                                                  errmsg("parameter \"%s\" cannot be changed without restarting the server",
5323                                                                                 name)));
5324                                         return false;
5325                                 }
5326
5327                                 if (changeVal)
5328                                 {
5329                                         /* Save old value to support transaction abort */
5330                                         if (!makeDefault)
5331                                                 push_old_value(&conf->gen, action);
5332
5333                                         if (conf->assign_hook)
5334                                                 (*conf->assign_hook) (newval, newextra);
5335                                         *conf->variable = newval;
5336                                         set_extra_field(&conf->gen, &conf->gen.extra,
5337                                                                         newextra);
5338                                         conf->gen.source = source;
5339                                 }
5340                                 if (makeDefault)
5341                                 {
5342                                         GucStack   *stack;
5343
5344                                         if (conf->gen.reset_source <= source)
5345                                         {
5346                                                 conf->reset_val = newval;
5347                                                 set_extra_field(&conf->gen, &conf->reset_extra,
5348                                                                                 newextra);
5349                                                 conf->gen.reset_source = source;
5350                                         }
5351                                         for (stack = conf->gen.stack; stack; stack = stack->prev)
5352                                         {
5353                                                 if (stack->source <= source)
5354                                                 {
5355                                                         stack->prior.val.boolval = newval;
5356                                                         set_extra_field(&conf->gen, &stack->prior.extra,
5357                                                                                         newextra);
5358                                                         stack->source = source;
5359                                                 }
5360                                         }
5361                                 }
5362
5363                                 /* Perhaps we didn't install newextra anywhere */
5364                                 if (newextra && !extra_field_used(&conf->gen, newextra))
5365                                         free(newextra);
5366                                 break;
5367                         }
5368
5369                 case PGC_INT:
5370                         {
5371                                 struct config_int *conf = (struct config_int *) record;
5372                                 int                     newval;
5373                                 void       *newextra = NULL;
5374
5375                                 if (value)
5376                                 {
5377                                         const char *hintmsg;
5378
5379                                         if (!parse_int(value, &newval, conf->gen.flags, &hintmsg))
5380                                         {
5381                                                 ereport(elevel,
5382                                                                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5383                                                  errmsg("invalid value for parameter \"%s\": \"%s\"",
5384                                                                 name, value),
5385                                                                  hintmsg ? errhint("%s", _(hintmsg)) : 0));
5386                                                 return false;
5387                                         }
5388                                         if (newval < conf->min || newval > conf->max)
5389                                         {
5390                                                 ereport(elevel,
5391                                                                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5392                                                                  errmsg("%d is outside the valid range for parameter \"%s\" (%d .. %d)",
5393                                                                                 newval, name, conf->min, conf->max)));
5394                                                 return false;
5395                                         }
5396                                         if (!call_int_check_hook(conf, &newval, &newextra,
5397                                                                                          source, elevel))
5398                                                 return false;
5399                                 }
5400                                 else if (source == PGC_S_DEFAULT)
5401                                 {
5402                                         newval = conf->boot_val;
5403                                         if (!call_int_check_hook(conf, &newval, &newextra,
5404                                                                                          source, elevel))
5405                                                 return false;
5406                                 }
5407                                 else
5408                                 {
5409                                         newval = conf->reset_val;
5410                                         newextra = conf->reset_extra;
5411                                         source = conf->gen.reset_source;
5412                                 }
5413
5414                                 if (prohibitValueChange)
5415                                 {
5416                                         if (*conf->variable != newval)
5417                                                 ereport(elevel,
5418                                                                 (errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
5419                                                                  errmsg("parameter \"%s\" cannot be changed without restarting the server",
5420                                                                                 name)));
5421                                         return false;
5422                                 }
5423
5424                                 if (changeVal)
5425                                 {
5426                                         /* Save old value to support transaction abort */
5427                                         if (!makeDefault)
5428                                                 push_old_value(&conf->gen, action);
5429
5430                                         if (conf->assign_hook)
5431                                                 (*conf->assign_hook) (newval, newextra);
5432                                         *conf->variable = newval;
5433                                         set_extra_field(&conf->gen, &conf->gen.extra,
5434                                                                         newextra);
5435                                         conf->gen.source = source;
5436                                 }
5437                                 if (makeDefault)
5438                                 {
5439                                         GucStack   *stack;
5440
5441                                         if (conf->gen.reset_source <= source)
5442                                         {
5443                                                 conf->reset_val = newval;
5444                                                 set_extra_field(&conf->gen, &conf->reset_extra,
5445                                                                                 newextra);
5446                                                 conf->gen.reset_source = source;
5447                                         }
5448                                         for (stack = conf->gen.stack; stack; stack = stack->prev)
5449                                         {
5450                                                 if (stack->source <= source)
5451                                                 {
5452                                                         stack->prior.val.intval = newval;
5453                                                         set_extra_field(&conf->gen, &stack->prior.extra,
5454                                                                                         newextra);
5455                                                         stack->source = source;
5456                                                 }
5457                                         }
5458                                 }
5459
5460                                 /* Perhaps we didn't install newextra anywhere */
5461                                 if (newextra && !extra_field_used(&conf->gen, newextra))
5462                                         free(newextra);
5463                                 break;
5464                         }
5465
5466                 case PGC_REAL:
5467                         {
5468                                 struct config_real *conf = (struct config_real *) record;
5469                                 double          newval;
5470                                 void       *newextra = NULL;
5471
5472                                 if (value)
5473                                 {
5474                                         if (!parse_real(value, &newval))
5475                                         {
5476                                                 ereport(elevel,
5477                                                                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5478                                                   errmsg("parameter \"%s\" requires a numeric value",
5479                                                                  name)));
5480                                                 return false;
5481                                         }
5482                                         if (newval < conf->min || newval > conf->max)
5483                                         {
5484                                                 ereport(elevel,
5485                                                                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5486                                                                  errmsg("%g is outside the valid range for parameter \"%s\" (%g .. %g)",
5487                                                                                 newval, name, conf->min, conf->max)));
5488                                                 return false;
5489                                         }
5490                                         if (!call_real_check_hook(conf, &newval, &newextra,
5491                                                                                           source, elevel))
5492                                                 return false;
5493                                 }
5494                                 else if (source == PGC_S_DEFAULT)
5495                                 {
5496                                         newval = conf->boot_val;
5497                                         if (!call_real_check_hook(conf, &newval, &newextra,
5498                                                                                           source, elevel))
5499                                                 return false;
5500                                 }
5501                                 else
5502                                 {
5503                                         newval = conf->reset_val;
5504                                         newextra = conf->reset_extra;
5505                                         source = conf->gen.reset_source;
5506                                 }
5507
5508                                 if (prohibitValueChange)
5509                                 {
5510                                         if (*conf->variable != newval)
5511                                                 ereport(elevel,
5512                                                                 (errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
5513                                                                  errmsg("parameter \"%s\" cannot be changed without restarting the server",
5514                                                                                 name)));
5515                                         return false;
5516                                 }
5517
5518                                 if (changeVal)
5519                                 {
5520                                         /* Save old value to support transaction abort */
5521                                         if (!makeDefault)
5522                                                 push_old_value(&conf->gen, action);
5523
5524                                         if (conf->assign_hook)
5525                                                 (*conf->assign_hook) (newval, newextra);
5526                                         *conf->variable = newval;
5527                                         set_extra_field(&conf->gen, &conf->gen.extra,
5528                                                                         newextra);
5529                                         conf->gen.source = source;
5530                                 }
5531                                 if (makeDefault)
5532                                 {
5533                                         GucStack   *stack;
5534
5535                                         if (conf->gen.reset_source <= source)
5536                                         {
5537                                                 conf->reset_val = newval;
5538                                                 set_extra_field(&conf->gen, &conf->reset_extra,
5539                                                                                 newextra);
5540                                                 conf->gen.reset_source = source;
5541                                         }
5542                                         for (stack = conf->gen.stack; stack; stack = stack->prev)
5543                                         {
5544                                                 if (stack->source <= source)
5545                                                 {
5546                                                         stack->prior.val.realval = newval;
5547                                                         set_extra_field(&conf->gen, &stack->prior.extra,
5548                                                                                         newextra);
5549                                                         stack->source = source;
5550                                                 }
5551                                         }
5552                                 }
5553
5554                                 /* Perhaps we didn't install newextra anywhere */
5555                                 if (newextra && !extra_field_used(&conf->gen, newextra))
5556                                         free(newextra);
5557                                 break;
5558                         }
5559
5560                 case PGC_STRING:
5561                         {
5562                                 struct config_string *conf = (struct config_string *) record;
5563                                 char       *newval;
5564                                 void       *newextra = NULL;
5565
5566                                 if (value)
5567                                 {
5568                                         /*
5569                                          * The value passed by the caller could be transient, so
5570                                          * we always strdup it.
5571                                          */
5572                                         newval = guc_strdup(elevel, value);
5573                                         if (newval == NULL)
5574                                                 return false;
5575
5576                                         /*
5577                                          * The only built-in "parsing" check we have is to apply
5578                                          * truncation if GUC_IS_NAME.
5579                                          */
5580                                         if (conf->gen.flags & GUC_IS_NAME)
5581                                                 truncate_identifier(newval, strlen(newval), true);
5582
5583                                         if (!call_string_check_hook(conf, &newval, &newextra,
5584                                                                                                 source, elevel))
5585                                         {
5586                                                 free(newval);
5587                                                 return false;
5588                                         }
5589                                 }
5590                                 else if (source == PGC_S_DEFAULT)
5591                                 {
5592                                         /* non-NULL boot_val must always get strdup'd */
5593                                         if (conf->boot_val != NULL)
5594                                         {
5595                                                 newval = guc_strdup(elevel, conf->boot_val);
5596                                                 if (newval == NULL)
5597                                                         return false;
5598                                         }
5599                                         else
5600                                                 newval = NULL;
5601
5602                                         if (!call_string_check_hook(conf, &newval, &newextra,
5603                                                                                                 source, elevel))
5604                                         {
5605                                                 free(newval);
5606                                                 return false;
5607                                         }
5608                                 }
5609                                 else
5610                                 {
5611                                         /*
5612                                          * strdup not needed, since reset_val is already under
5613                                          * guc.c's control
5614                                          */
5615                                         newval = conf->reset_val;
5616                                         newextra = conf->reset_extra;
5617                                         source = conf->gen.reset_source;
5618                                 }
5619
5620                                 if (prohibitValueChange)
5621                                 {
5622                                         /* newval shouldn't be NULL, so we're a bit sloppy here */
5623                                         if (*conf->variable == NULL || newval == NULL ||
5624                                                 strcmp(*conf->variable, newval) != 0)
5625                                                 ereport(elevel,
5626                                                                 (errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
5627                                                                  errmsg("parameter \"%s\" cannot be changed without restarting the server",
5628                                                                                 name)));
5629                                         return false;
5630                                 }
5631
5632                                 if (changeVal)
5633                                 {
5634                                         /* Save old value to support transaction abort */
5635                                         if (!makeDefault)
5636                                                 push_old_value(&conf->gen, action);
5637
5638                                         if (conf->assign_hook)
5639                                                 (*conf->assign_hook) (newval, newextra);
5640                                         set_string_field(conf, conf->variable, newval);
5641                                         set_extra_field(&conf->gen, &conf->gen.extra,
5642                                                                         newextra);
5643                                         conf->gen.source = source;
5644                                 }
5645
5646                                 if (makeDefault)
5647                                 {
5648                                         GucStack   *stack;
5649
5650                                         if (conf->gen.reset_source <= source)
5651                                         {
5652                                                 set_string_field(conf, &conf->reset_val, newval);
5653                                                 set_extra_field(&conf->gen, &conf->reset_extra,
5654                                                                                 newextra);
5655                                                 conf->gen.reset_source = source;
5656                                         }
5657                                         for (stack = conf->gen.stack; stack; stack = stack->prev)
5658                                         {
5659                                                 if (stack->source <= source)
5660                                                 {
5661                                                         set_string_field(conf, &stack->prior.val.stringval,
5662                                                                                          newval);
5663                                                         set_extra_field(&conf->gen, &stack->prior.extra,
5664                                                                                         newextra);
5665                                                         stack->source = source;
5666                                                 }
5667                                         }
5668                                 }
5669
5670                                 /* Perhaps we didn't install newval anywhere */
5671                                 if (newval && !string_field_used(conf, newval))
5672                                         free(newval);
5673                                 /* Perhaps we didn't install newextra anywhere */
5674                                 if (newextra && !extra_field_used(&conf->gen, newextra))
5675                                         free(newextra);
5676                                 break;
5677                         }
5678
5679                 case PGC_ENUM:
5680                         {
5681                                 struct config_enum *conf = (struct config_enum *) record;
5682                                 int                     newval;
5683                                 void       *newextra = NULL;
5684
5685                                 if (value)
5686                                 {
5687                                         if (!config_enum_lookup_by_name(conf, value, &newval))
5688                                         {
5689                                                 char       *hintmsg;
5690
5691                                                 hintmsg = config_enum_get_options(conf,
5692                                                                                                                 "Available values: ",
5693                                                                                                                   ".", ", ");
5694
5695                                                 ereport(elevel,
5696                                                                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5697                                                  errmsg("invalid value for parameter \"%s\": \"%s\"",
5698                                                                 name, value),
5699                                                                  hintmsg ? errhint("%s", _(hintmsg)) : 0));
5700
5701                                                 if (hintmsg)
5702                                                         pfree(hintmsg);
5703                                                 return false;
5704                                         }
5705                                         if (!call_enum_check_hook(conf, &newval, &newextra,
5706                                                                                           source, elevel))
5707                                                 return false;
5708                                 }
5709                                 else if (source == PGC_S_DEFAULT)
5710                                 {
5711                                         newval = conf->boot_val;
5712                                         if (!call_enum_check_hook(conf, &newval, &newextra,
5713                                                                                           source, elevel))
5714                                                 return false;
5715                                 }
5716                                 else
5717                                 {
5718                                         newval = conf->reset_val;
5719                                         newextra = conf->reset_extra;
5720                                         source = conf->gen.reset_source;
5721                                 }
5722
5723                                 if (prohibitValueChange)
5724                                 {
5725                                         if (*conf->variable != newval)
5726                                                 ereport(elevel,
5727                                                                 (errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
5728                                                                  errmsg("parameter \"%s\" cannot be changed without restarting the server",
5729                                                                                 name)));
5730                                         return false;
5731                                 }
5732
5733                                 if (changeVal)
5734                                 {
5735                                         /* Save old value to support transaction abort */
5736                                         if (!makeDefault)
5737                                                 push_old_value(&conf->gen, action);
5738
5739                                         if (conf->assign_hook)
5740                                                 (*conf->assign_hook) (newval, newextra);
5741                                         *conf->variable = newval;
5742                                         set_extra_field(&conf->gen, &conf->gen.extra,
5743                                                                         newextra);
5744                                         conf->gen.source = source;
5745                                 }
5746                                 if (makeDefault)
5747                                 {
5748                                         GucStack   *stack;
5749
5750                                         if (conf->gen.reset_source <= source)
5751                                         {
5752                                                 conf->reset_val = newval;
5753                                                 set_extra_field(&conf->gen, &conf->reset_extra,
5754                                                                                 newextra);
5755                                                 conf->gen.reset_source = source;
5756                                         }
5757                                         for (stack = conf->gen.stack; stack; stack = stack->prev)
5758                                         {
5759                                                 if (stack->source <= source)
5760                                                 {
5761                                                         stack->prior.val.enumval = newval;
5762                                                         set_extra_field(&conf->gen, &stack->prior.extra,
5763                                                                                         newextra);
5764                                                         stack->source = source;
5765                                                 }
5766                                         }
5767                                 }
5768
5769                                 /* Perhaps we didn't install newextra anywhere */
5770                                 if (newextra && !extra_field_used(&conf->gen, newextra))
5771                                         free(newextra);
5772                                 break;
5773                         }
5774         }
5775
5776         if (changeVal && (record->flags & GUC_REPORT))
5777                 ReportGUCOption(record);
5778
5779         return true;
5780 }
5781
5782
5783 /*
5784  * Set the fields for source file and line number the setting came from.
5785  */
5786 static void
5787 set_config_sourcefile(const char *name, char *sourcefile, int sourceline)
5788 {
5789         struct config_generic *record;
5790         int                     elevel;
5791
5792         /*
5793          * To avoid cluttering the log, only the postmaster bleats loudly about
5794          * problems with the config file.
5795          */
5796         elevel = IsUnderPostmaster ? DEBUG3 : LOG;
5797
5798         record = find_option(name, true, elevel);
5799         /* should not happen */
5800         if (record == NULL)
5801                 elog(ERROR, "unrecognized configuration parameter \"%s\"", name);
5802
5803         sourcefile = guc_strdup(elevel, sourcefile);
5804         if (record->sourcefile)
5805                 free(record->sourcefile);
5806         record->sourcefile = sourcefile;
5807         record->sourceline = sourceline;
5808 }
5809
5810 /*
5811  * Set a config option to the given value. See also set_config_option,
5812  * this is just the wrapper to be called from outside GUC.      NB: this
5813  * is used only for non-transactional operations.
5814  *
5815  * Note: there is no support here for setting source file/line, as it
5816  * is currently not needed.
5817  */
5818 void
5819 SetConfigOption(const char *name, const char *value,
5820                                 GucContext context, GucSource source)
5821 {
5822         (void) set_config_option(name, value, context, source,
5823                                                          GUC_ACTION_SET, true);
5824 }
5825
5826
5827
5828 /*
5829  * Fetch the current value of the option `name'. If the option doesn't exist,
5830  * throw an ereport and don't return.
5831  *
5832  * If restrict_superuser is true, we also enforce that only superusers can
5833  * see GUC_SUPERUSER_ONLY variables.  This should only be passed as true
5834  * in user-driven calls.
5835  *
5836  * The string is *not* allocated for modification and is really only
5837  * valid until the next call to configuration related functions.
5838  */
5839 const char *
5840 GetConfigOption(const char *name, bool restrict_superuser)
5841 {
5842         struct config_generic *record;
5843         static char buffer[256];
5844
5845         record = find_option(name, false, ERROR);
5846         if (record == NULL)
5847                 ereport(ERROR,
5848                                 (errcode(ERRCODE_UNDEFINED_OBJECT),
5849                            errmsg("unrecognized configuration parameter \"%s\"", name)));
5850         if (restrict_superuser &&
5851                 (record->flags & GUC_SUPERUSER_ONLY) &&
5852                 !superuser())
5853                 ereport(ERROR,
5854                                 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
5855                                  errmsg("must be superuser to examine \"%s\"", name)));
5856
5857         switch (record->vartype)
5858         {
5859                 case PGC_BOOL:
5860                         return *((struct config_bool *) record)->variable ? "on" : "off";
5861
5862                 case PGC_INT:
5863                         snprintf(buffer, sizeof(buffer), "%d",
5864                                          *((struct config_int *) record)->variable);
5865                         return buffer;
5866
5867                 case PGC_REAL:
5868                         snprintf(buffer, sizeof(buffer), "%g",
5869                                          *((struct config_real *) record)->variable);
5870                         return buffer;
5871
5872                 case PGC_STRING:
5873                         return *((struct config_string *) record)->variable;
5874
5875                 case PGC_ENUM:
5876                         return config_enum_lookup_by_value((struct config_enum *) record,
5877                                                                  *((struct config_enum *) record)->variable);
5878         }
5879         return NULL;
5880 }
5881
5882 /*
5883  * Get the RESET value associated with the given option.
5884  *
5885  * Note: this is not re-entrant, due to use of static result buffer;
5886  * not to mention that a string variable could have its reset_val changed.
5887  * Beware of assuming the result value is good for very long.
5888  */
5889 const char *
5890 GetConfigOptionResetString(const char *name)
5891 {
5892         struct config_generic *record;
5893         static char buffer[256];
5894
5895         record = find_option(name, false, ERROR);
5896         if (record == NULL)
5897                 ereport(ERROR,
5898                                 (errcode(ERRCODE_UNDEFINED_OBJECT),
5899                            errmsg("unrecognized configuration parameter \"%s\"", name)));
5900         if ((record->flags & GUC_SUPERUSER_ONLY) && !superuser())
5901                 ereport(ERROR,
5902                                 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
5903                                  errmsg("must be superuser to examine \"%s\"", name)));
5904
5905         switch (record->vartype)
5906         {
5907                 case PGC_BOOL:
5908                         return ((struct config_bool *) record)->reset_val ? "on" : "off";
5909
5910                 case PGC_INT:
5911                         snprintf(buffer, sizeof(buffer), "%d",
5912                                          ((struct config_int *) record)->reset_val);
5913                         return buffer;
5914
5915                 case PGC_REAL:
5916                         snprintf(buffer, sizeof(buffer), "%g",
5917                                          ((struct config_real *) record)->reset_val);
5918                         return buffer;
5919
5920                 case PGC_STRING:
5921                         return ((struct config_string *) record)->reset_val;
5922
5923                 case PGC_ENUM:
5924                         return config_enum_lookup_by_value((struct config_enum *) record,
5925                                                                  ((struct config_enum *) record)->reset_val);
5926         }
5927         return NULL;
5928 }
5929
5930
5931 /*
5932  * flatten_set_variable_args
5933  *              Given a parsenode List as emitted by the grammar for SET,
5934  *              convert to the flat string representation used by GUC.
5935  *
5936  * We need to be told the name of the variable the args are for, because
5937  * the flattening rules vary (ugh).
5938  *
5939  * The result is NULL if args is NIL (ie, SET ... TO DEFAULT), otherwise
5940  * a palloc'd string.
5941  */
5942 static char *
5943 flatten_set_variable_args(const char *name, List *args)
5944 {
5945         struct config_generic *record;
5946         int                     flags;
5947         StringInfoData buf;
5948         ListCell   *l;
5949
5950         /* Fast path if just DEFAULT */
5951         if (args == NIL)
5952                 return NULL;
5953
5954         /*
5955          * Get flags for the variable; if it's not known, use default flags.
5956          * (Caller might throw error later, but not our business to do so here.)
5957          */
5958         record = find_option(name, false, WARNING);
5959         if (record)
5960                 flags = record->flags;
5961         else
5962                 flags = 0;
5963
5964         /* Complain if list input and non-list variable */
5965         if ((flags & GUC_LIST_INPUT) == 0 &&
5966                 list_length(args) != 1)
5967                 ereport(ERROR,
5968                                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5969                                  errmsg("SET %s takes only one argument", name)));
5970
5971         initStringInfo(&buf);
5972
5973         /*
5974          * Each list member may be a plain A_Const node, or an A_Const within a
5975          * TypeCast; the latter case is supported only for ConstInterval arguments
5976          * (for SET TIME ZONE).
5977          */
5978         foreach(l, args)
5979         {
5980                 Node       *arg = (Node *) lfirst(l);
5981                 char       *val;
5982                 TypeName   *typeName = NULL;
5983                 A_Const    *con;
5984
5985                 if (l != list_head(args))
5986                         appendStringInfo(&buf, ", ");
5987
5988                 if (IsA(arg, TypeCast))
5989                 {
5990                         TypeCast   *tc = (TypeCast *) arg;
5991
5992                         arg = tc->arg;
5993                         typeName = tc->typeName;
5994                 }
5995
5996                 if (!IsA(arg, A_Const))
5997                         elog(ERROR, "unrecognized node type: %d", (int) nodeTag(arg));
5998                 con = (A_Const *) arg;
5999
6000                 switch (nodeTag(&con->val))
6001                 {
6002                         case T_Integer:
6003                                 appendStringInfo(&buf, "%ld", intVal(&con->val));
6004                                 break;
6005                         case T_Float:
6006                                 /* represented as a string, so just copy it */
6007                                 appendStringInfoString(&buf, strVal(&con->val));
6008                                 break;
6009                         case T_String:
6010                                 val = strVal(&con->val);
6011                                 if (typeName != NULL)
6012                                 {
6013                                         /*
6014                                          * Must be a ConstInterval argument for TIME ZONE. Coerce
6015                                          * to interval and back to normalize the value and account
6016                                          * for any typmod.
6017                                          */
6018                                         Oid                     typoid;
6019                                         int32           typmod;
6020                                         Datum           interval;
6021                                         char       *intervalout;
6022
6023                                         typenameTypeIdAndMod(NULL, typeName, &typoid, &typmod);
6024                                         Assert(typoid == INTERVALOID);
6025
6026                                         interval =
6027                                                 DirectFunctionCall3(interval_in,
6028                                                                                         CStringGetDatum(val),
6029                                                                                         ObjectIdGetDatum(InvalidOid),
6030                                                                                         Int32GetDatum(typmod));
6031
6032                                         intervalout =
6033                                                 DatumGetCString(DirectFunctionCall1(interval_out,
6034                                                                                                                         interval));
6035                                         appendStringInfo(&buf, "INTERVAL '%s'", intervalout);
6036                                 }
6037                                 else
6038                                 {
6039                                         /*
6040                                          * Plain string literal or identifier.  For quote mode,
6041                                          * quote it if it's not a vanilla identifier.
6042                                          */
6043                                         if (flags & GUC_LIST_QUOTE)
6044                                                 appendStringInfoString(&buf, quote_identifier(val));
6045                                         else
6046                                                 appendStringInfoString(&buf, val);
6047                                 }
6048                                 break;
6049                         default:
6050                                 elog(ERROR, "unrecognized node type: %d",
6051                                          (int) nodeTag(&con->val));
6052                                 break;
6053                 }
6054         }
6055
6056         return buf.data;
6057 }
6058
6059
6060 /*
6061  * SET command
6062  */
6063 void
6064 ExecSetVariableStmt(VariableSetStmt *stmt)
6065 {
6066         GucAction       action = stmt->is_local ? GUC_ACTION_LOCAL : GUC_ACTION_SET;
6067
6068         switch (stmt->kind)
6069         {
6070                 case VAR_SET_VALUE:
6071                 case VAR_SET_CURRENT:
6072                         set_config_option(stmt->name,
6073                                                           ExtractSetVariableArgs(stmt),
6074                                                           (superuser() ? PGC_SUSET : PGC_USERSET),
6075                                                           PGC_S_SESSION,
6076                                                           action,
6077                                                           true);
6078                         break;
6079                 case VAR_SET_MULTI:
6080
6081                         /*
6082                          * Special case for special SQL syntax that effectively sets more
6083                          * than one variable per statement.
6084                          */
6085                         if (strcmp(stmt->name, "TRANSACTION") == 0)
6086                         {
6087                                 ListCell   *head;
6088
6089                                 foreach(head, stmt->args)
6090                                 {
6091                                         DefElem    *item = (DefElem *) lfirst(head);
6092
6093                                         if (strcmp(item->defname, "transaction_isolation") == 0)
6094                                                 SetPGVariable("transaction_isolation",
6095                                                                           list_make1(item->arg), stmt->is_local);
6096                                         else if (strcmp(item->defname, "transaction_read_only") == 0)
6097                                                 SetPGVariable("transaction_read_only",
6098                                                                           list_make1(item->arg), stmt->is_local);
6099                                         else if (strcmp(item->defname, "transaction_deferrable") == 0)
6100                                                 SetPGVariable("transaction_deferrable",
6101                                                                           list_make1(item->arg), stmt->is_local);
6102                                         else
6103                                                 elog(ERROR, "unexpected SET TRANSACTION element: %s",
6104                                                          item->defname);
6105                                 }
6106                         }
6107                         else if (strcmp(stmt->name, "SESSION CHARACTERISTICS") == 0)
6108                         {
6109                                 ListCell   *head;
6110
6111                                 foreach(head, stmt->args)
6112                                 {
6113                                         DefElem    *item = (DefElem *) lfirst(head);
6114
6115                                         if (strcmp(item->defname, "transaction_isolation") == 0)
6116                                                 SetPGVariable("default_transaction_isolation",
6117                                                                           list_make1(item->arg), stmt->is_local);
6118                                         else if (strcmp(item->defname, "transaction_read_only") == 0)
6119                                                 SetPGVariable("default_transaction_read_only",
6120                                                                           list_make1(item->arg), stmt->is_local);
6121                                         else if (strcmp(item->defname, "transaction_deferrable") == 0)
6122                                                 SetPGVariable("default_transaction_deferrable",
6123                                                                           list_make1(item->arg), stmt->is_local);
6124                                         else
6125                                                 elog(ERROR, "unexpected SET SESSION element: %s",
6126                                                          item->defname);
6127                                 }
6128                         }
6129                         else
6130                                 elog(ERROR, "unexpected SET MULTI element: %s",
6131                                          stmt->name);
6132                         break;
6133                 case VAR_SET_DEFAULT:
6134                 case VAR_RESET:
6135                         set_config_option(stmt->name,
6136                                                           NULL,
6137                                                           (superuser() ? PGC_SUSET : PGC_USERSET),
6138                                                           PGC_S_SESSION,
6139                                                           action,
6140                                                           true);
6141                         break;
6142                 case VAR_RESET_ALL:
6143                         ResetAllOptions();
6144                         break;
6145         }
6146 }
6147
6148 /*
6149  * Get the value to assign for a VariableSetStmt, or NULL if it's RESET.
6150  * The result is palloc'd.
6151  *
6152  * This is exported for use by actions such as ALTER ROLE SET.
6153  */
6154 char *
6155 ExtractSetVariableArgs(VariableSetStmt *stmt)
6156 {
6157         switch (stmt->kind)
6158         {
6159                 case VAR_SET_VALUE:
6160                         return flatten_set_variable_args(stmt->name, stmt->args);
6161                 case VAR_SET_CURRENT:
6162                         return GetConfigOptionByName(stmt->name, NULL);
6163                 default:
6164                         return NULL;
6165         }
6166 }
6167
6168 /*
6169  * SetPGVariable - SET command exported as an easily-C-callable function.
6170  *
6171  * This provides access to SET TO value, as well as SET TO DEFAULT (expressed
6172  * by passing args == NIL), but not SET FROM CURRENT functionality.
6173  */
6174 void
6175 SetPGVariable(const char *name, List *args, bool is_local)
6176 {
6177         char       *argstring = flatten_set_variable_args(name, args);
6178
6179         /* Note SET DEFAULT (argstring == NULL) is equivalent to RESET */
6180         set_config_option(name,
6181                                           argstring,
6182                                           (superuser() ? PGC_SUSET : PGC_USERSET),
6183                                           PGC_S_SESSION,
6184                                           is_local ? GUC_ACTION_LOCAL : GUC_ACTION_SET,
6185                                           true);
6186 }
6187
6188 /*
6189  * SET command wrapped as a SQL callable function.
6190  */
6191 Datum
6192 set_config_by_name(PG_FUNCTION_ARGS)
6193 {
6194         char       *name;
6195         char       *value;
6196         char       *new_value;
6197         bool            is_local;
6198
6199         if (PG_ARGISNULL(0))
6200                 ereport(ERROR,
6201                                 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
6202                                  errmsg("SET requires parameter name")));
6203
6204         /* Get the GUC variable name */
6205         name = TextDatumGetCString(PG_GETARG_DATUM(0));
6206
6207         /* Get the desired value or set to NULL for a reset request */
6208         if (PG_ARGISNULL(1))
6209                 value = NULL;
6210         else
6211                 value = TextDatumGetCString(PG_GETARG_DATUM(1));
6212
6213         /*
6214          * Get the desired state of is_local. Default to false if provided value
6215          * is NULL
6216          */
6217         if (PG_ARGISNULL(2))
6218                 is_local = false;
6219         else
6220                 is_local = PG_GETARG_BOOL(2);
6221
6222         /* Note SET DEFAULT (argstring == NULL) is equivalent to RESET */
6223         set_config_option(name,
6224                                           value,
6225                                           (superuser() ? PGC_SUSET : PGC_USERSET),
6226                                           PGC_S_SESSION,
6227                                           is_local ? GUC_ACTION_LOCAL : GUC_ACTION_SET,
6228                                           true);
6229
6230         /* get the new current value */
6231         new_value = GetConfigOptionByName(name, NULL);
6232
6233         /* Convert return string to text */
6234         PG_RETURN_TEXT_P(cstring_to_text(new_value));
6235 }
6236
6237
6238 /*
6239  * Common code for DefineCustomXXXVariable subroutines: allocate the
6240  * new variable's config struct and fill in generic fields.
6241  */
6242 static struct config_generic *
6243 init_custom_variable(const char *name,
6244                                          const char *short_desc,
6245                                          const char *long_desc,
6246                                          GucContext context,
6247                                          int flags,
6248                                          enum config_type type,
6249                                          size_t sz)
6250 {
6251         struct config_generic *gen;
6252
6253         /*
6254          * Only allow custom PGC_POSTMASTER variables to be created during shared
6255          * library preload; any later than that, we can't ensure that the value
6256          * doesn't change after startup.  This is a fatal elog if it happens; just
6257          * erroring out isn't safe because we don't know what the calling loadable
6258          * module might already have hooked into.
6259          */
6260         if (context == PGC_POSTMASTER &&
6261                 !process_shared_preload_libraries_in_progress)
6262                 elog(FATAL, "cannot create PGC_POSTMASTER variables after startup");
6263
6264         gen = (struct config_generic *) guc_malloc(ERROR, sz);
6265         memset(gen, 0, sz);
6266
6267         gen->name = guc_strdup(ERROR, name);
6268         gen->context = context;
6269         gen->group = CUSTOM_OPTIONS;
6270         gen->short_desc = short_desc;
6271         gen->long_desc = long_desc;
6272         gen->flags = flags;
6273         gen->vartype = type;
6274
6275         return gen;
6276 }
6277
6278 /*
6279  * Common code for DefineCustomXXXVariable subroutines: insert the new
6280  * variable into the GUC variable array, replacing any placeholder.
6281  */
6282 static void
6283 define_custom_variable(struct config_generic * variable)
6284 {
6285         const char *name = variable->name;
6286         const char **nameAddr = &name;
6287         const char *value;
6288         struct config_string *pHolder;
6289         GucContext      phcontext;
6290         struct config_generic **res;
6291
6292         /*
6293          * See if there's a placeholder by the same name.
6294          */
6295         res = (struct config_generic **) bsearch((void *) &nameAddr,
6296                                                                                          (void *) guc_variables,
6297                                                                                          num_guc_variables,
6298                                                                                          sizeof(struct config_generic *),
6299                                                                                          guc_var_compare);
6300         if (res == NULL)
6301         {
6302                 /*
6303                  * No placeholder to replace, so we can just add it ... but first,
6304                  * make sure it's initialized to its default value.
6305                  */
6306                 InitializeOneGUCOption(variable);
6307                 add_guc_variable(variable, ERROR);
6308                 return;
6309         }
6310
6311         /*
6312          * This better be a placeholder
6313          */
6314         if (((*res)->flags & GUC_CUSTOM_PLACEHOLDER) == 0)
6315                 ereport(ERROR,
6316                                 (errcode(ERRCODE_INTERNAL_ERROR),
6317                                  errmsg("attempt to redefine parameter \"%s\"", name)));
6318
6319         Assert((*res)->vartype == PGC_STRING);
6320         pHolder = (struct config_string *) (*res);
6321
6322         /*
6323          * First, set the variable to its default value.  We must do this even
6324          * though we intend to immediately apply a new value, since it's possible
6325          * that the new value is invalid.
6326          */
6327         InitializeOneGUCOption(variable);
6328
6329         /*
6330          * Replace the placeholder. We aren't changing the name, so no re-sorting
6331          * is necessary
6332          */
6333         *res = variable;
6334
6335         /*
6336          * Infer context for assignment based on source of existing value. We
6337          * can't tell this with exact accuracy, but we can at least do something
6338          * reasonable in typical cases.
6339          */
6340         switch (pHolder->gen.source)
6341         {
6342                 case PGC_S_DEFAULT:
6343                 case PGC_S_DYNAMIC_DEFAULT:
6344                 case PGC_S_ENV_VAR:
6345                 case PGC_S_FILE:
6346                 case PGC_S_ARGV:
6347
6348                         /*
6349                          * If we got past the check in init_custom_variable, we can safely
6350                          * assume that any existing value for a PGC_POSTMASTER variable
6351                          * was set in postmaster context.
6352                          */
6353                         if (variable->context == PGC_POSTMASTER)
6354                                 phcontext = PGC_POSTMASTER;
6355                         else
6356                                 phcontext = PGC_SIGHUP;
6357                         break;
6358
6359                 case PGC_S_DATABASE:
6360                 case PGC_S_USER:
6361                 case PGC_S_DATABASE_USER:
6362
6363                         /*
6364                          * The existing value came from an ALTER ROLE/DATABASE SET
6365                          * command. We can assume that at the time the command was issued,
6366                          * we checked that the issuing user was superuser if the variable
6367                          * requires superuser privileges to set.  So it's safe to use
6368                          * SUSET context here.
6369                          */
6370                         phcontext = PGC_SUSET;
6371                         break;
6372
6373                 case PGC_S_CLIENT:
6374                 case PGC_S_SESSION:
6375                 default:
6376
6377                         /*
6378                          * We must assume that the value came from an untrusted user, even
6379                          * if the current_user is a superuser.
6380                          */
6381                         phcontext = PGC_USERSET;
6382                         break;
6383         }
6384
6385         /*
6386          * Assign the string value stored in the placeholder to the real variable.
6387          *
6388          * XXX this is not really good enough --- it should be a nontransactional
6389          * assignment, since we don't want it to roll back if the current xact
6390          * fails later.  (Or do we?)
6391          */
6392         value = *pHolder->variable;
6393
6394         if (value)
6395         {
6396                 if (set_config_option(name, value,
6397                                                           phcontext, pHolder->gen.source,
6398                                                           GUC_ACTION_SET, true))
6399                 {
6400                         /* Also copy over any saved source-location information */
6401                         if (pHolder->gen.sourcefile)
6402                                 set_config_sourcefile(name, pHolder->gen.sourcefile,
6403                                                                           pHolder->gen.sourceline);
6404                 }
6405         }
6406
6407         /*
6408          * Free up as much as we conveniently can of the placeholder structure
6409          * (this neglects any stack items...)
6410          */
6411         set_string_field(pHolder, pHolder->variable, NULL);
6412         set_string_field(pHolder, &pHolder->reset_val, NULL);
6413
6414         free(pHolder);
6415 }
6416
6417 void
6418 DefineCustomBoolVariable(const char *name,
6419                                                  const char *short_desc,
6420                                                  const char *long_desc,
6421                                                  bool *valueAddr,
6422                                                  bool bootValue,
6423                                                  GucContext context,
6424                                                  int flags,
6425                                                  GucBoolCheckHook check_hook,
6426                                                  GucBoolAssignHook assign_hook,
6427                                                  GucShowHook show_hook)
6428 {
6429         struct config_bool *var;
6430
6431         var = (struct config_bool *)
6432                 init_custom_variable(name, short_desc, long_desc, context, flags,
6433                                                          PGC_BOOL, sizeof(struct config_bool));
6434         var->variable = valueAddr;
6435         var->boot_val = bootValue;
6436         var->reset_val = bootValue;
6437         var->check_hook = check_hook;
6438         var->assign_hook = assign_hook;
6439         var->show_hook = show_hook;
6440         define_custom_variable(&var->gen);
6441 }
6442
6443 void
6444 DefineCustomIntVariable(const char *name,
6445                                                 const char *short_desc,
6446                                                 const char *long_desc,
6447                                                 int *valueAddr,
6448                                                 int bootValue,
6449                                                 int minValue,
6450                                                 int maxValue,
6451                                                 GucContext context,
6452                                                 int flags,
6453                                                 GucIntCheckHook check_hook,
6454                                                 GucIntAssignHook assign_hook,
6455                                                 GucShowHook show_hook)
6456 {
6457         struct config_int *var;
6458
6459         var = (struct config_int *)
6460                 init_custom_variable(name, short_desc, long_desc, context, flags,
6461                                                          PGC_INT, sizeof(struct config_int));
6462         var->variable = valueAddr;
6463         var->boot_val = bootValue;
6464         var->reset_val = bootValue;
6465         var->min = minValue;
6466         var->max = maxValue;
6467         var->check_hook = check_hook;
6468         var->assign_hook = assign_hook;
6469         var->show_hook = show_hook;
6470         define_custom_variable(&var->gen);
6471 }
6472
6473 void
6474 DefineCustomRealVariable(const char *name,
6475                                                  const char *short_desc,
6476                                                  const char *long_desc,
6477                                                  double *valueAddr,
6478                                                  double bootValue,
6479                                                  double minValue,
6480                                                  double maxValue,
6481                                                  GucContext context,
6482                                                  int flags,
6483                                                  GucRealCheckHook check_hook,
6484                                                  GucRealAssignHook assign_hook,
6485                                                  GucShowHook show_hook)
6486 {
6487         struct config_real *var;
6488
6489         var = (struct config_real *)
6490                 init_custom_variable(name, short_desc, long_desc, context, flags,
6491                                                          PGC_REAL, sizeof(struct config_real));
6492         var->variable = valueAddr;
6493         var->boot_val = bootValue;
6494         var->reset_val = bootValue;
6495         var->min = minValue;
6496         var->max = maxValue;
6497         var->check_hook = check_hook;
6498         var->assign_hook = assign_hook;
6499         var->show_hook = show_hook;
6500         define_custom_variable(&var->gen);
6501 }
6502
6503 void
6504 DefineCustomStringVariable(const char *name,
6505                                                    const char *short_desc,
6506                                                    const char *long_desc,
6507                                                    char **valueAddr,
6508                                                    const char *bootValue,
6509                                                    GucContext context,
6510                                                    int flags,
6511                                                    GucStringCheckHook check_hook,
6512                                                    GucStringAssignHook assign_hook,
6513                                                    GucShowHook show_hook)
6514 {
6515         struct config_string *var;
6516
6517         var = (struct config_string *)
6518                 init_custom_variable(name, short_desc, long_desc, context, flags,
6519                                                          PGC_STRING, sizeof(struct config_string));
6520         var->variable = valueAddr;
6521         var->boot_val = bootValue;
6522         var->check_hook = check_hook;
6523         var->assign_hook = assign_hook;
6524         var->show_hook = show_hook;
6525         define_custom_variable(&var->gen);
6526 }
6527
6528 void
6529 DefineCustomEnumVariable(const char *name,
6530                                                  const char *short_desc,
6531                                                  const char *long_desc,
6532                                                  int *valueAddr,
6533                                                  int bootValue,
6534                                                  const struct config_enum_entry * options,
6535                                                  GucContext context,
6536                                                  int flags,
6537                                                  GucEnumCheckHook check_hook,
6538                                                  GucEnumAssignHook assign_hook,
6539                                                  GucShowHook show_hook)
6540 {
6541         struct config_enum *var;
6542
6543         var = (struct config_enum *)
6544                 init_custom_variable(name, short_desc, long_desc, context, flags,
6545                                                          PGC_ENUM, sizeof(struct config_enum));
6546         var->variable = valueAddr;
6547         var->boot_val = bootValue;
6548         var->reset_val = bootValue;
6549         var->options = options;
6550         var->check_hook = check_hook;
6551         var->assign_hook = assign_hook;
6552         var->show_hook = show_hook;
6553         define_custom_variable(&var->gen);
6554 }
6555
6556 void
6557 EmitWarningsOnPlaceholders(const char *className)
6558 {
6559         int                     classLen = strlen(className);
6560         int                     i;
6561
6562         for (i = 0; i < num_guc_variables; i++)
6563         {
6564                 struct config_generic *var = guc_variables[i];
6565
6566                 if ((var->flags & GUC_CUSTOM_PLACEHOLDER) != 0 &&
6567                         strncmp(className, var->name, classLen) == 0 &&
6568                         var->name[classLen] == GUC_QUALIFIER_SEPARATOR)
6569                 {
6570                         ereport(WARNING,
6571                                         (errcode(ERRCODE_UNDEFINED_OBJECT),
6572                                          errmsg("unrecognized configuration parameter \"%s\"",
6573                                                         var->name)));
6574                 }
6575         }
6576 }
6577
6578
6579 /*
6580  * SHOW command
6581  */
6582 void
6583 GetPGVariable(const char *name, DestReceiver *dest)
6584 {
6585         if (guc_name_compare(name, "all") == 0)
6586                 ShowAllGUCConfig(dest);
6587         else
6588                 ShowGUCConfigOption(name, dest);
6589 }
6590
6591 TupleDesc
6592 GetPGVariableResultDesc(const char *name)
6593 {
6594         TupleDesc       tupdesc;
6595
6596         if (guc_name_compare(name, "all") == 0)
6597         {
6598                 /* need a tuple descriptor representing three TEXT columns */
6599                 tupdesc = CreateTemplateTupleDesc(3, false);
6600                 TupleDescInitEntry(tupdesc, (AttrNumber) 1, "name",
6601                                                    TEXTOID, -1, 0);
6602                 TupleDescInitEntry(tupdesc, (AttrNumber) 2, "setting",
6603                                                    TEXTOID, -1, 0);
6604                 TupleDescInitEntry(tupdesc, (AttrNumber) 3, "description",
6605                                                    TEXTOID, -1, 0);
6606         }
6607         else
6608         {
6609                 const char *varname;
6610
6611                 /* Get the canonical spelling of name */
6612                 (void) GetConfigOptionByName(name, &varname);
6613
6614                 /* need a tuple descriptor representing a single TEXT column */
6615                 tupdesc = CreateTemplateTupleDesc(1, false);
6616                 TupleDescInitEntry(tupdesc, (AttrNumber) 1, varname,
6617                                                    TEXTOID, -1, 0);
6618         }
6619         return tupdesc;
6620 }
6621
6622
6623 /*
6624  * SHOW command
6625  */
6626 static void
6627 ShowGUCConfigOption(const char *name, DestReceiver *dest)
6628 {
6629         TupOutputState *tstate;
6630         TupleDesc       tupdesc;
6631         const char *varname;
6632         char       *value;
6633
6634         /* Get the value and canonical spelling of name */
6635         value = GetConfigOptionByName(name, &varname);
6636
6637         /* need a tuple descriptor representing a single TEXT column */
6638         tupdesc = CreateTemplateTupleDesc(1, false);
6639         TupleDescInitEntry(tupdesc, (AttrNumber) 1, varname,
6640                                            TEXTOID, -1, 0);
6641
6642         /* prepare for projection of tuples */
6643         tstate = begin_tup_output_tupdesc(dest, tupdesc);
6644
6645         /* Send it */
6646         do_text_output_oneline(tstate, value);
6647
6648         end_tup_output(tstate);
6649 }
6650
6651 /*
6652  * SHOW ALL command
6653  */
6654 static void
6655 ShowAllGUCConfig(DestReceiver *dest)
6656 {
6657         bool            am_superuser = superuser();
6658         int                     i;
6659         TupOutputState *tstate;
6660         TupleDesc       tupdesc;
6661         Datum           values[3];
6662         bool            isnull[3] = {false, false, false};
6663
6664         /* need a tuple descriptor representing three TEXT columns */
6665         tupdesc = CreateTemplateTupleDesc(3, false);
6666         TupleDescInitEntry(tupdesc, (AttrNumber) 1, "name",
6667                                            TEXTOID, -1, 0);
6668         TupleDescInitEntry(tupdesc, (AttrNumber) 2, "setting",
6669                                            TEXTOID, -1, 0);
6670         TupleDescInitEntry(tupdesc, (AttrNumber) 3, "description",
6671                                            TEXTOID, -1, 0);
6672
6673         /* prepare for projection of tuples */
6674         tstate = begin_tup_output_tupdesc(dest, tupdesc);
6675
6676         for (i = 0; i < num_guc_variables; i++)
6677         {
6678                 struct config_generic *conf = guc_variables[i];
6679                 char       *setting;
6680
6681                 if ((conf->flags & GUC_NO_SHOW_ALL) ||
6682                         ((conf->flags & GUC_SUPERUSER_ONLY) && !am_superuser))
6683                         continue;
6684
6685                 /* assign to the values array */
6686                 values[0] = PointerGetDatum(cstring_to_text(conf->name));
6687
6688                 setting = _ShowOption(conf, true);
6689                 if (setting)
6690                 {
6691                         values[1] = PointerGetDatum(cstring_to_text(setting));
6692                         isnull[1] = false;
6693                 }
6694                 else
6695                 {
6696                         values[1] = PointerGetDatum(NULL);
6697                         isnull[1] = true;
6698                 }
6699
6700                 values[2] = PointerGetDatum(cstring_to_text(conf->short_desc));
6701
6702                 /* send it to dest */
6703                 do_tup_output(tstate, values, isnull);
6704
6705                 /* clean up */
6706                 pfree(DatumGetPointer(values[0]));
6707                 if (setting)
6708                 {
6709                         pfree(setting);
6710                         pfree(DatumGetPointer(values[1]));
6711                 }
6712                 pfree(DatumGetPointer(values[2]));
6713         }
6714
6715         end_tup_output(tstate);
6716 }
6717
6718 /*
6719  * Return GUC variable value by name; optionally return canonical
6720  * form of name.  Return value is palloc'd.
6721  */
6722 char *
6723 GetConfigOptionByName(const char *name, const char **varname)
6724 {
6725         struct config_generic *record;
6726
6727         record = find_option(name, false, ERROR);
6728         if (record == NULL)
6729                 ereport(ERROR,
6730                                 (errcode(ERRCODE_UNDEFINED_OBJECT),
6731                            errmsg("unrecognized configuration parameter \"%s\"", name)));
6732         if ((record->flags & GUC_SUPERUSER_ONLY) && !superuser())
6733                 ereport(ERROR,
6734                                 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
6735                                  errmsg("must be superuser to examine \"%s\"", name)));
6736
6737         if (varname)
6738                 *varname = record->name;
6739
6740         return _ShowOption(record, true);
6741 }
6742
6743 /*
6744  * Return GUC variable value by variable number; optionally return canonical
6745  * form of name.  Return value is palloc'd.
6746  */
6747 void
6748 GetConfigOptionByNum(int varnum, const char **values, bool *noshow)
6749 {
6750         char            buffer[256];
6751         struct config_generic *conf;
6752
6753         /* check requested variable number valid */
6754         Assert((varnum >= 0) && (varnum < num_guc_variables));
6755
6756         conf = guc_variables[varnum];
6757
6758         if (noshow)
6759         {
6760                 if ((conf->flags & GUC_NO_SHOW_ALL) ||
6761                         ((conf->flags & GUC_SUPERUSER_ONLY) && !superuser()))
6762                         *noshow = true;
6763                 else
6764                         *noshow = false;
6765         }
6766
6767         /* first get the generic attributes */
6768
6769         /* name */
6770         values[0] = conf->name;
6771
6772         /* setting : use _ShowOption in order to avoid duplicating the logic */
6773         values[1] = _ShowOption(conf, false);
6774
6775         /* unit */
6776         if (conf->vartype == PGC_INT)
6777         {
6778                 static char buf[8];
6779
6780                 switch (conf->flags & (GUC_UNIT_MEMORY | GUC_UNIT_TIME))
6781                 {
6782                         case GUC_UNIT_KB:
6783                                 values[2] = "kB";
6784                                 break;
6785                         case GUC_UNIT_BLOCKS:
6786                                 snprintf(buf, sizeof(buf), "%dkB", BLCKSZ / 1024);
6787                                 values[2] = buf;
6788                                 break;
6789                         case GUC_UNIT_XBLOCKS:
6790                                 snprintf(buf, sizeof(buf), "%dkB", XLOG_BLCKSZ / 1024);
6791                                 values[2] = buf;
6792                                 break;
6793                         case GUC_UNIT_MS:
6794                                 values[2] = "ms";
6795                                 break;
6796                         case GUC_UNIT_S:
6797                                 values[2] = "s";
6798                                 break;
6799                         case GUC_UNIT_MIN:
6800                                 values[2] = "min";
6801                                 break;
6802                         default:
6803                                 values[2] = "";
6804                                 break;
6805                 }
6806         }
6807         else
6808                 values[2] = NULL;
6809
6810         /* group */
6811         values[3] = config_group_names[conf->group];
6812
6813         /* short_desc */
6814         values[4] = conf->short_desc;
6815
6816         /* extra_desc */
6817         values[5] = conf->long_desc;
6818
6819         /* context */
6820         values[6] = GucContext_Names[conf->context];
6821
6822         /* vartype */
6823         values[7] = config_type_names[conf->vartype];
6824
6825         /* source */
6826         values[8] = GucSource_Names[conf->source];
6827
6828         /* now get the type specifc attributes */
6829         switch (conf->vartype)
6830         {
6831                 case PGC_BOOL:
6832                         {
6833                                 struct config_bool *lconf = (struct config_bool *) conf;
6834
6835                                 /* min_val */
6836                                 values[9] = NULL;
6837
6838                                 /* max_val */
6839                                 values[10] = NULL;
6840
6841                                 /* enumvals */
6842                                 values[11] = NULL;
6843
6844                                 /* boot_val */
6845                                 values[12] = pstrdup(lconf->boot_val ? "on" : "off");
6846
6847                                 /* reset_val */
6848                                 values[13] = pstrdup(lconf->reset_val ? "on" : "off");
6849                         }
6850                         break;
6851
6852                 case PGC_INT:
6853                         {
6854                                 struct config_int *lconf = (struct config_int *) conf;
6855
6856                                 /* min_val */
6857                                 snprintf(buffer, sizeof(buffer), "%d", lconf->min);
6858                                 values[9] = pstrdup(buffer);
6859
6860                                 /* max_val */
6861                                 snprintf(buffer, sizeof(buffer), "%d", lconf->max);
6862                                 values[10] = pstrdup(buffer);
6863
6864                                 /* enumvals */
6865                                 values[11] = NULL;
6866
6867                                 /* boot_val */
6868                                 snprintf(buffer, sizeof(buffer), "%d", lconf->boot_val);
6869                                 values[12] = pstrdup(buffer);
6870
6871                                 /* reset_val */
6872                                 snprintf(buffer, sizeof(buffer), "%d", lconf->reset_val);
6873                                 values[13] = pstrdup(buffer);
6874                         }
6875                         break;
6876
6877                 case PGC_REAL:
6878                         {
6879                                 struct config_real *lconf = (struct config_real *) conf;
6880
6881                                 /* min_val */
6882                                 snprintf(buffer, sizeof(buffer), "%g", lconf->min);
6883                                 values[9] = pstrdup(buffer);
6884
6885                                 /* max_val */
6886                                 snprintf(buffer, sizeof(buffer), "%g", lconf->max);
6887                                 values[10] = pstrdup(buffer);
6888
6889                                 /* enumvals */
6890                                 values[11] = NULL;
6891
6892                                 /* boot_val */
6893                                 snprintf(buffer, sizeof(buffer), "%g", lconf->boot_val);
6894                                 values[12] = pstrdup(buffer);
6895
6896                                 /* reset_val */
6897                                 snprintf(buffer, sizeof(buffer), "%g", lconf->reset_val);
6898                                 values[13] = pstrdup(buffer);
6899                         }
6900                         break;
6901
6902                 case PGC_STRING:
6903                         {
6904                                 struct config_string *lconf = (struct config_string *) conf;
6905
6906                                 /* min_val */
6907                                 values[9] = NULL;
6908
6909                                 /* max_val */
6910                                 values[10] = NULL;
6911
6912                                 /* enumvals */
6913                                 values[11] = NULL;
6914
6915                                 /* boot_val */
6916                                 if (lconf->boot_val == NULL)
6917                                         values[12] = NULL;
6918                                 else
6919                                         values[12] = pstrdup(lconf->boot_val);
6920
6921                                 /* reset_val */
6922                                 if (lconf->reset_val == NULL)
6923                                         values[13] = NULL;
6924                                 else
6925                                         values[13] = pstrdup(lconf->reset_val);
6926                         }
6927                         break;
6928
6929                 case PGC_ENUM:
6930                         {
6931                                 struct config_enum *lconf = (struct config_enum *) conf;
6932
6933                                 /* min_val */
6934                                 values[9] = NULL;
6935
6936                                 /* max_val */
6937                                 values[10] = NULL;
6938
6939                                 /* enumvals */
6940
6941                                 /*
6942                                  * NOTE! enumvals with double quotes in them are not
6943                                  * supported!
6944                                  */
6945                                 values[11] = config_enum_get_options((struct config_enum *) conf,
6946                                                                                                          "{\"", "\"}", "\",\"");
6947
6948                                 /* boot_val */
6949                                 values[12] = pstrdup(config_enum_lookup_by_value(lconf,
6950                                                                                                                    lconf->boot_val));
6951
6952                                 /* reset_val */
6953                                 values[13] = pstrdup(config_enum_lookup_by_value(lconf,
6954                                                                                                                   lconf->reset_val));
6955                         }
6956                         break;
6957
6958                 default:
6959                         {
6960                                 /*
6961                                  * should never get here, but in case we do, set 'em to NULL
6962                                  */
6963
6964                                 /* min_val */
6965                                 values[9] = NULL;
6966
6967                                 /* max_val */
6968                                 values[10] = NULL;
6969
6970                                 /* enumvals */
6971                                 values[11] = NULL;
6972
6973                                 /* boot_val */
6974                                 values[12] = NULL;
6975
6976                                 /* reset_val */
6977                                 values[13] = NULL;
6978                         }
6979                         break;
6980         }
6981
6982         /*
6983          * If the setting came from a config file, set the source location. For
6984          * security reasons, we don't show source file/line number for
6985          * non-superusers.
6986          */
6987         if (conf->source == PGC_S_FILE && superuser())
6988         {
6989                 values[14] = conf->sourcefile;
6990                 snprintf(buffer, sizeof(buffer), "%d", conf->sourceline);
6991                 values[15] = pstrdup(buffer);
6992         }
6993         else
6994         {
6995                 values[14] = NULL;
6996                 values[15] = NULL;
6997         }
6998 }
6999
7000 /*
7001  * Return the total number of GUC variables
7002  */
7003 int
7004 GetNumConfigOptions(void)
7005 {
7006         return num_guc_variables;
7007 }
7008
7009 /*
7010  * show_config_by_name - equiv to SHOW X command but implemented as
7011  * a function.
7012  */
7013 Datum
7014 show_config_by_name(PG_FUNCTION_ARGS)
7015 {
7016         char       *varname;
7017         char       *varval;
7018
7019         /* Get the GUC variable name */
7020         varname = TextDatumGetCString(PG_GETARG_DATUM(0));
7021
7022         /* Get the value */
7023         varval = GetConfigOptionByName(varname, NULL);
7024
7025         /* Convert to text */
7026         PG_RETURN_TEXT_P(cstring_to_text(varval));
7027 }
7028
7029 /*
7030  * show_all_settings - equiv to SHOW ALL command but implemented as
7031  * a Table Function.
7032  */
7033 #define NUM_PG_SETTINGS_ATTS    16
7034
7035 Datum
7036 show_all_settings(PG_FUNCTION_ARGS)
7037 {
7038         FuncCallContext *funcctx;
7039         TupleDesc       tupdesc;
7040         int                     call_cntr;
7041         int                     max_calls;
7042         AttInMetadata *attinmeta;
7043         MemoryContext oldcontext;
7044
7045         /* stuff done only on the first call of the function */
7046         if (SRF_IS_FIRSTCALL())
7047         {
7048                 /* create a function context for cross-call persistence */
7049                 funcctx = SRF_FIRSTCALL_INIT();
7050
7051                 /*
7052                  * switch to memory context appropriate for multiple function calls
7053                  */
7054                 oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
7055
7056                 /*
7057                  * need a tuple descriptor representing NUM_PG_SETTINGS_ATTS columns
7058                  * of the appropriate types
7059                  */
7060                 tupdesc = CreateTemplateTupleDesc(NUM_PG_SETTINGS_ATTS, false);
7061                 TupleDescInitEntry(tupdesc, (AttrNumber) 1, "name",
7062                                                    TEXTOID, -1, 0);
7063                 TupleDescInitEntry(tupdesc, (AttrNumber) 2, "setting",
7064                                                    TEXTOID, -1, 0);
7065                 TupleDescInitEntry(tupdesc, (AttrNumber) 3, "unit",
7066                                                    TEXTOID, -1, 0);
7067                 TupleDescInitEntry(tupdesc, (AttrNumber) 4, "category",
7068                                                    TEXTOID, -1, 0);
7069                 TupleDescInitEntry(tupdesc, (AttrNumber) 5, "short_desc",
7070                                                    TEXTOID, -1, 0);
7071                 TupleDescInitEntry(tupdesc, (AttrNumber) 6, "extra_desc",
7072                                                    TEXTOID, -1, 0);
7073                 TupleDescInitEntry(tupdesc, (AttrNumber) 7, "context",
7074                                                    TEXTOID, -1, 0);
7075                 TupleDescInitEntry(tupdesc, (AttrNumber) 8, "vartype",
7076                                                    TEXTOID, -1, 0);
7077                 TupleDescInitEntry(tupdesc, (AttrNumber) 9, "source",
7078                                                    TEXTOID, -1, 0);
7079                 TupleDescInitEntry(tupdesc, (AttrNumber) 10, "min_val",
7080                                                    TEXTOID, -1, 0);
7081                 TupleDescInitEntry(tupdesc, (AttrNumber) 11, "max_val",
7082                                                    TEXTOID, -1, 0);
7083                 TupleDescInitEntry(tupdesc, (AttrNumber) 12, "enumvals",
7084                                                    TEXTARRAYOID, -1, 0);
7085                 TupleDescInitEntry(tupdesc, (AttrNumber) 13, "boot_val",
7086                                                    TEXTOID, -1, 0);
7087                 TupleDescInitEntry(tupdesc, (AttrNumber) 14, "reset_val",
7088                                                    TEXTOID, -1, 0);
7089                 TupleDescInitEntry(tupdesc, (AttrNumber) 15, "sourcefile",
7090                                                    TEXTOID, -1, 0);
7091                 TupleDescInitEntry(tupdesc, (AttrNumber) 16, "sourceline",
7092                                                    INT4OID, -1, 0);
7093
7094                 /*
7095                  * Generate attribute metadata needed later to produce tuples from raw
7096                  * C strings
7097                  */
7098                 attinmeta = TupleDescGetAttInMetadata(tupdesc);
7099                 funcctx->attinmeta = attinmeta;
7100
7101                 /* total number of tuples to be returned */
7102                 funcctx->max_calls = GetNumConfigOptions();
7103
7104                 MemoryContextSwitchTo(oldcontext);
7105         }
7106
7107         /* stuff done on every call of the function */
7108         funcctx = SRF_PERCALL_SETUP();
7109
7110         call_cntr = funcctx->call_cntr;
7111         max_calls = funcctx->max_calls;
7112         attinmeta = funcctx->attinmeta;
7113
7114         if (call_cntr < max_calls)      /* do when there is more left to send */
7115         {
7116                 char       *values[NUM_PG_SETTINGS_ATTS];
7117                 bool            noshow;
7118                 HeapTuple       tuple;
7119                 Datum           result;
7120
7121                 /*
7122                  * Get the next visible GUC variable name and value
7123                  */
7124                 do
7125                 {
7126                         GetConfigOptionByNum(call_cntr, (const char **) values, &noshow);
7127                         if (noshow)
7128                         {
7129                                 /* bump the counter and get the next config setting */
7130                                 call_cntr = ++funcctx->call_cntr;
7131
7132                                 /* make sure we haven't gone too far now */
7133                                 if (call_cntr >= max_calls)
7134                                         SRF_RETURN_DONE(funcctx);
7135                         }
7136                 } while (noshow);
7137
7138                 /* build a tuple */
7139                 tuple = BuildTupleFromCStrings(attinmeta, values);
7140
7141                 /* make the tuple into a datum */
7142                 result = HeapTupleGetDatum(tuple);
7143
7144                 SRF_RETURN_NEXT(funcctx, result);
7145         }
7146         else
7147         {
7148                 /* do when there is no more left */
7149                 SRF_RETURN_DONE(funcctx);
7150         }
7151 }
7152
7153 static char *
7154 _ShowOption(struct config_generic * record, bool use_units)
7155 {
7156         char            buffer[256];
7157         const char *val;
7158
7159         switch (record->vartype)
7160         {
7161                 case PGC_BOOL:
7162                         {
7163                                 struct config_bool *conf = (struct config_bool *) record;
7164
7165                                 if (conf->show_hook)
7166                                         val = (*conf->show_hook) ();
7167                                 else
7168                                         val = *conf->variable ? "on" : "off";
7169                         }
7170                         break;
7171
7172                 case PGC_INT:
7173                         {
7174                                 struct config_int *conf = (struct config_int *) record;
7175
7176                                 if (conf->show_hook)
7177                                         val = (*conf->show_hook) ();
7178                                 else
7179                                 {
7180                                         /*
7181                                          * Use int64 arithmetic to avoid overflows in units
7182                                          * conversion.
7183                                          */
7184                                         int64           result = *conf->variable;
7185                                         const char *unit;
7186
7187                                         if (use_units && result > 0 &&
7188                                                 (record->flags & GUC_UNIT_MEMORY))
7189                                         {
7190                                                 switch (record->flags & GUC_UNIT_MEMORY)
7191                                                 {
7192                                                         case GUC_UNIT_BLOCKS:
7193                                                                 result *= BLCKSZ / 1024;
7194                                                                 break;
7195                                                         case GUC_UNIT_XBLOCKS:
7196                                                                 result *= XLOG_BLCKSZ / 1024;
7197                                                                 break;
7198                                                 }
7199
7200                                                 if (result % KB_PER_GB == 0)
7201                                                 {
7202                                                         result /= KB_PER_GB;
7203                                                         unit = "GB";
7204                                                 }
7205                                                 else if (result % KB_PER_MB == 0)
7206                                                 {
7207                                                         result /= KB_PER_MB;
7208                                                         unit = "MB";
7209                                                 }
7210                                                 else
7211                                                 {
7212                                                         unit = "kB";
7213                                                 }
7214                                         }
7215                                         else if (use_units && result > 0 &&
7216                                                          (record->flags & GUC_UNIT_TIME))
7217                                         {
7218                                                 switch (record->flags & GUC_UNIT_TIME)
7219                                                 {
7220                                                         case GUC_UNIT_S:
7221                                                                 result *= MS_PER_S;
7222                                                                 break;
7223                                                         case GUC_UNIT_MIN:
7224                                                                 result *= MS_PER_MIN;
7225                                                                 break;
7226                                                 }
7227
7228                                                 if (result % MS_PER_D == 0)
7229                                                 {
7230                                                         result /= MS_PER_D;
7231                                                         unit = "d";
7232                                                 }
7233                                                 else if (result % MS_PER_H == 0)
7234                                                 {
7235                                                         result /= MS_PER_H;
7236                                                         unit = "h";
7237                                                 }
7238                                                 else if (result % MS_PER_MIN == 0)
7239                                                 {
7240                                                         result /= MS_PER_MIN;
7241                                                         unit = "min";
7242                                                 }
7243                                                 else if (result % MS_PER_S == 0)
7244                                                 {
7245                                                         result /= MS_PER_S;
7246                                                         unit = "s";
7247                                                 }
7248                                                 else
7249                                                 {
7250                                                         unit = "ms";
7251                                                 }
7252                                         }
7253                                         else
7254                                                 unit = "";
7255
7256                                         snprintf(buffer, sizeof(buffer), INT64_FORMAT "%s",
7257                                                          result, unit);
7258                                         val = buffer;
7259                                 }
7260                         }
7261                         break;
7262
7263                 case PGC_REAL:
7264                         {
7265                                 struct config_real *conf = (struct config_real *) record;
7266
7267                                 if (conf->show_hook)
7268                                         val = (*conf->show_hook) ();
7269                                 else
7270                                 {
7271                                         snprintf(buffer, sizeof(buffer), "%g",
7272                                                          *conf->variable);
7273                                         val = buffer;
7274                                 }
7275                         }
7276                         break;
7277
7278                 case PGC_STRING:
7279                         {
7280                                 struct config_string *conf = (struct config_string *) record;
7281
7282                                 if (conf->show_hook)
7283                                         val = (*conf->show_hook) ();
7284                                 else if (*conf->variable && **conf->variable)
7285                                         val = *conf->variable;
7286                                 else
7287                                         val = "";
7288                         }
7289                         break;
7290
7291                 case PGC_ENUM:
7292                         {
7293                                 struct config_enum *conf = (struct config_enum *) record;
7294
7295                                 if (conf->show_hook)
7296                                         val = (*conf->show_hook) ();
7297                                 else
7298                                         val = config_enum_lookup_by_value(conf, *conf->variable);
7299                         }
7300                         break;
7301
7302                 default:
7303                         /* just to keep compiler quiet */
7304                         val = "???";
7305                         break;
7306         }
7307
7308         return pstrdup(val);
7309 }
7310
7311
7312 #ifdef EXEC_BACKEND
7313
7314 /*
7315  *      These routines dump out all non-default GUC options into a binary
7316  *      file that is read by all exec'ed backends.  The format is:
7317  *
7318  *              variable name, string, null terminated
7319  *              variable value, string, null terminated
7320  *              variable source, integer
7321  */
7322 static void
7323 write_one_nondefault_variable(FILE *fp, struct config_generic * gconf)
7324 {
7325         if (gconf->source == PGC_S_DEFAULT)
7326                 return;
7327
7328         fprintf(fp, "%s", gconf->name);
7329         fputc(0, fp);
7330
7331         switch (gconf->vartype)
7332         {
7333                 case PGC_BOOL:
7334                         {
7335                                 struct config_bool *conf = (struct config_bool *) gconf;
7336
7337                                 if (*conf->variable)
7338                                         fprintf(fp, "true");
7339                                 else
7340                                         fprintf(fp, "false");
7341                         }
7342                         break;
7343
7344                 case PGC_INT:
7345                         {
7346                                 struct config_int *conf = (struct config_int *) gconf;
7347
7348                                 fprintf(fp, "%d", *conf->variable);
7349                         }
7350                         break;
7351
7352                 case PGC_REAL:
7353                         {
7354                                 struct config_real *conf = (struct config_real *) gconf;
7355
7356                                 /* Could lose precision here? */
7357                                 fprintf(fp, "%f", *conf->variable);
7358                         }
7359                         break;
7360
7361                 case PGC_STRING:
7362                         {
7363                                 struct config_string *conf = (struct config_string *) gconf;
7364
7365                                 fprintf(fp, "%s", *conf->variable);
7366                         }
7367                         break;
7368
7369                 case PGC_ENUM:
7370                         {
7371                                 struct config_enum *conf = (struct config_enum *) gconf;
7372
7373                                 fprintf(fp, "%s",
7374                                                 config_enum_lookup_by_value(conf, *conf->variable));
7375                         }
7376                         break;
7377         }
7378
7379         fputc(0, fp);
7380
7381         fwrite(&gconf->source, sizeof(gconf->source), 1, fp);
7382 }
7383
7384 void
7385 write_nondefault_variables(GucContext context)
7386 {
7387         int                     elevel;
7388         FILE       *fp;
7389         struct config_generic *cvc_conf;
7390         int                     i;
7391
7392         Assert(context == PGC_POSTMASTER || context == PGC_SIGHUP);
7393
7394         elevel = (context == PGC_SIGHUP) ? LOG : ERROR;
7395
7396         /*
7397          * Open file
7398          */
7399         fp = AllocateFile(CONFIG_EXEC_PARAMS_NEW, "w");
7400         if (!fp)
7401         {
7402                 ereport(elevel,
7403                                 (errcode_for_file_access(),
7404                                  errmsg("could not write to file \"%s\": %m",
7405                                                 CONFIG_EXEC_PARAMS_NEW)));
7406                 return;
7407         }
7408
7409         /*
7410          * custom_variable_classes must be written out first; otherwise we might
7411          * reject custom variable values while reading the file.
7412          */
7413         cvc_conf = find_option("custom_variable_classes", false, ERROR);
7414         if (cvc_conf)
7415                 write_one_nondefault_variable(fp, cvc_conf);
7416
7417         for (i = 0; i < num_guc_variables; i++)
7418         {
7419                 struct config_generic *gconf = guc_variables[i];
7420
7421                 if (gconf != cvc_conf)
7422                         write_one_nondefault_variable(fp, gconf);
7423         }
7424
7425         if (FreeFile(fp))
7426         {
7427                 ereport(elevel,
7428                                 (errcode_for_file_access(),
7429                                  errmsg("could not write to file \"%s\": %m",
7430                                                 CONFIG_EXEC_PARAMS_NEW)));
7431                 return;
7432         }
7433
7434         /*
7435          * Put new file in place.  This could delay on Win32, but we don't hold
7436          * any exclusive locks.
7437          */
7438         rename(CONFIG_EXEC_PARAMS_NEW, CONFIG_EXEC_PARAMS);
7439 }
7440
7441
7442 /*
7443  *      Read string, including null byte from file
7444  *
7445  *      Return NULL on EOF and nothing read
7446  */
7447 static char *
7448 read_string_with_null(FILE *fp)
7449 {
7450         int                     i = 0,
7451                                 ch,
7452                                 maxlen = 256;
7453         char       *str = NULL;
7454
7455         do
7456         {
7457                 if ((ch = fgetc(fp)) == EOF)
7458                 {
7459                         if (i == 0)
7460                                 return NULL;
7461                         else
7462                                 elog(FATAL, "invalid format of exec config params file");
7463                 }
7464                 if (i == 0)
7465                         str = guc_malloc(FATAL, maxlen);
7466                 else if (i == maxlen)
7467                         str = guc_realloc(FATAL, str, maxlen *= 2);
7468                 str[i++] = ch;
7469         } while (ch != 0);
7470
7471         return str;
7472 }
7473
7474
7475 /*
7476  *      This routine loads a previous postmaster dump of its non-default
7477  *      settings.
7478  */
7479 void
7480 read_nondefault_variables(void)
7481 {
7482         FILE       *fp;
7483         char       *varname,
7484                            *varvalue;
7485         int                     varsource;
7486
7487         /*
7488          * Open file
7489          */
7490         fp = AllocateFile(CONFIG_EXEC_PARAMS, "r");
7491         if (!fp)
7492         {
7493                 /* File not found is fine */
7494                 if (errno != ENOENT)
7495                         ereport(FATAL,
7496                                         (errcode_for_file_access(),
7497                                          errmsg("could not read from file \"%s\": %m",
7498                                                         CONFIG_EXEC_PARAMS)));
7499                 return;
7500         }
7501
7502         for (;;)
7503         {
7504                 struct config_generic *record;
7505
7506                 if ((varname = read_string_with_null(fp)) == NULL)
7507                         break;
7508
7509                 if ((record = find_option(varname, true, FATAL)) == NULL)
7510                         elog(FATAL, "failed to locate variable %s in exec config params file", varname);
7511                 if ((varvalue = read_string_with_null(fp)) == NULL)
7512                         elog(FATAL, "invalid format of exec config params file");
7513                 if (fread(&varsource, sizeof(varsource), 1, fp) == 0)
7514                         elog(FATAL, "invalid format of exec config params file");
7515
7516                 (void) set_config_option(varname, varvalue, record->context,
7517                                                                  varsource, GUC_ACTION_SET, true);
7518                 free(varname);
7519                 free(varvalue);
7520         }
7521
7522         FreeFile(fp);
7523 }
7524 #endif   /* EXEC_BACKEND */
7525
7526
7527 /*
7528  * A little "long argument" simulation, although not quite GNU
7529  * compliant. Takes a string of the form "some-option=some value" and
7530  * returns name = "some_option" and value = "some value" in malloc'ed
7531  * storage. Note that '-' is converted to '_' in the option name. If
7532  * there is no '=' in the input string then value will be NULL.
7533  */
7534 void
7535 ParseLongOption(const char *string, char **name, char **value)
7536 {
7537         size_t          equal_pos;
7538         char       *cp;
7539
7540         AssertArg(string);
7541         AssertArg(name);
7542         AssertArg(value);
7543
7544         equal_pos = strcspn(string, "=");
7545
7546         if (string[equal_pos] == '=')
7547         {
7548                 *name = guc_malloc(FATAL, equal_pos + 1);
7549                 strlcpy(*name, string, equal_pos + 1);
7550
7551                 *value = guc_strdup(FATAL, &string[equal_pos + 1]);
7552         }
7553         else
7554         {
7555                 /* no equal sign in string */
7556                 *name = guc_strdup(FATAL, string);
7557                 *value = NULL;
7558         }
7559
7560         for (cp = *name; *cp; cp++)
7561                 if (*cp == '-')
7562                         *cp = '_';
7563 }
7564
7565
7566 /*
7567  * Handle options fetched from pg_db_role_setting.setconfig,
7568  * pg_proc.proconfig, etc.      Caller must specify proper context/source/action.
7569  *
7570  * The array parameter must be an array of TEXT (it must not be NULL).
7571  */
7572 void
7573 ProcessGUCArray(ArrayType *array,
7574                                 GucContext context, GucSource source, GucAction action)
7575 {
7576         int                     i;
7577
7578         Assert(array != NULL);
7579         Assert(ARR_ELEMTYPE(array) == TEXTOID);
7580         Assert(ARR_NDIM(array) == 1);
7581         Assert(ARR_LBOUND(array)[0] == 1);
7582
7583         for (i = 1; i <= ARR_DIMS(array)[0]; i++)
7584         {
7585                 Datum           d;
7586                 bool            isnull;
7587                 char       *s;
7588                 char       *name;
7589                 char       *value;
7590
7591                 d = array_ref(array, 1, &i,
7592                                           -1 /* varlenarray */ ,
7593                                           -1 /* TEXT's typlen */ ,
7594                                           false /* TEXT's typbyval */ ,
7595                                           'i' /* TEXT's typalign */ ,
7596                                           &isnull);
7597
7598                 if (isnull)
7599                         continue;
7600
7601                 s = TextDatumGetCString(d);
7602
7603                 ParseLongOption(s, &name, &value);
7604                 if (!value)
7605                 {
7606                         ereport(WARNING,
7607                                         (errcode(ERRCODE_SYNTAX_ERROR),
7608                                          errmsg("could not parse setting for parameter \"%s\"",
7609                                                         name)));
7610                         free(name);
7611                         continue;
7612                 }
7613
7614                 (void) set_config_option(name, value, context, source, action, true);
7615
7616                 free(name);
7617                 if (value)
7618                         free(value);
7619                 pfree(s);
7620         }
7621 }
7622
7623
7624 /*
7625  * Add an entry to an option array.  The array parameter may be NULL
7626  * to indicate the current table entry is NULL.
7627  */
7628 ArrayType *
7629 GUCArrayAdd(ArrayType *array, const char *name, const char *value)
7630 {
7631         struct config_generic *record;
7632         Datum           datum;
7633         char       *newval;
7634         ArrayType  *a;
7635
7636         Assert(name);
7637         Assert(value);
7638
7639         /* test if the option is valid and we're allowed to set it */
7640         (void) validate_option_array_item(name, value, false);
7641
7642         /* normalize name (converts obsolete GUC names to modern spellings) */
7643         record = find_option(name, false, WARNING);
7644         if (record)
7645                 name = record->name;
7646
7647         /* build new item for array */
7648         newval = palloc(strlen(name) + 1 + strlen(value) + 1);
7649         sprintf(newval, "%s=%s", name, value);
7650         datum = CStringGetTextDatum(newval);
7651
7652         if (array)
7653         {
7654                 int                     index;
7655                 bool            isnull;
7656                 int                     i;
7657
7658                 Assert(ARR_ELEMTYPE(array) == TEXTOID);
7659                 Assert(ARR_NDIM(array) == 1);
7660                 Assert(ARR_LBOUND(array)[0] == 1);
7661
7662                 index = ARR_DIMS(array)[0] + 1; /* add after end */
7663
7664                 for (i = 1; i <= ARR_DIMS(array)[0]; i++)
7665                 {
7666                         Datum           d;
7667                         char       *current;
7668
7669                         d = array_ref(array, 1, &i,
7670                                                   -1 /* varlenarray */ ,
7671                                                   -1 /* TEXT's typlen */ ,
7672                                                   false /* TEXT's typbyval */ ,
7673                                                   'i' /* TEXT's typalign */ ,
7674                                                   &isnull);
7675                         if (isnull)
7676                                 continue;
7677                         current = TextDatumGetCString(d);
7678
7679                         /* check for match up through and including '=' */
7680                         if (strncmp(current, newval, strlen(name) + 1) == 0)
7681                         {
7682                                 index = i;
7683                                 break;
7684                         }
7685                 }
7686
7687                 a = array_set(array, 1, &index,
7688                                           datum,
7689                                           false,
7690                                           -1 /* varlena array */ ,
7691                                           -1 /* TEXT's typlen */ ,
7692                                           false /* TEXT's typbyval */ ,
7693                                           'i' /* TEXT's typalign */ );
7694         }
7695         else
7696                 a = construct_array(&datum, 1,
7697                                                         TEXTOID,
7698                                                         -1, false, 'i');
7699
7700         return a;
7701 }
7702
7703
7704 /*
7705  * Delete an entry from an option array.  The array parameter may be NULL
7706  * to indicate the current table entry is NULL.  Also, if the return value
7707  * is NULL then a null should be stored.
7708  */
7709 ArrayType *
7710 GUCArrayDelete(ArrayType *array, const char *name)
7711 {
7712         struct config_generic *record;
7713         ArrayType  *newarray;
7714         int                     i;
7715         int                     index;
7716
7717         Assert(name);
7718
7719         /* test if the option is valid and we're allowed to set it */
7720         (void) validate_option_array_item(name, NULL, false);
7721
7722         /* normalize name (converts obsolete GUC names to modern spellings) */
7723         record = find_option(name, false, WARNING);
7724         if (record)
7725                 name = record->name;
7726
7727         /* if array is currently null, then surely nothing to delete */
7728         if (!array)
7729                 return NULL;
7730
7731         newarray = NULL;
7732         index = 1;
7733
7734         for (i = 1; i <= ARR_DIMS(array)[0]; i++)
7735         {
7736                 Datum           d;
7737                 char       *val;
7738                 bool            isnull;
7739
7740                 d = array_ref(array, 1, &i,
7741                                           -1 /* varlenarray */ ,
7742                                           -1 /* TEXT's typlen */ ,
7743                                           false /* TEXT's typbyval */ ,
7744                                           'i' /* TEXT's typalign */ ,
7745                                           &isnull);
7746                 if (isnull)
7747                         continue;
7748                 val = TextDatumGetCString(d);
7749
7750                 /* ignore entry if it's what we want to delete */
7751                 if (strncmp(val, name, strlen(name)) == 0
7752                         && val[strlen(name)] == '=')
7753                         continue;
7754
7755                 /* else add it to the output array */
7756                 if (newarray)
7757                         newarray = array_set(newarray, 1, &index,
7758                                                                  d,
7759                                                                  false,
7760                                                                  -1 /* varlenarray */ ,
7761                                                                  -1 /* TEXT's typlen */ ,
7762                                                                  false /* TEXT's typbyval */ ,
7763                                                                  'i' /* TEXT's typalign */ );
7764                 else
7765                         newarray = construct_array(&d, 1,
7766                                                                            TEXTOID,
7767                                                                            -1, false, 'i');
7768
7769                 index++;
7770         }
7771
7772         return newarray;
7773 }
7774
7775
7776 /*
7777  * Given a GUC array, delete all settings from it that our permission
7778  * level allows: if superuser, delete them all; if regular user, only
7779  * those that are PGC_USERSET
7780  */
7781 ArrayType *
7782 GUCArrayReset(ArrayType *array)
7783 {
7784         ArrayType  *newarray;
7785         int                     i;
7786         int                     index;
7787
7788         /* if array is currently null, nothing to do */
7789         if (!array)
7790                 return NULL;
7791
7792         /* if we're superuser, we can delete everything, so just do it */
7793         if (superuser())
7794                 return NULL;
7795
7796         newarray = NULL;
7797         index = 1;
7798
7799         for (i = 1; i <= ARR_DIMS(array)[0]; i++)
7800         {
7801                 Datum           d;
7802                 char       *val;
7803                 char       *eqsgn;
7804                 bool            isnull;
7805
7806                 d = array_ref(array, 1, &i,
7807                                           -1 /* varlenarray */ ,
7808                                           -1 /* TEXT's typlen */ ,
7809                                           false /* TEXT's typbyval */ ,
7810                                           'i' /* TEXT's typalign */ ,
7811                                           &isnull);
7812                 if (isnull)
7813                         continue;
7814                 val = TextDatumGetCString(d);
7815
7816                 eqsgn = strchr(val, '=');
7817                 *eqsgn = '\0';
7818
7819                 /* skip if we have permission to delete it */
7820                 if (validate_option_array_item(val, NULL, true))
7821                         continue;
7822
7823                 /* else add it to the output array */
7824                 if (newarray)
7825                         newarray = array_set(newarray, 1, &index,
7826                                                                  d,
7827                                                                  false,
7828                                                                  -1 /* varlenarray */ ,
7829                                                                  -1 /* TEXT's typlen */ ,
7830                                                                  false /* TEXT's typbyval */ ,
7831                                                                  'i' /* TEXT's typalign */ );
7832                 else
7833                         newarray = construct_array(&d, 1,
7834                                                                            TEXTOID,
7835                                                                            -1, false, 'i');
7836
7837                 index++;
7838                 pfree(val);
7839         }
7840
7841         return newarray;
7842 }
7843
7844 /*
7845  * Validate a proposed option setting for GUCArrayAdd/Delete/Reset.
7846  *
7847  * name is the option name.  value is the proposed value for the Add case,
7848  * or NULL for the Delete/Reset cases.  If skipIfNoPermissions is true, it's
7849  * not an error to have no permissions to set the option.
7850  *
7851  * Returns TRUE if OK, FALSE if skipIfNoPermissions is true and user does not
7852  * have permission to change this option (all other error cases result in an
7853  * error being thrown).
7854  */
7855 static bool
7856 validate_option_array_item(const char *name, const char *value,
7857                                                    bool skipIfNoPermissions)
7858
7859 {
7860         struct config_generic *gconf;
7861
7862         /*
7863          * There are three cases to consider:
7864          *
7865          * name is a known GUC variable.  Check the value normally, check
7866          * permissions normally (ie, allow if variable is USERSET, or if it's
7867          * SUSET and user is superuser).
7868          *
7869          * name is not known, but exists or can be created as a placeholder
7870          * (implying it has a prefix listed in custom_variable_classes). We allow
7871          * this case if you're a superuser, otherwise not.  Superusers are assumed
7872          * to know what they're doing.  We can't allow it for other users, because
7873          * when the placeholder is resolved it might turn out to be a SUSET
7874          * variable; define_custom_variable assumes we checked that.
7875          *
7876          * name is not known and can't be created as a placeholder.  Throw error,
7877          * unless skipIfNoPermissions is true, in which case return FALSE. (It's
7878          * tempting to allow this case to superusers, if the name is qualified but
7879          * not listed in custom_variable_classes.  That would ease restoring of
7880          * dumps containing ALTER ROLE/DATABASE SET.  However, it's not clear that
7881          * this usage justifies such a loss of error checking. You can always fix
7882          * custom_variable_classes before you restore.)
7883          */
7884         gconf = find_option(name, true, WARNING);
7885         if (!gconf)
7886         {
7887                 /* not known, failed to make a placeholder */
7888                 if (skipIfNoPermissions)
7889                         return false;
7890                 ereport(ERROR,
7891                                 (errcode(ERRCODE_UNDEFINED_OBJECT),
7892                            errmsg("unrecognized configuration parameter \"%s\"", name)));
7893         }
7894
7895         if (gconf->flags & GUC_CUSTOM_PLACEHOLDER)
7896         {
7897                 /*
7898                  * We cannot do any meaningful check on the value, so only permissions
7899                  * are useful to check.
7900                  */
7901                 if (superuser())
7902                         return true;
7903                 if (skipIfNoPermissions)
7904                         return false;
7905                 ereport(ERROR,
7906                                 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
7907                                  errmsg("permission denied to set parameter \"%s\"", name)));
7908         }
7909
7910         /* manual permissions check so we can avoid an error being thrown */
7911         if (gconf->context == PGC_USERSET)
7912                  /* ok */ ;
7913         else if (gconf->context == PGC_SUSET && superuser())
7914                  /* ok */ ;
7915         else if (skipIfNoPermissions)
7916                 return false;
7917         /* if a permissions error should be thrown, let set_config_option do it */
7918
7919         /* test for permissions and valid option value */
7920         set_config_option(name, value,
7921                                           superuser() ? PGC_SUSET : PGC_USERSET,
7922                                           PGC_S_TEST, GUC_ACTION_SET, false);
7923
7924         return true;
7925 }
7926
7927
7928 /*
7929  * Called by check_hooks that want to override the normal
7930  * ERRCODE_INVALID_PARAMETER_VALUE SQLSTATE for check hook failures.
7931  *
7932  * Note that GUC_check_errmsg() etc are just macros that result in a direct
7933  * assignment to the associated variables.      That is ugly, but forced by the
7934  * limitations of C's macro mechanisms.
7935  */
7936 void
7937 GUC_check_errcode(int sqlerrcode)
7938 {
7939         GUC_check_errcode_value = sqlerrcode;
7940 }
7941
7942
7943 /*
7944  * Convenience functions to manage calling a variable's check_hook.
7945  * These mostly take care of the protocol for letting check hooks supply
7946  * portions of the error report on failure.
7947  */
7948
7949 static bool
7950 call_bool_check_hook(struct config_bool * conf, bool *newval, void **extra,
7951                                          GucSource source, int elevel)
7952 {
7953         /* Quick success if no hook */
7954         if (!conf->check_hook)
7955                 return true;
7956
7957         /* Reset variables that might be set by hook */
7958         GUC_check_errcode_value = ERRCODE_INVALID_PARAMETER_VALUE;
7959         GUC_check_errmsg_string = NULL;
7960         GUC_check_errdetail_string = NULL;
7961         GUC_check_errhint_string = NULL;
7962
7963         if (!(*conf->check_hook) (newval, extra, source))
7964         {
7965                 ereport(elevel,
7966                                 (errcode(GUC_check_errcode_value),
7967                                  GUC_check_errmsg_string ?
7968                                  errmsg("%s", GUC_check_errmsg_string) :
7969                                  errmsg("invalid value for parameter \"%s\": %d",
7970                                                 conf->gen.name, (int) *newval),
7971                                  GUC_check_errdetail_string ?
7972                                  errdetail("%s", GUC_check_errdetail_string) : 0,
7973                                  GUC_check_errhint_string ?
7974                                  errhint("%s", GUC_check_errhint_string) : 0));
7975                 /* Flush any strings created in ErrorContext */
7976                 FlushErrorState();
7977                 return false;
7978         }
7979
7980         return true;
7981 }
7982
7983 static bool
7984 call_int_check_hook(struct config_int * conf, int *newval, void **extra,
7985                                         GucSource source, int elevel)
7986 {
7987         /* Quick success if no hook */
7988         if (!conf->check_hook)
7989                 return true;
7990
7991         /* Reset variables that might be set by hook */
7992         GUC_check_errcode_value = ERRCODE_INVALID_PARAMETER_VALUE;
7993         GUC_check_errmsg_string = NULL;
7994         GUC_check_errdetail_string = NULL;
7995         GUC_check_errhint_string = NULL;
7996
7997         if (!(*conf->check_hook) (newval, extra, source))
7998         {
7999                 ereport(elevel,
8000                                 (errcode(GUC_check_errcode_value),
8001                                  GUC_check_errmsg_string ?
8002                                  errmsg("%s", GUC_check_errmsg_string) :
8003                                  errmsg("invalid value for parameter \"%s\": %d",
8004                                                 conf->gen.name, *newval),
8005                                  GUC_check_errdetail_string ?
8006                                  errdetail("%s", GUC_check_errdetail_string) : 0,
8007                                  GUC_check_errhint_string ?
8008                                  errhint("%s", GUC_check_errhint_string) : 0));
8009                 /* Flush any strings created in ErrorContext */
8010                 FlushErrorState();
8011                 return false;
8012         }
8013
8014         return true;
8015 }
8016
8017 static bool
8018 call_real_check_hook(struct config_real * conf, double *newval, void **extra,
8019                                          GucSource source, int elevel)
8020 {
8021         /* Quick success if no hook */
8022         if (!conf->check_hook)
8023                 return true;
8024
8025         /* Reset variables that might be set by hook */
8026         GUC_check_errcode_value = ERRCODE_INVALID_PARAMETER_VALUE;
8027         GUC_check_errmsg_string = NULL;
8028         GUC_check_errdetail_string = NULL;
8029         GUC_check_errhint_string = NULL;
8030
8031         if (!(*conf->check_hook) (newval, extra, source))
8032         {
8033                 ereport(elevel,
8034                                 (errcode(GUC_check_errcode_value),
8035                                  GUC_check_errmsg_string ?
8036                                  errmsg("%s", GUC_check_errmsg_string) :
8037                                  errmsg("invalid value for parameter \"%s\": %g",
8038                                                 conf->gen.name, *newval),
8039                                  GUC_check_errdetail_string ?
8040                                  errdetail("%s", GUC_check_errdetail_string) : 0,
8041                                  GUC_check_errhint_string ?
8042                                  errhint("%s", GUC_check_errhint_string) : 0));
8043                 /* Flush any strings created in ErrorContext */
8044                 FlushErrorState();
8045                 return false;
8046         }
8047
8048         return true;
8049 }
8050
8051 static bool
8052 call_string_check_hook(struct config_string * conf, char **newval, void **extra,
8053                                            GucSource source, int elevel)
8054 {
8055         /* Quick success if no hook */
8056         if (!conf->check_hook)
8057                 return true;
8058
8059         /* Reset variables that might be set by hook */
8060         GUC_check_errcode_value = ERRCODE_INVALID_PARAMETER_VALUE;
8061         GUC_check_errmsg_string = NULL;
8062         GUC_check_errdetail_string = NULL;
8063         GUC_check_errhint_string = NULL;
8064
8065         if (!(*conf->check_hook) (newval, extra, source))
8066         {
8067                 ereport(elevel,
8068                                 (errcode(GUC_check_errcode_value),
8069                                  GUC_check_errmsg_string ?
8070                                  errmsg("%s", GUC_check_errmsg_string) :
8071                                  errmsg("invalid value for parameter \"%s\": \"%s\"",
8072                                                 conf->gen.name, *newval ? *newval : ""),
8073                                  GUC_check_errdetail_string ?
8074                                  errdetail("%s", GUC_check_errdetail_string) : 0,
8075                                  GUC_check_errhint_string ?
8076                                  errhint("%s", GUC_check_errhint_string) : 0));
8077                 /* Flush any strings created in ErrorContext */
8078                 FlushErrorState();
8079                 return false;
8080         }
8081
8082         return true;
8083 }
8084
8085 static bool
8086 call_enum_check_hook(struct config_enum * conf, int *newval, void **extra,
8087                                          GucSource source, int elevel)
8088 {
8089         /* Quick success if no hook */
8090         if (!conf->check_hook)
8091                 return true;
8092
8093         /* Reset variables that might be set by hook */
8094         GUC_check_errcode_value = ERRCODE_INVALID_PARAMETER_VALUE;
8095         GUC_check_errmsg_string = NULL;
8096         GUC_check_errdetail_string = NULL;
8097         GUC_check_errhint_string = NULL;
8098
8099         if (!(*conf->check_hook) (newval, extra, source))
8100         {
8101                 ereport(elevel,
8102                                 (errcode(GUC_check_errcode_value),
8103                                  GUC_check_errmsg_string ?
8104                                  errmsg("%s", GUC_check_errmsg_string) :
8105                                  errmsg("invalid value for parameter \"%s\": \"%s\"",
8106                                                 conf->gen.name,
8107                                                 config_enum_lookup_by_value(conf, *newval)),
8108                                  GUC_check_errdetail_string ?
8109                                  errdetail("%s", GUC_check_errdetail_string) : 0,
8110                                  GUC_check_errhint_string ?
8111                                  errhint("%s", GUC_check_errhint_string) : 0));
8112                 /* Flush any strings created in ErrorContext */
8113                 FlushErrorState();
8114                 return false;
8115         }
8116
8117         return true;
8118 }
8119
8120
8121 /*
8122  * check_hook, assign_hook and show_hook subroutines
8123  */
8124
8125 static bool
8126 check_log_destination(char **newval, void **extra, GucSource source)
8127 {
8128         char       *rawstring;
8129         List       *elemlist;
8130         ListCell   *l;
8131         int                     newlogdest = 0;
8132         int                *myextra;
8133
8134         /* Need a modifiable copy of string */
8135         rawstring = pstrdup(*newval);
8136
8137         /* Parse string into list of identifiers */
8138         if (!SplitIdentifierString(rawstring, ',', &elemlist))
8139         {
8140                 /* syntax error in list */
8141                 GUC_check_errdetail("List syntax is invalid.");
8142                 pfree(rawstring);
8143                 list_free(elemlist);
8144                 return false;
8145         }
8146
8147         foreach(l, elemlist)
8148         {
8149                 char       *tok = (char *) lfirst(l);
8150
8151                 if (pg_strcasecmp(tok, "stderr") == 0)
8152                         newlogdest |= LOG_DESTINATION_STDERR;
8153                 else if (pg_strcasecmp(tok, "csvlog") == 0)
8154                         newlogdest |= LOG_DESTINATION_CSVLOG;
8155 #ifdef HAVE_SYSLOG
8156                 else if (pg_strcasecmp(tok, "syslog") == 0)
8157                         newlogdest |= LOG_DESTINATION_SYSLOG;
8158 #endif
8159 #ifdef WIN32
8160                 else if (pg_strcasecmp(tok, "eventlog") == 0)
8161                         newlogdest |= LOG_DESTINATION_EVENTLOG;
8162 #endif
8163                 else
8164                 {
8165                         GUC_check_errdetail("Unrecognized key word: \"%s\".", tok);
8166                         pfree(rawstring);
8167                         list_free(elemlist);
8168                         return false;
8169                 }
8170         }
8171
8172         pfree(rawstring);
8173         list_free(elemlist);
8174
8175         myextra = (int *) guc_malloc(ERROR, sizeof(int));
8176         *myextra = newlogdest;
8177         *extra = (void *) myextra;
8178
8179         return true;
8180 }
8181
8182 static void
8183 assign_log_destination(const char *newval, void *extra)
8184 {
8185         Log_destination = *((int *) extra);
8186 }
8187
8188 static void
8189 assign_syslog_facility(int newval, void *extra)
8190 {
8191 #ifdef HAVE_SYSLOG
8192         set_syslog_parameters(syslog_ident_str ? syslog_ident_str : "postgres",
8193                                                   newval);
8194 #endif
8195         /* Without syslog support, just ignore it */
8196 }
8197
8198 static void
8199 assign_syslog_ident(const char *newval, void *extra)
8200 {
8201 #ifdef HAVE_SYSLOG
8202         set_syslog_parameters(newval, syslog_facility);
8203 #endif
8204         /* Without syslog support, it will always be set to "none", so ignore */
8205 }
8206
8207
8208 static void
8209 assign_session_replication_role(int newval, void *extra)
8210 {
8211         /*
8212          * Must flush the plan cache when changing replication role; but don't
8213          * flush unnecessarily.
8214          */
8215         if (SessionReplicationRole != newval)
8216                 ResetPlanCache();
8217 }
8218
8219 static bool
8220 check_temp_buffers(int *newval, void **extra, GucSource source)
8221 {
8222         /*
8223          * Once local buffers have been initialized, it's too late to change this.
8224          */
8225         if (NLocBuffer && NLocBuffer != *newval)
8226         {
8227                 GUC_check_errdetail("\"temp_buffers\" cannot be changed after any temporary tables have been accessed in the session.");
8228                 return false;
8229         }
8230         return true;
8231 }
8232
8233 static bool
8234 check_phony_autocommit(bool *newval, void **extra, GucSource source)
8235 {
8236         if (!*newval)
8237         {
8238                 GUC_check_errcode(ERRCODE_FEATURE_NOT_SUPPORTED);
8239                 GUC_check_errmsg("SET AUTOCOMMIT TO OFF is no longer supported");
8240                 return false;
8241         }
8242         return true;
8243 }
8244
8245 static bool
8246 check_custom_variable_classes(char **newval, void **extra, GucSource source)
8247 {
8248         /*
8249          * Check syntax. newval must be a comma separated list of identifiers.
8250          * Whitespace is allowed but removed from the result.
8251          */
8252         bool            hasSpaceAfterToken = false;
8253         const char *cp = *newval;
8254         int                     symLen = 0;
8255         char            c;
8256         StringInfoData buf;
8257
8258         /* Default NULL is OK */
8259         if (cp == NULL)
8260                 return true;
8261
8262         initStringInfo(&buf);
8263         while ((c = *cp++) != '\0')
8264         {
8265                 if (isspace((unsigned char) c))
8266                 {
8267                         if (symLen > 0)
8268                                 hasSpaceAfterToken = true;
8269                         continue;
8270                 }
8271
8272                 if (c == ',')
8273                 {
8274                         if (symLen > 0)         /* terminate identifier */
8275                         {
8276                                 appendStringInfoChar(&buf, ',');
8277                                 symLen = 0;
8278                         }
8279                         hasSpaceAfterToken = false;
8280                         continue;
8281                 }
8282
8283                 if (hasSpaceAfterToken || !(isalnum((unsigned char) c) || c == '_'))
8284                 {
8285                         /*
8286                          * Syntax error due to token following space after token or
8287                          * non-identifier character
8288                          */
8289                         pfree(buf.data);
8290                         return false;
8291                 }
8292                 appendStringInfoChar(&buf, c);
8293                 symLen++;
8294         }
8295
8296         /* Remove stray ',' at end */
8297         if (symLen == 0 && buf.len > 0)
8298                 buf.data[--buf.len] = '\0';
8299
8300         /* GUC wants the result malloc'd */
8301         free(*newval);
8302         *newval = guc_strdup(LOG, buf.data);
8303
8304         pfree(buf.data);
8305         return true;
8306 }
8307
8308 static bool
8309 check_debug_assertions(bool *newval, void **extra, GucSource source)
8310 {
8311 #ifndef USE_ASSERT_CHECKING
8312         if (*newval)
8313         {
8314                 GUC_check_errmsg("assertion checking is not supported by this build");
8315                 return false;
8316         }
8317 #endif
8318         return true;
8319 }
8320
8321 static bool
8322 check_bonjour(bool *newval, void **extra, GucSource source)
8323 {
8324 #ifndef USE_BONJOUR
8325         if (*newval)
8326         {
8327                 GUC_check_errmsg("Bonjour is not supported by this build");
8328                 return false;
8329         }
8330 #endif
8331         return true;
8332 }
8333
8334 static bool
8335 check_ssl(bool *newval, void **extra, GucSource source)
8336 {
8337 #ifndef USE_SSL
8338         if (*newval)
8339         {
8340                 GUC_check_errmsg("SSL is not supported by this build");
8341                 return false;
8342         }
8343 #endif
8344         return true;
8345 }
8346
8347 static bool
8348 check_stage_log_stats(bool *newval, void **extra, GucSource source)
8349 {
8350         if (*newval && log_statement_stats)
8351         {
8352                 GUC_check_errdetail("Cannot enable parameter when \"log_statement_stats\" is true.");
8353                 return false;
8354         }
8355         return true;
8356 }
8357
8358 static bool
8359 check_log_stats(bool *newval, void **extra, GucSource source)
8360 {
8361         if (*newval &&
8362                 (log_parser_stats || log_planner_stats || log_executor_stats))
8363         {
8364                 GUC_check_errdetail("Cannot enable \"log_statement_stats\" when "
8365                                                         "\"log_parser_stats\", \"log_planner_stats\", "
8366                                                         "or \"log_executor_stats\" is true.");
8367                 return false;
8368         }
8369         return true;
8370 }
8371
8372 static bool
8373 check_canonical_path(char **newval, void **extra, GucSource source)
8374 {
8375         /*
8376          * Since canonicalize_path never enlarges the string, we can just modify
8377          * newval in-place.  But watch out for NULL, which is the default value
8378          * for external_pid_file.
8379          */
8380         if (*newval)
8381                 canonicalize_path(*newval);
8382         return true;
8383 }
8384
8385 static bool
8386 check_timezone_abbreviations(char **newval, void **extra, GucSource source)
8387 {
8388         /*
8389          * The boot_val given above for timezone_abbreviations is NULL. When we
8390          * see this we just do nothing.  If this value isn't overridden from the
8391          * config file then pg_timezone_abbrev_initialize() will eventually
8392          * replace it with "Default".  This hack has two purposes: to avoid
8393          * wasting cycles loading values that might soon be overridden from the
8394          * config file, and to avoid trying to read the timezone abbrev files
8395          * during InitializeGUCOptions().  The latter doesn't work in an
8396          * EXEC_BACKEND subprocess because my_exec_path hasn't been set yet and so
8397          * we can't locate PGSHAREDIR.
8398          */
8399         if (*newval == NULL)
8400         {
8401                 Assert(source == PGC_S_DEFAULT);
8402                 return true;
8403         }
8404
8405         /* OK, load the file and produce a malloc'd TimeZoneAbbrevTable */
8406         *extra = load_tzoffsets(*newval);
8407
8408         /* tzparser.c returns NULL on failure, reporting via GUC_check_errmsg */
8409         if (!*extra)
8410                 return false;
8411
8412         return true;
8413 }
8414
8415 static void
8416 assign_timezone_abbreviations(const char *newval, void *extra)
8417 {
8418         /* Do nothing for the boot_val default of NULL */
8419         if (!extra)
8420                 return;
8421
8422         InstallTimeZoneAbbrevs((TimeZoneAbbrevTable *) extra);
8423 }
8424
8425 /*
8426  * pg_timezone_abbrev_initialize --- set default value if not done already
8427  *
8428  * This is called after initial loading of postgresql.conf.  If no
8429  * timezone_abbreviations setting was found therein, select default.
8430  * If a non-default value is already installed, nothing will happen.
8431  */
8432 void
8433 pg_timezone_abbrev_initialize(void)
8434 {
8435         SetConfigOption("timezone_abbreviations", "Default",
8436                                         PGC_POSTMASTER, PGC_S_DYNAMIC_DEFAULT);
8437 }
8438
8439 static const char *
8440 show_archive_command(void)
8441 {
8442         if (XLogArchivingActive())
8443                 return XLogArchiveCommand;
8444         else
8445                 return "(disabled)";
8446 }
8447
8448 static void
8449 assign_tcp_keepalives_idle(int newval, void *extra)
8450 {
8451         /*
8452          * The kernel API provides no way to test a value without setting it; and
8453          * once we set it we might fail to unset it.  So there seems little point
8454          * in fully implementing the check-then-assign GUC API for these
8455          * variables.  Instead we just do the assignment on demand.  pqcomm.c
8456          * reports any problems via elog(LOG).
8457          *
8458          * This approach means that the GUC value might have little to do with the
8459          * actual kernel value, so we use a show_hook that retrieves the kernel
8460          * value rather than trusting GUC's copy.
8461          */
8462         (void) pq_setkeepalivesidle(newval, MyProcPort);
8463 }
8464
8465 static const char *
8466 show_tcp_keepalives_idle(void)
8467 {
8468         /* See comments in assign_tcp_keepalives_idle */
8469         static char nbuf[16];
8470
8471         snprintf(nbuf, sizeof(nbuf), "%d", pq_getkeepalivesidle(MyProcPort));
8472         return nbuf;
8473 }
8474
8475 static void
8476 assign_tcp_keepalives_interval(int newval, void *extra)
8477 {
8478         /* See comments in assign_tcp_keepalives_idle */
8479         (void) pq_setkeepalivesinterval(newval, MyProcPort);
8480 }
8481
8482 static const char *
8483 show_tcp_keepalives_interval(void)
8484 {
8485         /* See comments in assign_tcp_keepalives_idle */
8486         static char nbuf[16];
8487
8488         snprintf(nbuf, sizeof(nbuf), "%d", pq_getkeepalivesinterval(MyProcPort));
8489         return nbuf;
8490 }
8491
8492 static void
8493 assign_tcp_keepalives_count(int newval, void *extra)
8494 {
8495         /* See comments in assign_tcp_keepalives_idle */
8496         (void) pq_setkeepalivescount(newval, MyProcPort);
8497 }
8498
8499 static const char *
8500 show_tcp_keepalives_count(void)
8501 {
8502         /* See comments in assign_tcp_keepalives_idle */
8503         static char nbuf[16];
8504
8505         snprintf(nbuf, sizeof(nbuf), "%d", pq_getkeepalivescount(MyProcPort));
8506         return nbuf;
8507 }
8508
8509 static bool
8510 check_maxconnections(int *newval, void **extra, GucSource source)
8511 {
8512         if (*newval + autovacuum_max_workers + 1 > MAX_BACKENDS)
8513                 return false;
8514         return true;
8515 }
8516
8517 static void
8518 assign_maxconnections(int newval, void *extra)
8519 {
8520         MaxBackends = newval + autovacuum_max_workers + 1;
8521 }
8522
8523 static bool
8524 check_autovacuum_max_workers(int *newval, void **extra, GucSource source)
8525 {
8526         if (MaxConnections + *newval + 1 > MAX_BACKENDS)
8527                 return false;
8528         return true;
8529 }
8530
8531 static void
8532 assign_autovacuum_max_workers(int newval, void *extra)
8533 {
8534         MaxBackends = MaxConnections + newval + 1;
8535 }
8536
8537 static bool
8538 check_effective_io_concurrency(int *newval, void **extra, GucSource source)
8539 {
8540 #ifdef USE_PREFETCH
8541         double          new_prefetch_pages = 0.0;
8542         int                     i;
8543
8544         /*----------
8545          * The user-visible GUC parameter is the number of drives (spindles),
8546          * which we need to translate to a number-of-pages-to-prefetch target.
8547          * The target value is stashed in *extra and then assigned to the actual
8548          * variable by assign_effective_io_concurrency.
8549          *
8550          * The expected number of prefetch pages needed to keep N drives busy is:
8551          *
8552          * drives |   I/O requests
8553          * -------+----------------
8554          *              1 |   1
8555          *              2 |   2/1 + 2/2 = 3
8556          *              3 |   3/1 + 3/2 + 3/3 = 5 1/2
8557          *              4 |   4/1 + 4/2 + 4/3 + 4/4 = 8 1/3
8558          *              n |   n * H(n)
8559          *
8560          * This is called the "coupon collector problem" and H(n) is called the
8561          * harmonic series.  This could be approximated by n * ln(n), but for
8562          * reasonable numbers of drives we might as well just compute the series.
8563          *
8564          * Alternatively we could set the target to the number of pages necessary
8565          * so that the expected number of active spindles is some arbitrary
8566          * percentage of the total.  This sounds the same but is actually slightly
8567          * different.  The result ends up being ln(1-P)/ln((n-1)/n) where P is
8568          * that desired fraction.
8569          *
8570          * Experimental results show that both of these formulas aren't aggressive
8571          * enough, but we don't really have any better proposals.
8572          *
8573          * Note that if *newval = 0 (disabled), we must set target = 0.
8574          *----------
8575          */
8576
8577         for (i = 1; i <= *newval; i++)
8578                 new_prefetch_pages += (double) *newval / (double) i;
8579
8580         /* This range check shouldn't fail, but let's be paranoid */
8581         if (new_prefetch_pages >= 0.0 && new_prefetch_pages < (double) INT_MAX)
8582         {
8583                 int                *myextra = (int *) guc_malloc(ERROR, sizeof(int));
8584
8585                 *myextra = (int) rint(new_prefetch_pages);
8586                 *extra = (void *) myextra;
8587
8588                 return true;
8589         }
8590         else
8591                 return false;
8592 #else
8593         return true;
8594 #endif   /* USE_PREFETCH */
8595 }
8596
8597 static void
8598 assign_effective_io_concurrency(int newval, void *extra)
8599 {
8600 #ifdef USE_PREFETCH
8601         target_prefetch_pages = *((int *) extra);
8602 #endif   /* USE_PREFETCH */
8603 }
8604
8605 static void
8606 assign_pgstat_temp_directory(const char *newval, void *extra)
8607 {
8608         /* check_canonical_path already canonicalized newval for us */
8609         char       *tname;
8610         char       *fname;
8611
8612         tname = guc_malloc(ERROR, strlen(newval) + 12);         /* /pgstat.tmp */
8613         sprintf(tname, "%s/pgstat.tmp", newval);
8614         fname = guc_malloc(ERROR, strlen(newval) + 13);         /* /pgstat.stat */
8615         sprintf(fname, "%s/pgstat.stat", newval);
8616
8617         if (pgstat_stat_tmpname)
8618                 free(pgstat_stat_tmpname);
8619         pgstat_stat_tmpname = tname;
8620         if (pgstat_stat_filename)
8621                 free(pgstat_stat_filename);
8622         pgstat_stat_filename = fname;
8623 }
8624
8625 static bool
8626 check_application_name(char **newval, void **extra, GucSource source)
8627 {
8628         /* Only allow clean ASCII chars in the application name */
8629         char       *p;
8630
8631         for (p = *newval; *p; p++)
8632         {
8633                 if (*p < 32 || *p > 126)
8634                         *p = '?';
8635         }
8636
8637         return true;
8638 }
8639
8640 static void
8641 assign_application_name(const char *newval, void *extra)
8642 {
8643         /* Update the pg_stat_activity view */
8644         pgstat_report_appname(newval);
8645 }
8646
8647 static const char *
8648 show_unix_socket_permissions(void)
8649 {
8650         static char buf[8];
8651
8652         snprintf(buf, sizeof(buf), "%04o", Unix_socket_permissions);
8653         return buf;
8654 }
8655
8656 static const char *
8657 show_log_file_mode(void)
8658 {
8659         static char buf[8];
8660
8661         snprintf(buf, sizeof(buf), "%04o", Log_file_mode);
8662         return buf;
8663 }
8664
8665 #include "guc-file.c"