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