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