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