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