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