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