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