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