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