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