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