Line data Source code
1 : /*--------------------------------------------------------------------
2 : * guc.c
3 : *
4 : * Support for grand unified configuration scheme, including SET
5 : * command, configuration file, and command line options.
6 : *
7 : * This file contains the generic option processing infrastructure.
8 : * guc_funcs.c contains SQL-level functionality, including SET/SHOW
9 : * commands and various system-administration SQL functions.
10 : * guc_tables.c contains the arrays that define all the built-in
11 : * GUC variables. Code that implements variable-specific behavior
12 : * is scattered around the system in check, assign, and show hooks.
13 : *
14 : * See src/backend/utils/misc/README for more information.
15 : *
16 : *
17 : * Copyright (c) 2000-2026, PostgreSQL Global Development Group
18 : * Written by Peter Eisentraut <peter_e@gmx.net>.
19 : *
20 : * IDENTIFICATION
21 : * src/backend/utils/misc/guc.c
22 : *
23 : *--------------------------------------------------------------------
24 : */
25 : #include "postgres.h"
26 :
27 : #include <limits.h>
28 : #include <math.h>
29 : #include <sys/stat.h>
30 : #include <unistd.h>
31 :
32 : #include "access/xact.h"
33 : #include "access/xlog.h"
34 : #include "catalog/objectaccess.h"
35 : #include "catalog/pg_authid.h"
36 : #include "catalog/pg_parameter_acl.h"
37 : #include "catalog/pg_type.h"
38 : #include "guc_internal.h"
39 : #include "libpq/pqformat.h"
40 : #include "libpq/protocol.h"
41 : #include "miscadmin.h"
42 : #include "parser/scansup.h"
43 : #include "port/pg_bitutils.h"
44 : #include "storage/fd.h"
45 : #include "storage/lwlock.h"
46 : #include "storage/shmem.h"
47 : #include "tcop/tcopprot.h"
48 : #include "utils/acl.h"
49 : #include "utils/builtins.h"
50 : #include "utils/conffiles.h"
51 : #include "utils/guc_tables.h"
52 : #include "utils/memutils.h"
53 : #include "utils/timestamp.h"
54 :
55 :
56 : #define CONFIG_FILENAME "postgresql.conf"
57 : #define HBA_FILENAME "pg_hba.conf"
58 : #define IDENT_FILENAME "pg_ident.conf"
59 : #define HOSTS_FILENAME "pg_hosts.conf"
60 :
61 : #ifdef EXEC_BACKEND
62 : #define CONFIG_EXEC_PARAMS "global/config_exec_params"
63 : #define CONFIG_EXEC_PARAMS_NEW "global/config_exec_params.new"
64 : #endif
65 :
66 : /*
67 : * Precision with which REAL type guc values are to be printed for GUC
68 : * serialization.
69 : */
70 : #define REALTYPE_PRECISION 17
71 :
72 : /*
73 : * Safe search path when executing code as the table owner, such as during
74 : * maintenance operations.
75 : */
76 : #define GUC_SAFE_SEARCH_PATH "pg_catalog, pg_temp"
77 :
78 : static int GUC_check_errcode_value;
79 :
80 : static List *reserved_class_prefix = NIL;
81 :
82 : /* global variables for check hook support */
83 : char *GUC_check_errmsg_string;
84 : char *GUC_check_errdetail_string;
85 : char *GUC_check_errhint_string;
86 :
87 :
88 : /*
89 : * Unit conversion tables.
90 : *
91 : * There are two tables, one for memory units, and another for time units.
92 : * For each supported conversion from one unit to another, we have an entry
93 : * in the table.
94 : *
95 : * To keep things simple, and to avoid possible roundoff error,
96 : * conversions are never chained. There needs to be a direct conversion
97 : * between all units (of the same type).
98 : *
99 : * The conversions for each base unit must be kept in order from greatest to
100 : * smallest human-friendly unit; convert_xxx_from_base_unit() rely on that.
101 : * (The order of the base-unit groups does not matter.)
102 : */
103 : #define MAX_UNIT_LEN 3 /* length of longest recognized unit string */
104 :
105 : typedef struct
106 : {
107 : char unit[MAX_UNIT_LEN + 1]; /* unit, as a string, like "kB" or
108 : * "min" */
109 : int base_unit; /* GUC_UNIT_XXX */
110 : double multiplier; /* Factor for converting unit -> base_unit */
111 : } unit_conversion;
112 :
113 : /* Ensure that the constants in the tables don't overflow or underflow */
114 : #if BLCKSZ < 1024 || BLCKSZ > (1024*1024)
115 : #error BLCKSZ must be between 1KB and 1MB
116 : #endif
117 : #if XLOG_BLCKSZ < 1024 || XLOG_BLCKSZ > (1024*1024)
118 : #error XLOG_BLCKSZ must be between 1KB and 1MB
119 : #endif
120 :
121 : static const char *const memory_units_hint = gettext_noop("Valid units for this parameter are \"B\", \"kB\", \"MB\", \"GB\", and \"TB\".");
122 :
123 : static const unit_conversion memory_unit_conversion_table[] =
124 : {
125 : {"TB", GUC_UNIT_BYTE, 1024.0 * 1024.0 * 1024.0 * 1024.0},
126 : {"GB", GUC_UNIT_BYTE, 1024.0 * 1024.0 * 1024.0},
127 : {"MB", GUC_UNIT_BYTE, 1024.0 * 1024.0},
128 : {"kB", GUC_UNIT_BYTE, 1024.0},
129 : {"B", GUC_UNIT_BYTE, 1.0},
130 :
131 : {"TB", GUC_UNIT_KB, 1024.0 * 1024.0 * 1024.0},
132 : {"GB", GUC_UNIT_KB, 1024.0 * 1024.0},
133 : {"MB", GUC_UNIT_KB, 1024.0},
134 : {"kB", GUC_UNIT_KB, 1.0},
135 : {"B", GUC_UNIT_KB, 1.0 / 1024.0},
136 :
137 : {"TB", GUC_UNIT_MB, 1024.0 * 1024.0},
138 : {"GB", GUC_UNIT_MB, 1024.0},
139 : {"MB", GUC_UNIT_MB, 1.0},
140 : {"kB", GUC_UNIT_MB, 1.0 / 1024.0},
141 : {"B", GUC_UNIT_MB, 1.0 / (1024.0 * 1024.0)},
142 :
143 : {"TB", GUC_UNIT_BLOCKS, (1024.0 * 1024.0 * 1024.0) / (BLCKSZ / 1024)},
144 : {"GB", GUC_UNIT_BLOCKS, (1024.0 * 1024.0) / (BLCKSZ / 1024)},
145 : {"MB", GUC_UNIT_BLOCKS, 1024.0 / (BLCKSZ / 1024)},
146 : {"kB", GUC_UNIT_BLOCKS, 1.0 / (BLCKSZ / 1024)},
147 : {"B", GUC_UNIT_BLOCKS, 1.0 / BLCKSZ},
148 :
149 : {"TB", GUC_UNIT_XBLOCKS, (1024.0 * 1024.0 * 1024.0) / (XLOG_BLCKSZ / 1024)},
150 : {"GB", GUC_UNIT_XBLOCKS, (1024.0 * 1024.0) / (XLOG_BLCKSZ / 1024)},
151 : {"MB", GUC_UNIT_XBLOCKS, 1024.0 / (XLOG_BLCKSZ / 1024)},
152 : {"kB", GUC_UNIT_XBLOCKS, 1.0 / (XLOG_BLCKSZ / 1024)},
153 : {"B", GUC_UNIT_XBLOCKS, 1.0 / XLOG_BLCKSZ},
154 :
155 : {""} /* end of table marker */
156 : };
157 :
158 : static const char *const time_units_hint = gettext_noop("Valid units for this parameter are \"us\", \"ms\", \"s\", \"min\", \"h\", and \"d\".");
159 :
160 : static const unit_conversion time_unit_conversion_table[] =
161 : {
162 : {"d", GUC_UNIT_MS, 1000 * 60 * 60 * 24},
163 : {"h", GUC_UNIT_MS, 1000 * 60 * 60},
164 : {"min", GUC_UNIT_MS, 1000 * 60},
165 : {"s", GUC_UNIT_MS, 1000},
166 : {"ms", GUC_UNIT_MS, 1},
167 : {"us", GUC_UNIT_MS, 1.0 / 1000},
168 :
169 : {"d", GUC_UNIT_S, 60 * 60 * 24},
170 : {"h", GUC_UNIT_S, 60 * 60},
171 : {"min", GUC_UNIT_S, 60},
172 : {"s", GUC_UNIT_S, 1},
173 : {"ms", GUC_UNIT_S, 1.0 / 1000},
174 : {"us", GUC_UNIT_S, 1.0 / (1000 * 1000)},
175 :
176 : {"d", GUC_UNIT_MIN, 60 * 24},
177 : {"h", GUC_UNIT_MIN, 60},
178 : {"min", GUC_UNIT_MIN, 1},
179 : {"s", GUC_UNIT_MIN, 1.0 / 60},
180 : {"ms", GUC_UNIT_MIN, 1.0 / (1000 * 60)},
181 : {"us", GUC_UNIT_MIN, 1.0 / (1000 * 1000 * 60)},
182 :
183 : {""} /* end of table marker */
184 : };
185 :
186 : /*
187 : * To allow continued support of obsolete names for GUC variables, we apply
188 : * the following mappings to any unrecognized name. Note that an old name
189 : * should be mapped to a new one only if the new variable has very similar
190 : * semantics to the old.
191 : */
192 : static const char *const map_old_guc_names[] = {
193 : "sort_mem", "work_mem",
194 : "vacuum_mem", "maintenance_work_mem",
195 : "ssl_ecdh_curve", "ssl_groups",
196 : NULL
197 : };
198 :
199 :
200 : /* Memory context holding all GUC-related data */
201 : static MemoryContext GUCMemoryContext;
202 :
203 : /*
204 : * We use a dynahash table to look up GUCs by name, or to iterate through
205 : * all the GUCs. The gucname field is redundant with gucvar->name, but
206 : * dynahash makes it too painful to not store the hash key separately.
207 : */
208 : typedef struct
209 : {
210 : const char *gucname; /* hash key */
211 : struct config_generic *gucvar; /* -> GUC's defining structure */
212 : } GUCHashEntry;
213 :
214 : static HTAB *guc_hashtab; /* entries are GUCHashEntrys */
215 :
216 : /*
217 : * In addition to the hash table, variables having certain properties are
218 : * linked into these lists, so that we can find them without scanning the
219 : * whole hash table. In most applications, only a small fraction of the
220 : * GUCs appear in these lists at any given time. The usage of the stack
221 : * and report lists is stylized enough that they can be slists, but the
222 : * nondef list has to be a dlist to avoid O(N) deletes in common cases.
223 : */
224 : static dlist_head guc_nondef_list; /* list of variables that have source
225 : * different from PGC_S_DEFAULT */
226 : static slist_head guc_stack_list; /* list of variables that have non-NULL
227 : * stack */
228 : static slist_head guc_report_list; /* list of variables that have the
229 : * GUC_NEEDS_REPORT bit set in status */
230 :
231 : static bool reporting_enabled; /* true to enable GUC_REPORT */
232 :
233 : static int GUCNestLevel = 0; /* 1 when in main transaction */
234 :
235 :
236 : static int guc_var_compare(const void *a, const void *b);
237 : static uint32 guc_name_hash(const void *key, Size keysize);
238 : static int guc_name_match(const void *key1, const void *key2, Size keysize);
239 : static void InitializeGUCOptionsFromEnvironment(void);
240 : static void InitializeOneGUCOption(struct config_generic *gconf);
241 : static void RemoveGUCFromLists(struct config_generic *gconf);
242 : static void set_guc_source(struct config_generic *gconf, GucSource newsource);
243 : static void pg_timezone_abbrev_initialize(void);
244 : static void push_old_value(struct config_generic *gconf, GucAction action);
245 : static void ReportGUCOption(struct config_generic *record);
246 : static void set_config_sourcefile(const char *name, char *sourcefile,
247 : int sourceline);
248 : static void reapply_stacked_values(struct config_generic *variable,
249 : struct config_generic *pHolder,
250 : GucStack *stack,
251 : const char *curvalue,
252 : GucContext curscontext, GucSource cursource,
253 : Oid cursrole);
254 : static void free_placeholder(struct config_generic *pHolder);
255 : static bool validate_option_array_item(const char *name, const char *value,
256 : bool skipIfNoPermissions);
257 : static void write_auto_conf_file(int fd, const char *filename, ConfigVariable *head);
258 : static void replace_auto_config_value(ConfigVariable **head_p, ConfigVariable **tail_p,
259 : const char *name, const char *value);
260 : static bool valid_custom_variable_name(const char *name);
261 : static bool assignable_custom_variable_name(const char *name, bool skip_errors,
262 : int elevel);
263 : static void do_serialize(char **destptr, Size *maxbytes,
264 : const char *fmt,...) pg_attribute_printf(3, 4);
265 : static bool call_bool_check_hook(const struct config_generic *conf, bool *newval,
266 : void **extra, GucSource source, int elevel);
267 : static bool call_int_check_hook(const struct config_generic *conf, int *newval,
268 : void **extra, GucSource source, int elevel);
269 : static bool call_real_check_hook(const struct config_generic *conf, double *newval,
270 : void **extra, GucSource source, int elevel);
271 : static bool call_string_check_hook(const struct config_generic *conf, char **newval,
272 : void **extra, GucSource source, int elevel);
273 : static bool call_enum_check_hook(const struct config_generic *conf, int *newval,
274 : void **extra, GucSource source, int elevel);
275 :
276 :
277 : /*
278 : * This function handles both actual config file (re)loads and execution of
279 : * show_all_file_settings() (i.e., the pg_file_settings view). In the latter
280 : * case we don't apply any of the settings, but we make all the usual validity
281 : * checks, and we return the ConfigVariable list so that it can be printed out
282 : * by show_all_file_settings().
283 : */
284 : ConfigVariable *
285 3419 : ProcessConfigFileInternal(GucContext context, bool applySettings, int elevel)
286 : {
287 3419 : bool error = false;
288 3419 : bool applying = false;
289 : const char *ConfFileWithError;
290 : ConfigVariable *head,
291 : *tail;
292 : HASH_SEQ_STATUS status;
293 : GUCHashEntry *hentry;
294 :
295 : /* Parse the main config file into a list of option names and values */
296 3419 : ConfFileWithError = ConfigFileName;
297 3419 : head = tail = NULL;
298 :
299 3419 : if (!ParseConfigFile(ConfigFileName, true,
300 : NULL, 0, CONF_FILE_START_DEPTH, elevel,
301 : &head, &tail))
302 : {
303 : /* Syntax error(s) detected in the file, so bail out */
304 0 : error = true;
305 0 : goto bail_out;
306 : }
307 :
308 : /*
309 : * Parse the PG_AUTOCONF_FILENAME file, if present, after the main file to
310 : * replace any parameters set by ALTER SYSTEM command. Because this file
311 : * is in the data directory, we can't read it until the DataDir has been
312 : * set.
313 : */
314 3419 : if (DataDir)
315 : {
316 2172 : if (!ParseConfigFile(PG_AUTOCONF_FILENAME, false,
317 : NULL, 0, CONF_FILE_START_DEPTH, elevel,
318 : &head, &tail))
319 : {
320 : /* Syntax error(s) detected in the file, so bail out */
321 0 : error = true;
322 0 : ConfFileWithError = PG_AUTOCONF_FILENAME;
323 0 : goto bail_out;
324 : }
325 : }
326 : else
327 : {
328 : /*
329 : * If DataDir is not set, the PG_AUTOCONF_FILENAME file cannot be
330 : * read. In this case, we don't want to accept any settings but
331 : * data_directory from postgresql.conf, because they might be
332 : * overwritten with settings in the PG_AUTOCONF_FILENAME file which
333 : * will be read later. OTOH, since data_directory isn't allowed in the
334 : * PG_AUTOCONF_FILENAME file, it will never be overwritten later.
335 : */
336 1247 : ConfigVariable *newlist = NULL;
337 :
338 : /*
339 : * Prune all items except the last "data_directory" from the list.
340 : */
341 34182 : for (ConfigVariable *item = head; item; item = item->next)
342 : {
343 32935 : if (!item->ignore &&
344 32935 : strcmp(item->name, "data_directory") == 0)
345 0 : newlist = item;
346 : }
347 :
348 1247 : if (newlist)
349 0 : newlist->next = NULL;
350 1247 : head = tail = newlist;
351 :
352 : /*
353 : * Quick exit if data_directory is not present in file.
354 : *
355 : * We need not do any further processing, in particular we don't set
356 : * PgReloadTime; that will be set soon by subsequent full loading of
357 : * the config file.
358 : */
359 1247 : if (head == NULL)
360 1247 : goto bail_out;
361 : }
362 :
363 : /*
364 : * Mark all extant GUC variables as not present in the config file. We
365 : * need this so that we can tell below which ones have been removed from
366 : * the file since we last processed it.
367 : */
368 2172 : hash_seq_init(&status, guc_hashtab);
369 918828 : while ((hentry = (GUCHashEntry *) hash_seq_search(&status)) != NULL)
370 : {
371 916656 : struct config_generic *gconf = hentry->gucvar;
372 :
373 916656 : gconf->status &= ~GUC_IS_IN_FILE;
374 : }
375 :
376 : /*
377 : * Check if all the supplied option names are valid, as an additional
378 : * quasi-syntactic check on the validity of the config file. It is
379 : * important that the postmaster and all backends agree on the results of
380 : * this phase, else we will have strange inconsistencies about which
381 : * processes accept a config file update and which don't. Hence, unknown
382 : * custom variable names have to be accepted without complaint. For the
383 : * same reason, we don't attempt to validate the options' values here.
384 : *
385 : * In addition, the GUC_IS_IN_FILE flag is set on each existing GUC
386 : * variable mentioned in the file; and we detect duplicate entries in the
387 : * file and mark the earlier occurrences as ignorable.
388 : */
389 67902 : for (ConfigVariable *item = head; item; item = item->next)
390 : {
391 : struct config_generic *record;
392 :
393 : /* Ignore anything already marked as ignorable */
394 65730 : if (item->ignore)
395 0 : continue;
396 :
397 : /*
398 : * Try to find the variable; but do not create a custom placeholder if
399 : * it's not there already.
400 : */
401 65730 : record = find_option(item->name, false, true, elevel);
402 :
403 65730 : if (record)
404 : {
405 : /* If it's already marked, then this is a duplicate entry */
406 65695 : if (record->status & GUC_IS_IN_FILE)
407 : {
408 : /*
409 : * Mark the earlier occurrence(s) as dead/ignorable. We could
410 : * avoid the O(N^2) behavior here with some additional state,
411 : * but it seems unlikely to be worth the trouble.
412 : */
413 224586 : for (ConfigVariable *pitem = head; pitem != item; pitem = pitem->next)
414 : {
415 217477 : if (!pitem->ignore &&
416 194291 : strcmp(pitem->name, item->name) == 0)
417 7109 : pitem->ignore = true;
418 : }
419 : }
420 : /* Now mark it as present in file */
421 65695 : record->status |= GUC_IS_IN_FILE;
422 : }
423 35 : else if (!valid_custom_variable_name(item->name))
424 : {
425 : /* Invalid non-custom variable, so complain */
426 1 : ereport(elevel,
427 : (errcode(ERRCODE_UNDEFINED_OBJECT),
428 : errmsg("unrecognized configuration parameter \"%s\" in file \"%s\" line %d",
429 : item->name,
430 : item->filename, item->sourceline)));
431 1 : item->errmsg = pstrdup("unrecognized configuration parameter");
432 1 : error = true;
433 1 : ConfFileWithError = item->filename;
434 : }
435 : }
436 :
437 : /*
438 : * If we've detected any errors so far, we don't want to risk applying any
439 : * changes.
440 : */
441 2172 : if (error)
442 1 : goto bail_out;
443 :
444 : /* Otherwise, set flag that we're beginning to apply changes */
445 2171 : applying = true;
446 :
447 : /*
448 : * Check for variables having been removed from the config file, and
449 : * revert their reset values (and perhaps also effective values) to the
450 : * boot-time defaults. If such a variable can't be changed after startup,
451 : * report that and continue.
452 : */
453 2171 : hash_seq_init(&status, guc_hashtab);
454 918405 : while ((hentry = (GUCHashEntry *) hash_seq_search(&status)) != NULL)
455 : {
456 916234 : struct config_generic *gconf = hentry->gucvar;
457 :
458 916234 : if (gconf->reset_source != PGC_S_FILE ||
459 28133 : (gconf->status & GUC_IS_IN_FILE))
460 916233 : continue;
461 1 : if (gconf->context < PGC_SIGHUP)
462 : {
463 : /* The removal can't be effective without a restart */
464 0 : gconf->status |= GUC_PENDING_RESTART;
465 0 : ereport(elevel,
466 : (errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
467 : errmsg("parameter \"%s\" cannot be changed without restarting the server",
468 : gconf->name)));
469 0 : record_config_file_error(psprintf("parameter \"%s\" cannot be changed without restarting the server",
470 : gconf->name),
471 : NULL, 0,
472 : &head, &tail);
473 0 : error = true;
474 0 : continue;
475 : }
476 :
477 : /* No more to do if we're just doing show_all_file_settings() */
478 1 : if (!applySettings)
479 0 : continue;
480 :
481 : /*
482 : * Reset any "file" sources to "default", else set_config_option will
483 : * not override those settings.
484 : */
485 1 : if (gconf->reset_source == PGC_S_FILE)
486 1 : gconf->reset_source = PGC_S_DEFAULT;
487 1 : if (gconf->source == PGC_S_FILE)
488 1 : set_guc_source(gconf, PGC_S_DEFAULT);
489 1 : for (GucStack *stack = gconf->stack; stack; stack = stack->prev)
490 : {
491 0 : if (stack->source == PGC_S_FILE)
492 0 : stack->source = PGC_S_DEFAULT;
493 : }
494 :
495 : /* Now we can re-apply the wired-in default (i.e., the boot_val) */
496 1 : if (set_config_option(gconf->name, NULL,
497 : context, PGC_S_DEFAULT,
498 : GUC_ACTION_SET, true, 0, false) > 0)
499 : {
500 : /* Log the change if appropriate */
501 1 : if (context == PGC_SIGHUP)
502 1 : ereport(elevel,
503 : (errmsg("parameter \"%s\" removed from configuration file, reset to default",
504 : gconf->name)));
505 : }
506 : }
507 :
508 : /*
509 : * Restore any variables determined by environment variables or
510 : * dynamically-computed defaults. This is a no-op except in the case
511 : * where one of these had been in the config file and is now removed.
512 : *
513 : * In particular, we *must not* do this during the postmaster's initial
514 : * loading of the file, since the timezone functions in particular should
515 : * be run only after initialization is complete.
516 : *
517 : * XXX this is an unmaintainable crock, because we have to know how to set
518 : * (or at least what to call to set) every non-PGC_INTERNAL variable that
519 : * could potentially have PGC_S_DYNAMIC_DEFAULT or PGC_S_ENV_VAR source.
520 : */
521 2171 : if (context == PGC_SIGHUP && applySettings)
522 : {
523 921 : InitializeGUCOptionsFromEnvironment();
524 921 : pg_timezone_abbrev_initialize();
525 : /* this selects SQL_ASCII in processes not connected to a database */
526 921 : SetConfigOption("client_encoding", GetDatabaseEncodingName(),
527 : PGC_BACKEND, PGC_S_DYNAMIC_DEFAULT);
528 : }
529 :
530 : /*
531 : * Now apply the values from the config file.
532 : */
533 67885 : for (ConfigVariable *item = head; item; item = item->next)
534 : {
535 65715 : char *pre_value = NULL;
536 : int scres;
537 :
538 : /* Ignore anything marked as ignorable */
539 65715 : if (item->ignore)
540 7109 : continue;
541 :
542 : /* In SIGHUP cases in the postmaster, we want to report changes */
543 58606 : if (context == PGC_SIGHUP && applySettings && !IsUnderPostmaster)
544 : {
545 4941 : const char *preval = GetConfigOption(item->name, true, false);
546 :
547 : /* If option doesn't exist yet or is NULL, treat as empty string */
548 4941 : if (!preval)
549 1 : preval = "";
550 : /* must dup, else might have dangling pointer below */
551 4941 : pre_value = pstrdup(preval);
552 : }
553 :
554 58606 : scres = set_config_option(item->name, item->value,
555 : context, PGC_S_FILE,
556 : GUC_ACTION_SET, applySettings, 0, false);
557 58605 : if (scres > 0)
558 : {
559 : /* variable was updated, so log the change if appropriate */
560 48020 : if (pre_value)
561 : {
562 3174 : const char *post_value = GetConfigOption(item->name, true, false);
563 :
564 3174 : if (!post_value)
565 0 : post_value = "";
566 3174 : if (strcmp(pre_value, post_value) != 0)
567 122 : ereport(elevel,
568 : (errmsg("parameter \"%s\" changed to \"%s\"",
569 : item->name, item->value)));
570 : }
571 48020 : item->applied = true;
572 : }
573 10585 : else if (scres == 0)
574 : {
575 0 : error = true;
576 0 : item->errmsg = pstrdup("setting could not be applied");
577 0 : ConfFileWithError = item->filename;
578 : }
579 : else
580 : {
581 : /* no error, but variable's active value was not changed */
582 10585 : item->applied = true;
583 : }
584 :
585 : /*
586 : * We should update source location unless there was an error, since
587 : * even if the active value didn't change, the reset value might have.
588 : * (In the postmaster, there won't be a difference, but it does matter
589 : * in backends.)
590 : */
591 58605 : if (scres != 0 && applySettings)
592 58496 : set_config_sourcefile(item->name, item->filename,
593 : item->sourceline);
594 :
595 58605 : if (pre_value)
596 4941 : pfree(pre_value);
597 : }
598 :
599 : /* Remember when we last successfully loaded the config file. */
600 2170 : if (applySettings)
601 2166 : PgReloadTime = GetCurrentTimestamp();
602 :
603 4 : bail_out:
604 3418 : if (error && applySettings)
605 : {
606 : /* During postmaster startup, any error is fatal */
607 1 : if (context == PGC_POSTMASTER)
608 1 : ereport(ERROR,
609 : (errcode(ERRCODE_CONFIG_FILE_ERROR),
610 : errmsg("configuration file \"%s\" contains errors",
611 : ConfFileWithError)));
612 0 : else if (applying)
613 0 : ereport(elevel,
614 : (errcode(ERRCODE_CONFIG_FILE_ERROR),
615 : errmsg("configuration file \"%s\" contains errors; unaffected changes were applied",
616 : ConfFileWithError)));
617 : else
618 0 : ereport(elevel,
619 : (errcode(ERRCODE_CONFIG_FILE_ERROR),
620 : errmsg("configuration file \"%s\" contains errors; no changes were applied",
621 : ConfFileWithError)));
622 : }
623 :
624 : /* Successful or otherwise, return the collected data list */
625 3417 : return head;
626 : }
627 :
628 :
629 : /*
630 : * Some infrastructure for GUC-related memory allocation
631 : *
632 : * These functions are generally modeled on libc's malloc/realloc/etc,
633 : * but any OOM issue is reported at the specified elevel.
634 : * (Thus, control returns only if that's less than ERROR.)
635 : */
636 : void *
637 1032695 : guc_malloc(int elevel, size_t size)
638 : {
639 : void *data;
640 :
641 1032695 : data = MemoryContextAllocExtended(GUCMemoryContext, size,
642 : MCXT_ALLOC_NO_OOM);
643 1032695 : if (unlikely(data == NULL))
644 0 : ereport(elevel,
645 : (errcode(ERRCODE_OUT_OF_MEMORY),
646 : errmsg("out of memory")));
647 1032695 : return data;
648 : }
649 :
650 : void *
651 0 : guc_realloc(int elevel, void *old, size_t size)
652 : {
653 : void *data;
654 :
655 0 : if (old != NULL)
656 : {
657 : /* This is to help catch old code that malloc's GUC data. */
658 : Assert(GetMemoryChunkContext(old) == GUCMemoryContext);
659 0 : data = repalloc_extended(old, size,
660 : MCXT_ALLOC_NO_OOM);
661 : }
662 : else
663 : {
664 : /* Like realloc(3), but not like repalloc(), we allow old == NULL. */
665 0 : data = MemoryContextAllocExtended(GUCMemoryContext, size,
666 : MCXT_ALLOC_NO_OOM);
667 : }
668 0 : if (unlikely(data == NULL))
669 0 : ereport(elevel,
670 : (errcode(ERRCODE_OUT_OF_MEMORY),
671 : errmsg("out of memory")));
672 0 : return data;
673 : }
674 :
675 : char *
676 872980 : guc_strdup(int elevel, const char *src)
677 : {
678 : char *data;
679 872980 : size_t len = strlen(src) + 1;
680 :
681 872980 : data = guc_malloc(elevel, len);
682 872980 : if (likely(data != NULL))
683 872980 : memcpy(data, src, len);
684 872980 : return data;
685 : }
686 :
687 : void
688 982344 : guc_free(void *ptr)
689 : {
690 : /*
691 : * Historically, GUC-related code has relied heavily on the ability to do
692 : * free(NULL), so we allow that here even though pfree() doesn't.
693 : */
694 982344 : if (ptr != NULL)
695 : {
696 : /* This is to help catch old code that malloc's GUC data. */
697 : Assert(GetMemoryChunkContext(ptr) == GUCMemoryContext);
698 595301 : pfree(ptr);
699 : }
700 982344 : }
701 :
702 :
703 : /*
704 : * Detect whether strval is referenced anywhere in a GUC string item
705 : */
706 : static bool
707 1350459 : string_field_used(struct config_generic *conf, char *strval)
708 : {
709 1350459 : if (strval == *(conf->_string.variable) ||
710 743594 : strval == conf->_string.reset_val ||
711 422536 : strval == conf->_string.boot_val)
712 927923 : return true;
713 661543 : for (GucStack *stack = conf->stack; stack; stack = stack->prev)
714 : {
715 294945 : if (strval == stack->prior.val.stringval ||
716 239011 : strval == stack->masked.val.stringval)
717 55938 : return true;
718 : }
719 366598 : return false;
720 : }
721 :
722 : /*
723 : * Support for assigning to a field of a string GUC item. Free the prior
724 : * value if it's not referenced anywhere else in the item (including stacked
725 : * states).
726 : */
727 : static void
728 1435396 : set_string_field(struct config_generic *conf, char **field, char *newval)
729 : {
730 1435396 : char *oldval = *field;
731 :
732 : /* Do the assignment */
733 1435396 : *field = newval;
734 :
735 : /* Free old value if it's not NULL and isn't referenced anymore */
736 1435396 : if (oldval && !string_field_used(conf, oldval))
737 363830 : guc_free(oldval);
738 1435396 : }
739 :
740 : /*
741 : * Detect whether an "extra" struct is referenced anywhere in a GUC item
742 : */
743 : static bool
744 254633 : extra_field_used(struct config_generic *gconf, void *extra)
745 : {
746 254633 : if (extra == gconf->extra)
747 101818 : return true;
748 152815 : if (extra == gconf->reset_extra)
749 74335 : return true;
750 87967 : for (GucStack *stack = gconf->stack; stack; stack = stack->prev)
751 : {
752 14391 : if (extra == stack->prior.extra ||
753 9491 : extra == stack->masked.extra)
754 4904 : return true;
755 : }
756 :
757 73576 : return false;
758 : }
759 :
760 : /*
761 : * Support for assigning to an "extra" field of a GUC item. Free the prior
762 : * value if it's not referenced anywhere else in the item (including stacked
763 : * states).
764 : */
765 : static void
766 2344382 : set_extra_field(struct config_generic *gconf, void **field, void *newval)
767 : {
768 2344382 : void *oldval = *field;
769 :
770 : /* Do the assignment */
771 2344382 : *field = newval;
772 :
773 : /* Free old value if it's not NULL and isn't referenced anymore */
774 2344382 : if (oldval && !extra_field_used(gconf, oldval))
775 73308 : guc_free(oldval);
776 2344382 : }
777 :
778 : /*
779 : * Support for copying a variable's active value into a stack entry.
780 : * The "extra" field associated with the active value is copied, too.
781 : *
782 : * NB: be sure stringval and extra fields of a new stack entry are
783 : * initialized to NULL before this is used, else we'll try to guc_free() them.
784 : */
785 : static void
786 352750 : set_stack_value(struct config_generic *gconf, config_var_value *val)
787 : {
788 352750 : switch (gconf->vartype)
789 : {
790 55862 : case PGC_BOOL:
791 55862 : val->val.boolval = *gconf->_bool.variable;
792 55862 : break;
793 13653 : case PGC_INT:
794 13653 : val->val.intval = *gconf->_int.variable;
795 13653 : break;
796 5802 : case PGC_REAL:
797 5802 : val->val.realval = *gconf->_real.variable;
798 5802 : break;
799 222251 : case PGC_STRING:
800 222251 : set_string_field(gconf, &(val->val.stringval), *gconf->_string.variable);
801 222251 : break;
802 55182 : case PGC_ENUM:
803 55182 : val->val.enumval = *gconf->_enum.variable;
804 55182 : break;
805 : }
806 352750 : set_extra_field(gconf, &(val->extra), gconf->extra);
807 352750 : }
808 :
809 : /*
810 : * Support for discarding a no-longer-needed value in a stack entry.
811 : * The "extra" field associated with the stack entry is cleared, too.
812 : */
813 : static void
814 37961 : discard_stack_value(struct config_generic *gconf, config_var_value *val)
815 : {
816 37961 : switch (gconf->vartype)
817 : {
818 24966 : case PGC_BOOL:
819 : case PGC_INT:
820 : case PGC_REAL:
821 : case PGC_ENUM:
822 : /* no need to do anything */
823 24966 : break;
824 12995 : case PGC_STRING:
825 12995 : set_string_field(gconf,
826 : &(val->val.stringval),
827 : NULL);
828 12995 : break;
829 : }
830 37961 : set_extra_field(gconf, &(val->extra), NULL);
831 37961 : }
832 :
833 :
834 : /*
835 : * Fetch a palloc'd, sorted array of GUC struct pointers
836 : *
837 : * The array length is returned into *num_vars.
838 : */
839 : struct config_generic **
840 1952 : get_guc_variables(int *num_vars)
841 : {
842 : struct config_generic **result;
843 : HASH_SEQ_STATUS status;
844 : GUCHashEntry *hentry;
845 : int i;
846 :
847 1952 : *num_vars = hash_get_num_entries(guc_hashtab);
848 1952 : result = palloc_array(struct config_generic *, *num_vars);
849 :
850 : /* Extract pointers from the hash table */
851 1952 : i = 0;
852 1952 : hash_seq_init(&status, guc_hashtab);
853 833653 : while ((hentry = (GUCHashEntry *) hash_seq_search(&status)) != NULL)
854 831701 : result[i++] = hentry->gucvar;
855 : Assert(i == *num_vars);
856 :
857 : /* Sort by name */
858 1952 : qsort(result, *num_vars,
859 : sizeof(struct config_generic *), guc_var_compare);
860 :
861 1952 : return result;
862 : }
863 :
864 :
865 : /*
866 : * Build the GUC hash table. This is split out so that help_config.c can
867 : * extract all the variables without running all of InitializeGUCOptions.
868 : * It's not meant for use anyplace else.
869 : */
870 : void
871 1275 : build_guc_variables(void)
872 : {
873 : int size_vars;
874 1275 : int num_vars = 0;
875 : HASHCTL hash_ctl;
876 : GUCHashEntry *hentry;
877 : bool found;
878 :
879 : /*
880 : * Create the memory context that will hold all GUC-related data.
881 : */
882 : Assert(GUCMemoryContext == NULL);
883 1275 : GUCMemoryContext = AllocSetContextCreate(TopMemoryContext,
884 : "GUCMemoryContext",
885 : ALLOCSET_DEFAULT_SIZES);
886 :
887 : /*
888 : * Count all the built-in variables.
889 : */
890 539325 : for (int i = 0; ConfigureNames[i].name; i++)
891 538050 : num_vars++;
892 :
893 : /*
894 : * Create hash table with 20% slack
895 : */
896 1275 : size_vars = num_vars + num_vars / 4;
897 :
898 1275 : hash_ctl.keysize = sizeof(char *);
899 1275 : hash_ctl.entrysize = sizeof(GUCHashEntry);
900 1275 : hash_ctl.hash = guc_name_hash;
901 1275 : hash_ctl.match = guc_name_match;
902 1275 : hash_ctl.hcxt = GUCMemoryContext;
903 1275 : guc_hashtab = hash_create("GUC hash table",
904 : size_vars,
905 : &hash_ctl,
906 : HASH_ELEM | HASH_FUNCTION | HASH_COMPARE | HASH_CONTEXT);
907 :
908 539325 : for (int i = 0; ConfigureNames[i].name; i++)
909 : {
910 538050 : struct config_generic *gucvar = &ConfigureNames[i];
911 :
912 538050 : hentry = (GUCHashEntry *) hash_search(guc_hashtab,
913 538050 : &gucvar->name,
914 : HASH_ENTER,
915 : &found);
916 : Assert(!found);
917 538050 : hentry->gucvar = gucvar;
918 : }
919 :
920 : Assert(num_vars == hash_get_num_entries(guc_hashtab));
921 1275 : }
922 :
923 : /*
924 : * Add a new GUC variable to the hash of known variables. The
925 : * hash is expanded if needed.
926 : */
927 : static bool
928 12314 : add_guc_variable(struct config_generic *var, int elevel)
929 : {
930 : GUCHashEntry *hentry;
931 : bool found;
932 :
933 12314 : hentry = (GUCHashEntry *) hash_search(guc_hashtab,
934 12314 : &var->name,
935 : HASH_ENTER_NULL,
936 : &found);
937 12314 : if (unlikely(hentry == NULL))
938 : {
939 0 : ereport(elevel,
940 : (errcode(ERRCODE_OUT_OF_MEMORY),
941 : errmsg("out of memory")));
942 0 : return false; /* out of memory */
943 : }
944 : Assert(!found);
945 12314 : hentry->gucvar = var;
946 12314 : return true;
947 : }
948 :
949 : /*
950 : * Decide whether a proposed custom variable name is allowed.
951 : *
952 : * It must be two or more identifiers separated by dots, where the rules
953 : * for what is an identifier agree with scan.l. (If you change this rule,
954 : * adjust the errdetail in assignable_custom_variable_name().)
955 : */
956 : static bool
957 149 : valid_custom_variable_name(const char *name)
958 : {
959 149 : bool saw_sep = false;
960 149 : bool name_start = true;
961 :
962 2928 : for (const char *p = name; *p; p++)
963 : {
964 2787 : if (*p == GUC_QUALIFIER_SEPARATOR)
965 : {
966 137 : if (name_start)
967 0 : return false; /* empty name component */
968 137 : saw_sep = true;
969 137 : name_start = true;
970 : }
971 2650 : else if (strchr("ABCDEFGHIJKLMNOPQRSTUVWXYZ"
972 2650 : "abcdefghijklmnopqrstuvwxyz_", *p) != NULL ||
973 10 : IS_HIGHBIT_SET(*p))
974 : {
975 : /* okay as first or non-first character */
976 2640 : name_start = false;
977 : }
978 10 : else if (!name_start && strchr("0123456789$", *p) != NULL)
979 : /* okay as non-first character */ ;
980 : else
981 8 : return false;
982 : }
983 141 : if (name_start)
984 0 : return false; /* empty name component */
985 : /* OK if we found at least one separator */
986 141 : return saw_sep;
987 : }
988 :
989 : /*
990 : * Decide whether an unrecognized variable name is allowed to be SET.
991 : *
992 : * It must pass the syntactic rules of valid_custom_variable_name(),
993 : * and it must not be in any namespace already reserved by an extension.
994 : * (We make this separate from valid_custom_variable_name() because we don't
995 : * apply the reserved-namespace test when reading configuration files.)
996 : *
997 : * If valid, return true. Otherwise, return false if skip_errors is true,
998 : * else throw a suitable error at the specified elevel (and return false
999 : * if that's less than ERROR).
1000 : */
1001 : static bool
1002 123 : assignable_custom_variable_name(const char *name, bool skip_errors, int elevel)
1003 : {
1004 : /* If there's no separator, it can't be a custom variable */
1005 123 : const char *sep = strchr(name, GUC_QUALIFIER_SEPARATOR);
1006 :
1007 123 : if (sep != NULL)
1008 : {
1009 91 : size_t classLen = sep - name;
1010 : ListCell *lc;
1011 :
1012 : /* The name must be syntactically acceptable ... */
1013 91 : if (!valid_custom_variable_name(name))
1014 : {
1015 8 : if (!skip_errors)
1016 8 : ereport(elevel,
1017 : (errcode(ERRCODE_INVALID_NAME),
1018 : errmsg("invalid configuration parameter name \"%s\"",
1019 : name),
1020 : errdetail("Custom parameter names must be two or more simple identifiers separated by dots.")));
1021 0 : return false;
1022 : }
1023 : /* ... and it must not match any previously-reserved prefix */
1024 105 : foreach(lc, reserved_class_prefix)
1025 : {
1026 29 : const char *rcprefix = lfirst(lc);
1027 :
1028 29 : if (strlen(rcprefix) == classLen &&
1029 7 : strncmp(name, rcprefix, classLen) == 0)
1030 : {
1031 7 : if (!skip_errors)
1032 4 : ereport(elevel,
1033 : (errcode(ERRCODE_INVALID_NAME),
1034 : errmsg("invalid configuration parameter name \"%s\"",
1035 : name),
1036 : errdetail("\"%s\" is a reserved prefix.",
1037 : rcprefix)));
1038 3 : return false;
1039 : }
1040 : }
1041 : /* OK to create it */
1042 76 : return true;
1043 : }
1044 :
1045 : /* Unrecognized single-part name */
1046 32 : if (!skip_errors)
1047 32 : ereport(elevel,
1048 : (errcode(ERRCODE_UNDEFINED_OBJECT),
1049 : errmsg("unrecognized configuration parameter \"%s\"",
1050 : name)));
1051 0 : return false;
1052 : }
1053 :
1054 : /*
1055 : * Create and add a placeholder variable for a custom variable name.
1056 : */
1057 : static struct config_generic *
1058 69 : add_placeholder_variable(const char *name, int elevel)
1059 : {
1060 69 : size_t sz = sizeof(struct config_generic) + sizeof(char *);
1061 : struct config_generic *var;
1062 :
1063 69 : var = (struct config_generic *) guc_malloc(elevel, sz);
1064 69 : if (var == NULL)
1065 0 : return NULL;
1066 69 : memset(var, 0, sz);
1067 :
1068 69 : var->name = guc_strdup(elevel, name);
1069 69 : if (var->name == NULL)
1070 : {
1071 0 : guc_free(var);
1072 0 : return NULL;
1073 : }
1074 :
1075 69 : var->context = PGC_USERSET;
1076 69 : var->group = CUSTOM_OPTIONS;
1077 69 : var->short_desc = "GUC placeholder variable";
1078 69 : var->flags = GUC_NO_SHOW_ALL | GUC_NOT_IN_SAMPLE | GUC_CUSTOM_PLACEHOLDER;
1079 69 : var->vartype = PGC_STRING;
1080 :
1081 : /*
1082 : * The char* is allocated at the end of the struct since we have no
1083 : * 'static' place to point to. Note that the current value, as well as
1084 : * the boot and reset values, start out NULL.
1085 : */
1086 69 : var->_string.variable = (char **) (var + 1);
1087 :
1088 69 : if (!add_guc_variable(var, elevel))
1089 : {
1090 0 : guc_free(unconstify(char *, var->name));
1091 0 : guc_free(var);
1092 0 : return NULL;
1093 : }
1094 :
1095 69 : return var;
1096 : }
1097 :
1098 : /*
1099 : * Look up option "name". If it exists, return a pointer to its record.
1100 : * Otherwise, if create_placeholders is true and name is a valid-looking
1101 : * custom variable name, we'll create and return a placeholder record.
1102 : * Otherwise, if skip_errors is true, then we silently return NULL for
1103 : * an unrecognized or invalid name. Otherwise, the error is reported at
1104 : * error level elevel (and we return NULL if that's less than ERROR).
1105 : *
1106 : * Note: internal errors, primarily out-of-memory, draw an elevel-level
1107 : * report and NULL return regardless of skip_errors. Hence, callers must
1108 : * handle a NULL return whenever elevel < ERROR, but they should not need
1109 : * to emit any additional error message. (In practice, internal errors
1110 : * can only happen when create_placeholders is true, so callers passing
1111 : * false need not think terribly hard about this.)
1112 : */
1113 : struct config_generic *
1114 906398 : find_option(const char *name, bool create_placeholders, bool skip_errors,
1115 : int elevel)
1116 : {
1117 : GUCHashEntry *hentry;
1118 :
1119 : Assert(name);
1120 :
1121 : /* Look it up using the hash table. */
1122 906398 : hentry = (GUCHashEntry *) hash_search(guc_hashtab,
1123 : &name,
1124 : HASH_FIND,
1125 : NULL);
1126 906398 : if (hentry)
1127 906161 : return hentry->gucvar;
1128 :
1129 : /*
1130 : * See if the name is an obsolete name for a variable. We assume that the
1131 : * set of supported old names is short enough that a brute-force search is
1132 : * the best way.
1133 : */
1134 948 : for (int i = 0; map_old_guc_names[i] != NULL; i += 2)
1135 : {
1136 711 : if (guc_name_compare(name, map_old_guc_names[i]) == 0)
1137 0 : return find_option(map_old_guc_names[i + 1], false,
1138 : skip_errors, elevel);
1139 : }
1140 :
1141 237 : if (create_placeholders)
1142 : {
1143 : /*
1144 : * Check if the name is valid, and if so, add a placeholder.
1145 : */
1146 115 : if (assignable_custom_variable_name(name, skip_errors, elevel))
1147 69 : return add_placeholder_variable(name, elevel);
1148 : else
1149 3 : return NULL; /* error message, if any, already emitted */
1150 : }
1151 :
1152 : /* Unknown name and we're not supposed to make a placeholder */
1153 122 : if (!skip_errors)
1154 25 : ereport(elevel,
1155 : (errcode(ERRCODE_UNDEFINED_OBJECT),
1156 : errmsg("unrecognized configuration parameter \"%s\"",
1157 : name)));
1158 97 : return NULL;
1159 : }
1160 :
1161 :
1162 : /*
1163 : * comparator for qsorting an array of GUC pointers
1164 : */
1165 : static int
1166 7450652 : guc_var_compare(const void *a, const void *b)
1167 : {
1168 7450652 : const struct config_generic *ca = *(const struct config_generic *const *) a;
1169 7450652 : const struct config_generic *cb = *(const struct config_generic *const *) b;
1170 :
1171 7450652 : return guc_name_compare(ca->name, cb->name);
1172 : }
1173 :
1174 : /*
1175 : * the bare comparison function for GUC names
1176 : */
1177 : int
1178 8775154 : guc_name_compare(const char *namea, const char *nameb)
1179 : {
1180 : /*
1181 : * The temptation to use strcasecmp() here must be resisted, because the
1182 : * hash mapping has to remain stable across setlocale() calls. So, build
1183 : * our own with a simple ASCII-only downcasing.
1184 : */
1185 40579863 : while (*namea && *nameb)
1186 : {
1187 39607391 : char cha = *namea++;
1188 39607391 : char chb = *nameb++;
1189 :
1190 39607391 : if (cha >= 'A' && cha <= 'Z')
1191 138157 : cha += 'a' - 'A';
1192 39607391 : if (chb >= 'A' && chb <= 'Z')
1193 47204 : chb += 'a' - 'A';
1194 39607391 : if (cha != chb)
1195 7802682 : return cha - chb;
1196 : }
1197 972472 : if (*namea)
1198 38935 : return 1; /* a is longer */
1199 933537 : if (*nameb)
1200 27040 : return -1; /* b is longer */
1201 906497 : return 0;
1202 : }
1203 :
1204 : /*
1205 : * Hash function that's compatible with guc_name_compare
1206 : */
1207 : static uint32
1208 1469082 : guc_name_hash(const void *key, Size keysize)
1209 : {
1210 1469082 : uint32 result = 0;
1211 1469082 : const char *name = *(const char *const *) key;
1212 :
1213 26624283 : while (*name)
1214 : {
1215 25155201 : char ch = *name++;
1216 :
1217 : /* Case-fold in the same way as guc_name_compare */
1218 25155201 : if (ch >= 'A' && ch <= 'Z')
1219 28048 : ch += 'a' - 'A';
1220 :
1221 : /* Merge into hash ... not very bright, but it needn't be */
1222 25155201 : result = pg_rotate_left32(result, 5);
1223 25155201 : result ^= (uint32) ch;
1224 : }
1225 1469082 : return result;
1226 : }
1227 :
1228 : /*
1229 : * Dynahash match function to use in guc_hashtab
1230 : */
1231 : static int
1232 906236 : guc_name_match(const void *key1, const void *key2, Size keysize)
1233 : {
1234 906236 : const char *name1 = *(const char *const *) key1;
1235 906236 : const char *name2 = *(const char *const *) key2;
1236 :
1237 906236 : return guc_name_compare(name1, name2);
1238 : }
1239 :
1240 :
1241 : /*
1242 : * Convert a GUC name to the form that should be used in pg_parameter_acl.
1243 : *
1244 : * We need to canonicalize entries since, for example, case should not be
1245 : * significant. In addition, we apply the map_old_guc_names[] mapping so that
1246 : * any obsolete names will be converted when stored in a new PG version.
1247 : * Note however that this function does not verify legality of the name.
1248 : *
1249 : * The result is a palloc'd string.
1250 : */
1251 : char *
1252 176 : convert_GUC_name_for_parameter_acl(const char *name)
1253 : {
1254 : char *result;
1255 :
1256 : /* Apply old-GUC-name mapping. */
1257 704 : for (int i = 0; map_old_guc_names[i] != NULL; i += 2)
1258 : {
1259 528 : if (guc_name_compare(name, map_old_guc_names[i]) == 0)
1260 : {
1261 0 : name = map_old_guc_names[i + 1];
1262 0 : break;
1263 : }
1264 : }
1265 :
1266 : /* Apply case-folding that matches guc_name_compare(). */
1267 176 : result = pstrdup(name);
1268 2864 : for (char *ptr = result; *ptr != '\0'; ptr++)
1269 : {
1270 2688 : char ch = *ptr;
1271 :
1272 2688 : if (ch >= 'A' && ch <= 'Z')
1273 : {
1274 6 : ch += 'a' - 'A';
1275 6 : *ptr = ch;
1276 : }
1277 : }
1278 :
1279 176 : return result;
1280 : }
1281 :
1282 : /*
1283 : * Check whether we should allow creation of a pg_parameter_acl entry
1284 : * for the given name. (This can be applied either before or after
1285 : * canonicalizing it.) Throws error if not.
1286 : */
1287 : void
1288 34 : check_GUC_name_for_parameter_acl(const char *name)
1289 : {
1290 : /* OK if the GUC exists. */
1291 34 : if (find_option(name, false, true, DEBUG5) != NULL)
1292 27 : return;
1293 : /* Otherwise, it'd better be a valid custom GUC name. */
1294 7 : (void) assignable_custom_variable_name(name, false, ERROR);
1295 : }
1296 :
1297 : /*
1298 : * Routine in charge of checking various states of a GUC.
1299 : *
1300 : * This performs two sanity checks. First, it checks that the initial
1301 : * value of a GUC is the same when declared and when loaded to prevent
1302 : * anybody looking at the C declarations of these GUCs from being fooled by
1303 : * mismatched values. Second, it checks for incorrect flag combinations.
1304 : *
1305 : * The following validation rules apply for the values:
1306 : * bool - can be false, otherwise must be same as the boot_val
1307 : * int - can be 0, otherwise must be same as the boot_val
1308 : * real - can be 0.0, otherwise must be same as the boot_val
1309 : * string - can be NULL, otherwise must be strcmp equal to the boot_val
1310 : * enum - must be same as the boot_val
1311 : */
1312 : #ifdef USE_ASSERT_CHECKING
1313 : static bool
1314 : check_GUC_init(const struct config_generic *gconf)
1315 : {
1316 : /* Checks on values */
1317 : switch (gconf->vartype)
1318 : {
1319 : case PGC_BOOL:
1320 : {
1321 : const struct config_bool *conf = &gconf->_bool;
1322 :
1323 : if (*conf->variable && !conf->boot_val)
1324 : {
1325 : elog(LOG, "GUC (PGC_BOOL) %s, boot_val=%d, C-var=%d",
1326 : gconf->name, conf->boot_val, *conf->variable);
1327 : return false;
1328 : }
1329 : break;
1330 : }
1331 : case PGC_INT:
1332 : {
1333 : const struct config_int *conf = &gconf->_int;
1334 :
1335 : if (*conf->variable != 0 && *conf->variable != conf->boot_val)
1336 : {
1337 : elog(LOG, "GUC (PGC_INT) %s, boot_val=%d, C-var=%d",
1338 : gconf->name, conf->boot_val, *conf->variable);
1339 : return false;
1340 : }
1341 : break;
1342 : }
1343 : case PGC_REAL:
1344 : {
1345 : const struct config_real *conf = &gconf->_real;
1346 :
1347 : if (*conf->variable != 0.0 && *conf->variable != conf->boot_val)
1348 : {
1349 : elog(LOG, "GUC (PGC_REAL) %s, boot_val=%g, C-var=%g",
1350 : gconf->name, conf->boot_val, *conf->variable);
1351 : return false;
1352 : }
1353 : break;
1354 : }
1355 : case PGC_STRING:
1356 : {
1357 : const struct config_string *conf = &gconf->_string;
1358 :
1359 : if (*conf->variable != NULL &&
1360 : (conf->boot_val == NULL ||
1361 : strcmp(*conf->variable, conf->boot_val) != 0))
1362 : {
1363 : elog(LOG, "GUC (PGC_STRING) %s, boot_val=%s, C-var=%s",
1364 : gconf->name, conf->boot_val ? conf->boot_val : "<null>", *conf->variable);
1365 : return false;
1366 : }
1367 : break;
1368 : }
1369 : case PGC_ENUM:
1370 : {
1371 : const struct config_enum *conf = &gconf->_enum;
1372 :
1373 : if (*conf->variable != conf->boot_val)
1374 : {
1375 : elog(LOG, "GUC (PGC_ENUM) %s, boot_val=%d, C-var=%d",
1376 : gconf->name, conf->boot_val, *conf->variable);
1377 : return false;
1378 : }
1379 : break;
1380 : }
1381 : }
1382 :
1383 : /* Flag combinations */
1384 :
1385 : /*
1386 : * GUC_NO_SHOW_ALL requires GUC_NOT_IN_SAMPLE, as a parameter not part of
1387 : * SHOW ALL should not be hidden in postgresql.conf.sample.
1388 : */
1389 : if ((gconf->flags & GUC_NO_SHOW_ALL) &&
1390 : !(gconf->flags & GUC_NOT_IN_SAMPLE))
1391 : {
1392 : elog(LOG, "GUC %s flags: NO_SHOW_ALL and !NOT_IN_SAMPLE",
1393 : gconf->name);
1394 : return false;
1395 : }
1396 :
1397 : return true;
1398 : }
1399 : #endif
1400 :
1401 : /*
1402 : * Initialize GUC options during program startup.
1403 : *
1404 : * Note that we cannot read the config file yet, since we have not yet
1405 : * processed command-line switches.
1406 : */
1407 : void
1408 1275 : InitializeGUCOptions(void)
1409 : {
1410 : HASH_SEQ_STATUS status;
1411 : GUCHashEntry *hentry;
1412 :
1413 : /*
1414 : * Before log_line_prefix could possibly receive a nonempty setting, make
1415 : * sure that timezone processing is minimally alive (see elog.c).
1416 : */
1417 1275 : pg_timezone_initialize();
1418 :
1419 : /*
1420 : * Create GUCMemoryContext and build hash table of all GUC variables.
1421 : */
1422 1275 : build_guc_variables();
1423 :
1424 : /*
1425 : * Load all variables with their compiled-in defaults, and initialize
1426 : * status fields as needed.
1427 : */
1428 1275 : hash_seq_init(&status, guc_hashtab);
1429 539325 : while ((hentry = (GUCHashEntry *) hash_seq_search(&status)) != NULL)
1430 : {
1431 : /* Check mapping between initial and default value */
1432 : Assert(check_GUC_init(hentry->gucvar));
1433 :
1434 538050 : InitializeOneGUCOption(hentry->gucvar);
1435 : }
1436 :
1437 1275 : reporting_enabled = false;
1438 :
1439 : /*
1440 : * Prevent any attempt to override the transaction modes from
1441 : * non-interactive sources.
1442 : */
1443 1275 : SetConfigOption("transaction_isolation", "read committed",
1444 : PGC_POSTMASTER, PGC_S_OVERRIDE);
1445 1275 : SetConfigOption("transaction_read_only", "no",
1446 : PGC_POSTMASTER, PGC_S_OVERRIDE);
1447 1275 : SetConfigOption("transaction_deferrable", "no",
1448 : PGC_POSTMASTER, PGC_S_OVERRIDE);
1449 :
1450 : /*
1451 : * For historical reasons, some GUC parameters can receive defaults from
1452 : * environment variables. Process those settings.
1453 : */
1454 1275 : InitializeGUCOptionsFromEnvironment();
1455 1275 : }
1456 :
1457 : /*
1458 : * Assign any GUC values that can come from the server's environment.
1459 : *
1460 : * This is called from InitializeGUCOptions, and also from ProcessConfigFile
1461 : * to deal with the possibility that a setting has been removed from
1462 : * postgresql.conf and should now get a value from the environment.
1463 : * (The latter is a kludge that should probably go away someday; if so,
1464 : * fold this back into InitializeGUCOptions.)
1465 : */
1466 : static void
1467 2196 : InitializeGUCOptionsFromEnvironment(void)
1468 : {
1469 : char *env;
1470 : ssize_t stack_rlimit;
1471 :
1472 2196 : env = getenv("PGPORT");
1473 2196 : if (env != NULL)
1474 2005 : SetConfigOption("port", env, PGC_POSTMASTER, PGC_S_ENV_VAR);
1475 :
1476 2196 : env = getenv("PGDATESTYLE");
1477 2196 : if (env != NULL)
1478 121 : SetConfigOption("datestyle", env, PGC_POSTMASTER, PGC_S_ENV_VAR);
1479 :
1480 2196 : env = getenv("PGCLIENTENCODING");
1481 2196 : if (env != NULL)
1482 15 : SetConfigOption("client_encoding", env, PGC_POSTMASTER, PGC_S_ENV_VAR);
1483 :
1484 : /*
1485 : * rlimit isn't exactly an "environment variable", but it behaves about
1486 : * the same. If we can identify the platform stack depth rlimit, increase
1487 : * default stack depth setting up to whatever is safe (but at most 2MB).
1488 : * Report the value's source as PGC_S_DYNAMIC_DEFAULT if it's 2MB, or as
1489 : * PGC_S_ENV_VAR if it's reflecting the rlimit limit.
1490 : */
1491 2196 : stack_rlimit = get_stack_depth_rlimit();
1492 2196 : if (stack_rlimit > 0)
1493 : {
1494 2196 : ssize_t new_limit = (stack_rlimit - STACK_DEPTH_SLOP) / 1024;
1495 :
1496 2196 : if (new_limit > 100)
1497 : {
1498 : GucSource source;
1499 : char limbuf[16];
1500 :
1501 2196 : if (new_limit < 2048)
1502 0 : source = PGC_S_ENV_VAR;
1503 : else
1504 : {
1505 2196 : new_limit = 2048;
1506 2196 : source = PGC_S_DYNAMIC_DEFAULT;
1507 : }
1508 2196 : snprintf(limbuf, sizeof(limbuf), "%zd", new_limit);
1509 2196 : SetConfigOption("max_stack_depth", limbuf,
1510 : PGC_POSTMASTER, source);
1511 : }
1512 : }
1513 2196 : }
1514 :
1515 : /*
1516 : * Initialize one GUC option variable to its compiled-in default.
1517 : *
1518 : * Note: the reason for calling check_hooks is not that we think the boot_val
1519 : * might fail, but that the hooks might wish to compute an "extra" struct.
1520 : */
1521 : static void
1522 600068 : InitializeOneGUCOption(struct config_generic *gconf)
1523 : {
1524 600068 : void *extra = NULL;
1525 :
1526 600068 : gconf->status = 0;
1527 600068 : gconf->source = PGC_S_DEFAULT;
1528 600068 : gconf->reset_source = PGC_S_DEFAULT;
1529 600068 : gconf->scontext = PGC_INTERNAL;
1530 600068 : gconf->reset_scontext = PGC_INTERNAL;
1531 600068 : gconf->srole = BOOTSTRAP_SUPERUSERID;
1532 600068 : gconf->reset_srole = BOOTSTRAP_SUPERUSERID;
1533 600068 : gconf->stack = NULL;
1534 600068 : gconf->extra = NULL;
1535 600068 : gconf->last_reported = NULL;
1536 600068 : gconf->sourcefile = NULL;
1537 600068 : gconf->sourceline = 0;
1538 :
1539 600068 : switch (gconf->vartype)
1540 : {
1541 169463 : case PGC_BOOL:
1542 : {
1543 169463 : struct config_bool *conf = &gconf->_bool;
1544 169463 : bool newval = conf->boot_val;
1545 :
1546 169463 : if (!call_bool_check_hook(gconf, &newval, &extra,
1547 : PGC_S_DEFAULT, LOG))
1548 0 : elog(FATAL, "failed to initialize %s to %d",
1549 : gconf->name, (int) newval);
1550 169463 : if (conf->assign_hook)
1551 0 : conf->assign_hook(newval, extra);
1552 169463 : *conf->variable = conf->reset_val = newval;
1553 169463 : break;
1554 : }
1555 202195 : case PGC_INT:
1556 : {
1557 202195 : struct config_int *conf = &gconf->_int;
1558 202195 : int newval = conf->boot_val;
1559 :
1560 : Assert(newval >= conf->min);
1561 : Assert(newval <= conf->max);
1562 202195 : if (!call_int_check_hook(gconf, &newval, &extra,
1563 : PGC_S_DEFAULT, LOG))
1564 0 : elog(FATAL, "failed to initialize %s to %d",
1565 : gconf->name, newval);
1566 202195 : if (conf->assign_hook)
1567 16766 : conf->assign_hook(newval, extra);
1568 202195 : *conf->variable = conf->reset_val = newval;
1569 202195 : break;
1570 : }
1571 40829 : case PGC_REAL:
1572 : {
1573 40829 : struct config_real *conf = &gconf->_real;
1574 40829 : double newval = conf->boot_val;
1575 :
1576 : Assert(newval >= conf->min);
1577 : Assert(newval <= conf->max);
1578 40829 : if (!call_real_check_hook(gconf, &newval, &extra,
1579 : PGC_S_DEFAULT, LOG))
1580 0 : elog(FATAL, "failed to initialize %s to %g",
1581 : gconf->name, newval);
1582 40829 : if (conf->assign_hook)
1583 2550 : conf->assign_hook(newval, extra);
1584 40829 : *conf->variable = conf->reset_val = newval;
1585 40829 : break;
1586 : }
1587 125640 : case PGC_STRING:
1588 : {
1589 125640 : struct config_string *conf = &gconf->_string;
1590 : char *newval;
1591 :
1592 : /* non-NULL boot_val must always get strdup'd */
1593 125640 : if (conf->boot_val != NULL)
1594 113262 : newval = guc_strdup(FATAL, conf->boot_val);
1595 : else
1596 12378 : newval = NULL;
1597 :
1598 125640 : if (!call_string_check_hook(gconf, &newval, &extra,
1599 : PGC_S_DEFAULT, LOG))
1600 0 : elog(FATAL, "failed to initialize %s to \"%s\"",
1601 : gconf->name, newval ? newval : "");
1602 125640 : if (conf->assign_hook)
1603 66082 : conf->assign_hook(newval, extra);
1604 125640 : *conf->variable = conf->reset_val = newval;
1605 125640 : break;
1606 : }
1607 61941 : case PGC_ENUM:
1608 : {
1609 61941 : struct config_enum *conf = &gconf->_enum;
1610 61941 : int newval = conf->boot_val;
1611 :
1612 61941 : if (!call_enum_check_hook(gconf, &newval, &extra,
1613 : PGC_S_DEFAULT, LOG))
1614 0 : elog(FATAL, "failed to initialize %s to %d",
1615 : gconf->name, newval);
1616 61941 : if (conf->assign_hook)
1617 8927 : conf->assign_hook(newval, extra);
1618 61941 : *conf->variable = conf->reset_val = newval;
1619 61941 : break;
1620 : }
1621 : }
1622 :
1623 600068 : gconf->extra = gconf->reset_extra = extra;
1624 600068 : }
1625 :
1626 : /*
1627 : * Summarily remove a GUC variable from any linked lists it's in.
1628 : *
1629 : * We use this in cases where the variable is about to be deleted or reset.
1630 : * These aren't common operations, so it's okay if this is a bit slow.
1631 : */
1632 : static void
1633 49778 : RemoveGUCFromLists(struct config_generic *gconf)
1634 : {
1635 49778 : if (gconf->source != PGC_S_DEFAULT)
1636 49777 : dlist_delete(&gconf->nondef_link);
1637 49778 : if (gconf->stack != NULL)
1638 0 : slist_delete(&guc_stack_list, &gconf->stack_link);
1639 49778 : if (gconf->status & GUC_NEEDS_REPORT)
1640 6024 : slist_delete(&guc_report_list, &gconf->report_link);
1641 49778 : }
1642 :
1643 :
1644 : /*
1645 : * Select the configuration files and data directory to be used, and
1646 : * do the initial read of postgresql.conf.
1647 : *
1648 : * This is called after processing command-line switches.
1649 : * userDoption is the -D switch value if any (NULL if unspecified).
1650 : * progname is just for use in error messages.
1651 : *
1652 : * Returns true on success; on failure, prints a suitable error message
1653 : * to stderr and returns false.
1654 : */
1655 : bool
1656 1247 : SelectConfigFiles(const char *userDoption, const char *progname)
1657 : {
1658 : char *configdir;
1659 : char *fname;
1660 : bool fname_is_malloced;
1661 : struct stat stat_buf;
1662 : struct config_generic *data_directory_rec;
1663 :
1664 : /* configdir is -D option, or $PGDATA if no -D */
1665 1247 : if (userDoption)
1666 1018 : configdir = make_absolute_path(userDoption);
1667 : else
1668 229 : configdir = make_absolute_path(getenv("PGDATA"));
1669 :
1670 1247 : if (configdir && stat(configdir, &stat_buf) != 0)
1671 : {
1672 0 : write_stderr("%s: could not access directory \"%s\": %m\n",
1673 : progname,
1674 : configdir);
1675 0 : if (errno == ENOENT)
1676 0 : write_stderr("Run initdb or pg_basebackup to initialize a PostgreSQL data directory.\n");
1677 0 : goto fail;
1678 : }
1679 :
1680 : /*
1681 : * Find the configuration file: if config_file was specified on the
1682 : * command line, use it, else use configdir/postgresql.conf. In any case
1683 : * ensure the result is an absolute path, so that it will be interpreted
1684 : * the same way by future backends.
1685 : */
1686 1247 : if (ConfigFileName)
1687 : {
1688 10 : fname = make_absolute_path(ConfigFileName);
1689 10 : fname_is_malloced = true;
1690 : }
1691 1237 : else if (configdir)
1692 : {
1693 1237 : fname = guc_malloc(FATAL,
1694 1237 : strlen(configdir) + strlen(CONFIG_FILENAME) + 2);
1695 1237 : sprintf(fname, "%s/%s", configdir, CONFIG_FILENAME);
1696 1237 : fname_is_malloced = false;
1697 : }
1698 : else
1699 : {
1700 0 : write_stderr("%s does not know where to find the server configuration file.\n"
1701 : "You must specify the --config-file or -D invocation "
1702 : "option or set the PGDATA environment variable.\n",
1703 : progname);
1704 0 : goto fail;
1705 : }
1706 :
1707 : /*
1708 : * Set the ConfigFileName GUC variable to its final value, ensuring that
1709 : * it can't be overridden later.
1710 : */
1711 1247 : SetConfigOption("config_file", fname, PGC_POSTMASTER, PGC_S_OVERRIDE);
1712 :
1713 1247 : if (fname_is_malloced)
1714 10 : free(fname);
1715 : else
1716 1237 : guc_free(fname);
1717 :
1718 : /*
1719 : * Now read the config file for the first time.
1720 : */
1721 1247 : if (stat(ConfigFileName, &stat_buf) != 0)
1722 : {
1723 0 : write_stderr("%s: could not access the server configuration file \"%s\": %m\n",
1724 : progname, ConfigFileName);
1725 0 : goto fail;
1726 : }
1727 :
1728 : /*
1729 : * Read the configuration file for the first time. This time only the
1730 : * data_directory parameter is picked up to determine the data directory,
1731 : * so that we can read the PG_AUTOCONF_FILENAME file next time.
1732 : */
1733 1247 : ProcessConfigFile(PGC_POSTMASTER);
1734 :
1735 : /*
1736 : * If the data_directory GUC variable has been set, use that as DataDir;
1737 : * otherwise use configdir if set; else punt.
1738 : *
1739 : * Note: SetDataDir will copy and absolute-ize its argument, so we don't
1740 : * have to.
1741 : */
1742 : data_directory_rec =
1743 1247 : find_option("data_directory", false, false, PANIC);
1744 1247 : if (*data_directory_rec->_string.variable)
1745 0 : SetDataDir(*data_directory_rec->_string.variable);
1746 1247 : else if (configdir)
1747 1247 : SetDataDir(configdir);
1748 : else
1749 : {
1750 0 : write_stderr("%s does not know where to find the database system data.\n"
1751 : "This can be specified as \"data_directory\" in \"%s\", "
1752 : "or by the -D invocation option, or by the "
1753 : "PGDATA environment variable.\n",
1754 : progname, ConfigFileName);
1755 0 : goto fail;
1756 : }
1757 :
1758 : /*
1759 : * Reflect the final DataDir value back into the data_directory GUC var.
1760 : * (If you are wondering why we don't just make them a single variable,
1761 : * it's because the EXEC_BACKEND case needs DataDir to be transmitted to
1762 : * child backends specially. XXX is that still true? Given that we now
1763 : * chdir to DataDir, EXEC_BACKEND can read the config file without knowing
1764 : * DataDir in advance.)
1765 : */
1766 1247 : SetConfigOption("data_directory", DataDir, PGC_POSTMASTER, PGC_S_OVERRIDE);
1767 :
1768 : /*
1769 : * Now read the config file a second time, allowing any settings in the
1770 : * PG_AUTOCONF_FILENAME file to take effect. (This is pretty ugly, but
1771 : * since we have to determine the DataDir before we can find the autoconf
1772 : * file, the alternatives seem worse.)
1773 : */
1774 1247 : ProcessConfigFile(PGC_POSTMASTER);
1775 :
1776 : /*
1777 : * If timezone_abbreviations wasn't set in the configuration file, install
1778 : * the default value. We do it this way because we can't safely install a
1779 : * "real" value until my_exec_path is set, which may not have happened
1780 : * when InitializeGUCOptions runs, so the bootstrap default value cannot
1781 : * be the real desired default.
1782 : */
1783 1245 : pg_timezone_abbrev_initialize();
1784 :
1785 : /*
1786 : * Figure out where pg_hba.conf is, and make sure the path is absolute.
1787 : */
1788 1245 : if (HbaFileName)
1789 : {
1790 1 : fname = make_absolute_path(HbaFileName);
1791 1 : fname_is_malloced = true;
1792 : }
1793 1244 : else if (configdir)
1794 : {
1795 1244 : fname = guc_malloc(FATAL,
1796 1244 : strlen(configdir) + strlen(HBA_FILENAME) + 2);
1797 1244 : sprintf(fname, "%s/%s", configdir, HBA_FILENAME);
1798 1244 : fname_is_malloced = false;
1799 : }
1800 : else
1801 : {
1802 0 : write_stderr("%s does not know where to find the \"hba\" configuration file.\n"
1803 : "This can be specified as \"hba_file\" in \"%s\", "
1804 : "or by the -D invocation option, or by the "
1805 : "PGDATA environment variable.\n",
1806 : progname, ConfigFileName);
1807 0 : goto fail;
1808 : }
1809 1245 : SetConfigOption("hba_file", fname, PGC_POSTMASTER, PGC_S_OVERRIDE);
1810 :
1811 1245 : if (fname_is_malloced)
1812 1 : free(fname);
1813 : else
1814 1244 : guc_free(fname);
1815 :
1816 : /*
1817 : * Likewise for pg_ident.conf.
1818 : */
1819 1245 : if (IdentFileName)
1820 : {
1821 1 : fname = make_absolute_path(IdentFileName);
1822 1 : fname_is_malloced = true;
1823 : }
1824 1244 : else if (configdir)
1825 : {
1826 1244 : fname = guc_malloc(FATAL,
1827 1244 : strlen(configdir) + strlen(IDENT_FILENAME) + 2);
1828 1244 : sprintf(fname, "%s/%s", configdir, IDENT_FILENAME);
1829 1244 : fname_is_malloced = false;
1830 : }
1831 : else
1832 : {
1833 0 : write_stderr("%s does not know where to find the \"ident\" configuration file.\n"
1834 : "This can be specified as \"ident_file\" in \"%s\", "
1835 : "or by the -D invocation option, or by the "
1836 : "PGDATA environment variable.\n",
1837 : progname, ConfigFileName);
1838 0 : goto fail;
1839 : }
1840 1245 : SetConfigOption("ident_file", fname, PGC_POSTMASTER, PGC_S_OVERRIDE);
1841 :
1842 1245 : if (fname_is_malloced)
1843 1 : free(fname);
1844 : else
1845 1244 : guc_free(fname);
1846 :
1847 : /*
1848 : * Likewise for pg_hosts.conf.
1849 : */
1850 1245 : if (HostsFileName)
1851 : {
1852 0 : fname = make_absolute_path(HostsFileName);
1853 0 : fname_is_malloced = true;
1854 : }
1855 1245 : else if (configdir)
1856 : {
1857 1245 : fname = guc_malloc(FATAL,
1858 1245 : strlen(configdir) + strlen(HOSTS_FILENAME) + 2);
1859 1245 : sprintf(fname, "%s/%s", configdir, HOSTS_FILENAME);
1860 1245 : fname_is_malloced = false;
1861 : }
1862 : else
1863 : {
1864 0 : write_stderr("%s does not know where to find the \"hosts\" configuration file.\n"
1865 : "This can be specified as \"hosts_file\" in \"%s\", "
1866 : "or by the -D invocation option, or by the "
1867 : "PGDATA environment variable.\n",
1868 : progname, ConfigFileName);
1869 0 : goto fail;
1870 : }
1871 1245 : SetConfigOption("hosts_file", fname, PGC_POSTMASTER, PGC_S_OVERRIDE);
1872 :
1873 1245 : if (fname_is_malloced)
1874 0 : free(fname);
1875 : else
1876 1245 : guc_free(fname);
1877 :
1878 1245 : free(configdir);
1879 :
1880 1245 : return true;
1881 :
1882 0 : fail:
1883 0 : free(configdir);
1884 :
1885 0 : return false;
1886 : }
1887 :
1888 : /*
1889 : * pg_timezone_abbrev_initialize --- set default value if not done already
1890 : *
1891 : * This is called after initial loading of postgresql.conf. If no
1892 : * timezone_abbreviations setting was found therein, select default.
1893 : * If a non-default value is already installed, nothing will happen.
1894 : *
1895 : * This can also be called from ProcessConfigFile to establish the default
1896 : * value after a postgresql.conf entry for it is removed.
1897 : */
1898 : static void
1899 2166 : pg_timezone_abbrev_initialize(void)
1900 : {
1901 2166 : SetConfigOption("timezone_abbreviations", "Default",
1902 : PGC_POSTMASTER, PGC_S_DYNAMIC_DEFAULT);
1903 2166 : }
1904 :
1905 :
1906 : /*
1907 : * Reset all options to their saved default values (implements RESET ALL)
1908 : */
1909 : void
1910 11 : ResetAllOptions(void)
1911 : {
1912 : dlist_mutable_iter iter;
1913 :
1914 : /* We need only consider GUCs not already at PGC_S_DEFAULT */
1915 634 : dlist_foreach_modify(iter, &guc_nondef_list)
1916 : {
1917 623 : struct config_generic *gconf = dlist_container(struct config_generic,
1918 : nondef_link, iter.cur);
1919 :
1920 : /* Don't reset non-SET-able values */
1921 623 : if (gconf->context != PGC_SUSET &&
1922 576 : gconf->context != PGC_USERSET)
1923 375 : continue;
1924 : /* Don't reset if special exclusion from RESET ALL */
1925 248 : if (gconf->flags & GUC_NO_RESET_ALL)
1926 55 : continue;
1927 : /* No need to reset if wasn't SET */
1928 193 : if (gconf->source <= PGC_S_OVERRIDE)
1929 169 : continue;
1930 :
1931 : /* Save old value to support transaction abort */
1932 24 : push_old_value(gconf, GUC_ACTION_SET);
1933 :
1934 24 : switch (gconf->vartype)
1935 : {
1936 12 : case PGC_BOOL:
1937 : {
1938 12 : struct config_bool *conf = &gconf->_bool;
1939 :
1940 12 : if (conf->assign_hook)
1941 0 : conf->assign_hook(conf->reset_val,
1942 : gconf->reset_extra);
1943 12 : *conf->variable = conf->reset_val;
1944 12 : set_extra_field(gconf, &gconf->extra,
1945 : gconf->reset_extra);
1946 12 : break;
1947 : }
1948 1 : case PGC_INT:
1949 : {
1950 1 : struct config_int *conf = &gconf->_int;
1951 :
1952 1 : if (conf->assign_hook)
1953 0 : conf->assign_hook(conf->reset_val,
1954 : gconf->reset_extra);
1955 1 : *conf->variable = conf->reset_val;
1956 1 : set_extra_field(gconf, &gconf->extra,
1957 : gconf->reset_extra);
1958 1 : break;
1959 : }
1960 4 : case PGC_REAL:
1961 : {
1962 4 : struct config_real *conf = &gconf->_real;
1963 :
1964 4 : if (conf->assign_hook)
1965 0 : conf->assign_hook(conf->reset_val,
1966 : gconf->reset_extra);
1967 4 : *conf->variable = conf->reset_val;
1968 4 : set_extra_field(gconf, &gconf->extra,
1969 : gconf->reset_extra);
1970 4 : break;
1971 : }
1972 6 : case PGC_STRING:
1973 : {
1974 6 : struct config_string *conf = &gconf->_string;
1975 :
1976 6 : if (conf->assign_hook)
1977 2 : conf->assign_hook(conf->reset_val,
1978 : gconf->reset_extra);
1979 6 : set_string_field(gconf, conf->variable, conf->reset_val);
1980 6 : set_extra_field(gconf, &gconf->extra,
1981 : gconf->reset_extra);
1982 6 : break;
1983 : }
1984 1 : case PGC_ENUM:
1985 : {
1986 1 : struct config_enum *conf = &gconf->_enum;
1987 :
1988 1 : if (conf->assign_hook)
1989 0 : conf->assign_hook(conf->reset_val,
1990 : gconf->reset_extra);
1991 1 : *conf->variable = conf->reset_val;
1992 1 : set_extra_field(gconf, &gconf->extra,
1993 : gconf->reset_extra);
1994 1 : break;
1995 : }
1996 : }
1997 :
1998 24 : set_guc_source(gconf, gconf->reset_source);
1999 24 : gconf->scontext = gconf->reset_scontext;
2000 24 : gconf->srole = gconf->reset_srole;
2001 :
2002 24 : if ((gconf->flags & GUC_REPORT) && !(gconf->status & GUC_NEEDS_REPORT))
2003 : {
2004 3 : gconf->status |= GUC_NEEDS_REPORT;
2005 3 : slist_push_head(&guc_report_list, &gconf->report_link);
2006 : }
2007 : }
2008 11 : }
2009 :
2010 :
2011 : /*
2012 : * Apply a change to a GUC variable's "source" field.
2013 : *
2014 : * Use this rather than just assigning, to ensure that the variable's
2015 : * membership in guc_nondef_list is updated correctly.
2016 : */
2017 : static void
2018 1000227 : set_guc_source(struct config_generic *gconf, GucSource newsource)
2019 : {
2020 : /* Adjust nondef list membership if appropriate for change */
2021 1000227 : if (gconf->source == PGC_S_DEFAULT)
2022 : {
2023 419326 : if (newsource != PGC_S_DEFAULT)
2024 418644 : dlist_push_tail(&guc_nondef_list, &gconf->nondef_link);
2025 : }
2026 : else
2027 : {
2028 580901 : if (newsource == PGC_S_DEFAULT)
2029 152872 : dlist_delete(&gconf->nondef_link);
2030 : }
2031 : /* Now update the source field */
2032 1000227 : gconf->source = newsource;
2033 1000227 : }
2034 :
2035 :
2036 : /*
2037 : * push_old_value
2038 : * Push previous state during transactional assignment to a GUC variable.
2039 : */
2040 : static void
2041 360306 : push_old_value(struct config_generic *gconf, GucAction action)
2042 : {
2043 : GucStack *stack;
2044 :
2045 : /* If we're not inside a nest level, do nothing */
2046 360306 : if (GUCNestLevel == 0)
2047 0 : return;
2048 :
2049 : /* Do we already have a stack entry of the current nest level? */
2050 360306 : stack = gconf->stack;
2051 360306 : if (stack && stack->nest_level >= GUCNestLevel)
2052 : {
2053 : /* Yes, so adjust its state if necessary */
2054 : Assert(stack->nest_level == GUCNestLevel);
2055 7564 : switch (action)
2056 : {
2057 7395 : case GUC_ACTION_SET:
2058 : /* SET overrides any prior action at same nest level */
2059 7395 : if (stack->state == GUC_SET_LOCAL)
2060 : {
2061 : /* must discard old masked value */
2062 0 : discard_stack_value(gconf, &stack->masked);
2063 : }
2064 7395 : stack->state = GUC_SET;
2065 7395 : break;
2066 169 : case GUC_ACTION_LOCAL:
2067 169 : if (stack->state == GUC_SET)
2068 : {
2069 : /* SET followed by SET LOCAL, remember SET's value */
2070 8 : stack->masked_scontext = gconf->scontext;
2071 8 : stack->masked_srole = gconf->srole;
2072 8 : set_stack_value(gconf, &stack->masked);
2073 8 : stack->state = GUC_SET_LOCAL;
2074 : }
2075 : /* in all other cases, no change to stack entry */
2076 169 : break;
2077 0 : case GUC_ACTION_SAVE:
2078 : /* Could only have a prior SAVE of same variable */
2079 : Assert(stack->state == GUC_SAVE);
2080 0 : break;
2081 : }
2082 7564 : return;
2083 : }
2084 :
2085 : /*
2086 : * Push a new stack entry
2087 : *
2088 : * We keep all the stack entries in TopTransactionContext for simplicity.
2089 : */
2090 352742 : stack = (GucStack *) MemoryContextAllocZero(TopTransactionContext,
2091 : sizeof(GucStack));
2092 :
2093 352742 : stack->prev = gconf->stack;
2094 352742 : stack->nest_level = GUCNestLevel;
2095 352742 : switch (action)
2096 : {
2097 39412 : case GUC_ACTION_SET:
2098 39412 : stack->state = GUC_SET;
2099 39412 : break;
2100 5085 : case GUC_ACTION_LOCAL:
2101 5085 : stack->state = GUC_LOCAL;
2102 5085 : break;
2103 308245 : case GUC_ACTION_SAVE:
2104 308245 : stack->state = GUC_SAVE;
2105 308245 : break;
2106 : }
2107 352742 : stack->source = gconf->source;
2108 352742 : stack->scontext = gconf->scontext;
2109 352742 : stack->srole = gconf->srole;
2110 352742 : set_stack_value(gconf, &stack->prior);
2111 :
2112 352742 : if (gconf->stack == NULL)
2113 331887 : slist_push_head(&guc_stack_list, &gconf->stack_link);
2114 352742 : gconf->stack = stack;
2115 : }
2116 :
2117 :
2118 : /*
2119 : * Do GUC processing at main transaction start.
2120 : */
2121 : void
2122 630756 : AtStart_GUC(void)
2123 : {
2124 : /*
2125 : * The nest level should be 0 between transactions; if it isn't, somebody
2126 : * didn't call AtEOXact_GUC, or called it with the wrong nestLevel. We
2127 : * throw a warning but make no other effort to clean up.
2128 : */
2129 630756 : if (GUCNestLevel != 0)
2130 0 : elog(WARNING, "GUC nest level = %d at transaction start",
2131 : GUCNestLevel);
2132 630756 : GUCNestLevel = 1;
2133 630756 : }
2134 :
2135 : /*
2136 : * Enter a new nesting level for GUC values. This is called at subtransaction
2137 : * start, and when entering a function that has proconfig settings, and in
2138 : * some other places where we want to set GUC variables transiently.
2139 : * NOTE we must not risk error here, else subtransaction start will be unhappy.
2140 : */
2141 : int
2142 303586 : NewGUCNestLevel(void)
2143 : {
2144 303586 : return ++GUCNestLevel;
2145 : }
2146 :
2147 : /*
2148 : * Set search_path to a fixed value for maintenance operations. No effect
2149 : * during bootstrap, when the search_path is already set to a fixed value and
2150 : * cannot be changed.
2151 : */
2152 : void
2153 236400 : RestrictSearchPath(void)
2154 : {
2155 236400 : if (!IsBootstrapProcessingMode())
2156 198609 : set_config_option("search_path", GUC_SAFE_SEARCH_PATH, PGC_USERSET,
2157 : PGC_S_SESSION, GUC_ACTION_SAVE, true, 0, false);
2158 236400 : }
2159 :
2160 : /*
2161 : * Do GUC processing at transaction or subtransaction commit or abort, or
2162 : * when exiting a function that has proconfig settings, or when undoing a
2163 : * transient assignment to some GUC variables. (The name is thus a bit of
2164 : * a misnomer; perhaps it should be ExitGUCNestLevel or some such.)
2165 : * During abort, we discard all GUC settings that were applied at nesting
2166 : * levels >= nestLevel. nestLevel == 1 corresponds to the main transaction.
2167 : */
2168 : void
2169 932468 : AtEOXact_GUC(bool isCommit, int nestLevel)
2170 : {
2171 : slist_mutable_iter iter;
2172 :
2173 : /*
2174 : * Note: it's possible to get here with GUCNestLevel == nestLevel-1 during
2175 : * abort, if there is a failure during transaction start before
2176 : * AtStart_GUC is called.
2177 : */
2178 : Assert(nestLevel > 0 &&
2179 : (nestLevel <= GUCNestLevel ||
2180 : (nestLevel == GUCNestLevel + 1 && !isCommit)));
2181 :
2182 : /* We need only process GUCs having nonempty stacks */
2183 1296824 : slist_foreach_modify(iter, &guc_stack_list)
2184 : {
2185 364356 : struct config_generic *gconf = slist_container(struct config_generic,
2186 : stack_link, iter.cur);
2187 : GucStack *stack;
2188 :
2189 : /*
2190 : * Process and pop each stack entry within the nest level. To simplify
2191 : * fmgr_security_definer() and other places that use GUC_ACTION_SAVE,
2192 : * we allow failure exit from code that uses a local nest level to be
2193 : * recovered at the surrounding transaction or subtransaction abort;
2194 : * so there could be more than one stack entry to pop.
2195 : */
2196 717120 : while ((stack = gconf->stack) != NULL &&
2197 385235 : stack->nest_level >= nestLevel)
2198 : {
2199 352764 : GucStack *prev = stack->prev;
2200 352764 : bool restorePrior = false;
2201 352764 : bool restoreMasked = false;
2202 : bool changed;
2203 :
2204 : /*
2205 : * In this next bit, if we don't set either restorePrior or
2206 : * restoreMasked, we must "discard" any unwanted fields of the
2207 : * stack entries to avoid leaking memory. If we do set one of
2208 : * those flags, unused fields will be cleaned up after restoring.
2209 : */
2210 352764 : if (!isCommit) /* if abort, always restore prior value */
2211 289829 : restorePrior = true;
2212 62935 : else if (stack->state == GUC_SAVE)
2213 21061 : restorePrior = true;
2214 41874 : else if (stack->nest_level == 1)
2215 : {
2216 : /* transaction commit */
2217 41846 : if (stack->state == GUC_SET_LOCAL)
2218 8 : restoreMasked = true;
2219 41838 : else if (stack->state == GUC_SET)
2220 : {
2221 : /* we keep the current active value */
2222 37957 : discard_stack_value(gconf, &stack->prior);
2223 : }
2224 : else /* must be GUC_LOCAL */
2225 3881 : restorePrior = true;
2226 : }
2227 28 : else if (prev == NULL ||
2228 8 : prev->nest_level < stack->nest_level - 1)
2229 : {
2230 : /* decrement entry's level and do not pop it */
2231 24 : stack->nest_level--;
2232 24 : continue;
2233 : }
2234 : else
2235 : {
2236 : /*
2237 : * We have to merge this stack entry into prev. See README for
2238 : * discussion of this bit.
2239 : */
2240 4 : switch (stack->state)
2241 : {
2242 0 : case GUC_SAVE:
2243 : Assert(false); /* can't get here */
2244 0 : break;
2245 :
2246 4 : case GUC_SET:
2247 : /* next level always becomes SET */
2248 4 : discard_stack_value(gconf, &stack->prior);
2249 4 : if (prev->state == GUC_SET_LOCAL)
2250 0 : discard_stack_value(gconf, &prev->masked);
2251 4 : prev->state = GUC_SET;
2252 4 : break;
2253 :
2254 0 : case GUC_LOCAL:
2255 0 : if (prev->state == GUC_SET)
2256 : {
2257 : /* LOCAL migrates down */
2258 0 : prev->masked_scontext = stack->scontext;
2259 0 : prev->masked_srole = stack->srole;
2260 0 : prev->masked = stack->prior;
2261 0 : prev->state = GUC_SET_LOCAL;
2262 : }
2263 : else
2264 : {
2265 : /* else just forget this stack level */
2266 0 : discard_stack_value(gconf, &stack->prior);
2267 : }
2268 0 : break;
2269 :
2270 0 : case GUC_SET_LOCAL:
2271 : /* prior state at this level no longer wanted */
2272 0 : discard_stack_value(gconf, &stack->prior);
2273 : /* copy down the masked state */
2274 0 : prev->masked_scontext = stack->masked_scontext;
2275 0 : prev->masked_srole = stack->masked_srole;
2276 0 : if (prev->state == GUC_SET_LOCAL)
2277 0 : discard_stack_value(gconf, &prev->masked);
2278 0 : prev->masked = stack->masked;
2279 0 : prev->state = GUC_SET_LOCAL;
2280 0 : break;
2281 : }
2282 : }
2283 :
2284 352740 : changed = false;
2285 :
2286 352740 : if (restorePrior || restoreMasked)
2287 : {
2288 : /* Perform appropriate restoration of the stacked value */
2289 : config_var_value newvalue;
2290 : GucSource newsource;
2291 : GucContext newscontext;
2292 : Oid newsrole;
2293 :
2294 314779 : if (restoreMasked)
2295 : {
2296 8 : newvalue = stack->masked;
2297 8 : newsource = PGC_S_SESSION;
2298 8 : newscontext = stack->masked_scontext;
2299 8 : newsrole = stack->masked_srole;
2300 : }
2301 : else
2302 : {
2303 314771 : newvalue = stack->prior;
2304 314771 : newsource = stack->source;
2305 314771 : newscontext = stack->scontext;
2306 314771 : newsrole = stack->srole;
2307 : }
2308 :
2309 314779 : switch (gconf->vartype)
2310 : {
2311 46102 : case PGC_BOOL:
2312 : {
2313 46102 : struct config_bool *conf = &gconf->_bool;
2314 46102 : bool newval = newvalue.val.boolval;
2315 46102 : void *newextra = newvalue.extra;
2316 :
2317 46102 : if (*conf->variable != newval ||
2318 315 : gconf->extra != newextra)
2319 : {
2320 45787 : if (conf->assign_hook)
2321 0 : conf->assign_hook(newval, newextra);
2322 45787 : *conf->variable = newval;
2323 45787 : set_extra_field(gconf, &gconf->extra,
2324 : newextra);
2325 45787 : changed = true;
2326 : }
2327 46102 : break;
2328 : }
2329 5467 : case PGC_INT:
2330 : {
2331 5467 : struct config_int *conf = &gconf->_int;
2332 5467 : int newval = newvalue.val.intval;
2333 5467 : void *newextra = newvalue.extra;
2334 :
2335 5467 : if (*conf->variable != newval ||
2336 131 : gconf->extra != newextra)
2337 : {
2338 5336 : if (conf->assign_hook)
2339 0 : conf->assign_hook(newval, newextra);
2340 5336 : *conf->variable = newval;
2341 5336 : set_extra_field(gconf, &gconf->extra,
2342 : newextra);
2343 5336 : changed = true;
2344 : }
2345 5467 : break;
2346 : }
2347 1094 : case PGC_REAL:
2348 : {
2349 1094 : struct config_real *conf = &gconf->_real;
2350 1094 : double newval = newvalue.val.realval;
2351 1094 : void *newextra = newvalue.extra;
2352 :
2353 1094 : if (*conf->variable != newval ||
2354 16 : gconf->extra != newextra)
2355 : {
2356 1078 : if (conf->assign_hook)
2357 0 : conf->assign_hook(newval, newextra);
2358 1078 : *conf->variable = newval;
2359 1078 : set_extra_field(gconf, &gconf->extra,
2360 : newextra);
2361 1078 : changed = true;
2362 : }
2363 1094 : break;
2364 : }
2365 209250 : case PGC_STRING:
2366 : {
2367 209250 : struct config_string *conf = &gconf->_string;
2368 209250 : char *newval = newvalue.val.stringval;
2369 209250 : void *newextra = newvalue.extra;
2370 :
2371 209250 : if (*conf->variable != newval ||
2372 13 : gconf->extra != newextra)
2373 : {
2374 209237 : if (conf->assign_hook)
2375 208862 : conf->assign_hook(newval, newextra);
2376 209237 : set_string_field(gconf, conf->variable, newval);
2377 209237 : set_extra_field(gconf, &gconf->extra,
2378 : newextra);
2379 209237 : changed = true;
2380 : }
2381 :
2382 : /*
2383 : * Release stacked values if not used anymore. We
2384 : * could use discard_stack_value() here, but since
2385 : * we have type-specific code anyway, might as
2386 : * well inline it.
2387 : */
2388 209250 : set_string_field(gconf, &stack->prior.val.stringval, NULL);
2389 209250 : set_string_field(gconf, &stack->masked.val.stringval, NULL);
2390 209250 : break;
2391 : }
2392 52866 : case PGC_ENUM:
2393 : {
2394 52866 : struct config_enum *conf = &gconf->_enum;
2395 52866 : int newval = newvalue.val.enumval;
2396 52866 : void *newextra = newvalue.extra;
2397 :
2398 52866 : if (*conf->variable != newval ||
2399 779 : gconf->extra != newextra)
2400 : {
2401 52087 : if (conf->assign_hook)
2402 20 : conf->assign_hook(newval, newextra);
2403 52087 : *conf->variable = newval;
2404 52087 : set_extra_field(gconf, &gconf->extra,
2405 : newextra);
2406 52087 : changed = true;
2407 : }
2408 52866 : break;
2409 : }
2410 : }
2411 :
2412 : /*
2413 : * Release stacked extra values if not used anymore.
2414 : */
2415 314779 : set_extra_field(gconf, &(stack->prior.extra), NULL);
2416 314779 : set_extra_field(gconf, &(stack->masked.extra), NULL);
2417 :
2418 : /* And restore source information */
2419 314779 : set_guc_source(gconf, newsource);
2420 314779 : gconf->scontext = newscontext;
2421 314779 : gconf->srole = newsrole;
2422 : }
2423 :
2424 : /*
2425 : * Pop the GUC's state stack; if it's now empty, remove the GUC
2426 : * from guc_stack_list.
2427 : */
2428 352740 : gconf->stack = prev;
2429 352740 : if (prev == NULL)
2430 331885 : slist_delete_current(&iter);
2431 352740 : pfree(stack);
2432 :
2433 : /* Report new value if we changed it */
2434 352740 : if (changed && (gconf->flags & GUC_REPORT) &&
2435 212961 : !(gconf->status & GUC_NEEDS_REPORT))
2436 : {
2437 212 : gconf->status |= GUC_NEEDS_REPORT;
2438 212 : slist_push_head(&guc_report_list, &gconf->report_link);
2439 : }
2440 : } /* end of stack-popping loop */
2441 : }
2442 :
2443 : /* Update nesting level */
2444 932468 : GUCNestLevel = nestLevel - 1;
2445 932468 : }
2446 :
2447 :
2448 : /*
2449 : * Start up automatic reporting of changes to variables marked GUC_REPORT.
2450 : * This is executed at completion of backend startup.
2451 : */
2452 : void
2453 14604 : BeginReportingGUCOptions(void)
2454 : {
2455 : HASH_SEQ_STATUS status;
2456 : GUCHashEntry *hentry;
2457 :
2458 : /*
2459 : * Don't do anything unless talking to an interactive frontend.
2460 : */
2461 14604 : if (whereToSendOutput != DestRemote)
2462 74 : return;
2463 :
2464 14530 : reporting_enabled = true;
2465 :
2466 : /*
2467 : * Hack for in_hot_standby: set the GUC value true if appropriate. This
2468 : * is kind of an ugly place to do it, but there's few better options.
2469 : *
2470 : * (This could be out of date by the time we actually send it, in which
2471 : * case the next ReportChangedGUCOptions call will send a duplicate
2472 : * report.)
2473 : */
2474 14530 : if (RecoveryInProgress())
2475 816 : SetConfigOption("in_hot_standby", "true",
2476 : PGC_INTERNAL, PGC_S_OVERRIDE);
2477 :
2478 : /* Transmit initial values of interesting variables */
2479 14530 : hash_seq_init(&status, guc_hashtab);
2480 6164288 : while ((hentry = (GUCHashEntry *) hash_seq_search(&status)) != NULL)
2481 : {
2482 6135228 : struct config_generic *conf = hentry->gucvar;
2483 :
2484 6135228 : if (conf->flags & GUC_REPORT)
2485 217950 : ReportGUCOption(conf);
2486 : }
2487 : }
2488 :
2489 : /*
2490 : * ReportChangedGUCOptions: report recently-changed GUC_REPORT variables
2491 : *
2492 : * This is called just before we wait for a new client query.
2493 : *
2494 : * By handling things this way, we ensure that a ParameterStatus message
2495 : * is sent at most once per variable per query, even if the variable
2496 : * changed multiple times within the query. That's quite possible when
2497 : * using features such as function SET clauses. Function SET clauses
2498 : * also tend to cause values to change intraquery but eventually revert
2499 : * to their prevailing values; ReportGUCOption is responsible for avoiding
2500 : * redundant reports in such cases.
2501 : */
2502 : void
2503 461560 : ReportChangedGUCOptions(void)
2504 : {
2505 : slist_mutable_iter iter;
2506 :
2507 : /* Quick exit if not (yet) enabled */
2508 461560 : if (!reporting_enabled)
2509 36441 : return;
2510 :
2511 : /*
2512 : * Since in_hot_standby isn't actually changed by normal GUC actions, we
2513 : * need a hack to check whether a new value needs to be reported to the
2514 : * client. For speed, we rely on the assumption that it can never
2515 : * transition from false to true.
2516 : */
2517 425119 : if (in_hot_standby_guc && !RecoveryInProgress())
2518 7 : SetConfigOption("in_hot_standby", "false",
2519 : PGC_INTERNAL, PGC_S_OVERRIDE);
2520 :
2521 : /* Transmit new values of interesting variables */
2522 573624 : slist_foreach_modify(iter, &guc_report_list)
2523 : {
2524 148505 : struct config_generic *conf = slist_container(struct config_generic,
2525 : report_link, iter.cur);
2526 :
2527 : Assert((conf->flags & GUC_REPORT) && (conf->status & GUC_NEEDS_REPORT));
2528 148505 : ReportGUCOption(conf);
2529 148505 : conf->status &= ~GUC_NEEDS_REPORT;
2530 148505 : slist_delete_current(&iter);
2531 : }
2532 : }
2533 :
2534 : /*
2535 : * ReportGUCOption: if appropriate, transmit option value to frontend
2536 : *
2537 : * We need not transmit the value if it's the same as what we last
2538 : * transmitted.
2539 : */
2540 : static void
2541 366455 : ReportGUCOption(struct config_generic *record)
2542 : {
2543 366455 : char *val = ShowGUCOption(record, false);
2544 :
2545 366455 : if (record->last_reported == NULL ||
2546 148505 : strcmp(val, record->last_reported) != 0)
2547 : {
2548 : StringInfoData msgbuf;
2549 :
2550 227529 : pq_beginmessage(&msgbuf, PqMsg_ParameterStatus);
2551 227529 : pq_sendstring(&msgbuf, record->name);
2552 227529 : pq_sendstring(&msgbuf, val);
2553 227529 : pq_endmessage(&msgbuf);
2554 :
2555 : /*
2556 : * We need a long-lifespan copy. If guc_strdup() fails due to OOM,
2557 : * we'll set last_reported to NULL and thereby possibly make a
2558 : * duplicate report later.
2559 : */
2560 227529 : guc_free(record->last_reported);
2561 227529 : record->last_reported = guc_strdup(LOG, val);
2562 : }
2563 :
2564 366455 : pfree(val);
2565 366455 : }
2566 :
2567 : /*
2568 : * Convert a value from one of the human-friendly units ("kB", "min" etc.)
2569 : * to the given base unit. 'value' and 'unit' are the input value and unit
2570 : * to convert from (there can be trailing spaces in the unit string).
2571 : * The converted value is stored in *base_value.
2572 : * It's caller's responsibility to round off the converted value as necessary
2573 : * and check for out-of-range.
2574 : *
2575 : * Returns true on success, false if the input unit is not recognized.
2576 : */
2577 : static bool
2578 9114 : convert_to_base_unit(double value, const char *unit,
2579 : int base_unit, double *base_value)
2580 : {
2581 : char unitstr[MAX_UNIT_LEN + 1];
2582 : int unitlen;
2583 : const unit_conversion *table;
2584 :
2585 : /* extract unit string to compare to table entries */
2586 9114 : unitlen = 0;
2587 26950 : while (*unit != '\0' && !isspace((unsigned char) *unit) &&
2588 : unitlen < MAX_UNIT_LEN)
2589 17836 : unitstr[unitlen++] = *(unit++);
2590 9114 : unitstr[unitlen] = '\0';
2591 : /* allow whitespace after unit */
2592 9114 : while (isspace((unsigned char) *unit))
2593 0 : unit++;
2594 9114 : if (*unit != '\0')
2595 0 : return false; /* unit too long, or garbage after it */
2596 :
2597 : /* now search the appropriate table */
2598 9114 : if (base_unit & GUC_UNIT_MEMORY)
2599 6754 : table = memory_unit_conversion_table;
2600 : else
2601 2360 : table = time_unit_conversion_table;
2602 :
2603 106802 : for (int i = 0; *table[i].unit; i++)
2604 : {
2605 106802 : if (base_unit == table[i].base_unit &&
2606 30563 : strcmp(unitstr, table[i].unit) == 0)
2607 : {
2608 9114 : double cvalue = value * table[i].multiplier;
2609 :
2610 : /*
2611 : * If the user gave a fractional value such as "30.1GB", round it
2612 : * off to the nearest multiple of the next smaller unit, if there
2613 : * is one.
2614 : */
2615 9114 : if (*table[i + 1].unit &&
2616 9114 : base_unit == table[i + 1].base_unit)
2617 9110 : cvalue = rint(cvalue / table[i + 1].multiplier) *
2618 9110 : table[i + 1].multiplier;
2619 :
2620 9114 : *base_value = cvalue;
2621 9114 : return true;
2622 : }
2623 : }
2624 0 : return false;
2625 : }
2626 :
2627 : /*
2628 : * Convert an integer value in some base unit to a human-friendly unit.
2629 : *
2630 : * The output unit is chosen so that it's the greatest unit that can represent
2631 : * the value without loss. For example, if the base unit is GUC_UNIT_KB, 1024
2632 : * is converted to 1 MB, but 1025 is represented as 1025 kB.
2633 : */
2634 : static void
2635 423 : convert_int_from_base_unit(int64 base_value, int base_unit,
2636 : int64 *value, const char **unit)
2637 : {
2638 : const unit_conversion *table;
2639 :
2640 423 : *unit = NULL;
2641 :
2642 423 : if (base_unit & GUC_UNIT_MEMORY)
2643 361 : table = memory_unit_conversion_table;
2644 : else
2645 62 : table = time_unit_conversion_table;
2646 :
2647 2860 : for (int i = 0; *table[i].unit; i++)
2648 : {
2649 2860 : if (base_unit == table[i].base_unit)
2650 : {
2651 : /*
2652 : * Accept the first conversion that divides the value evenly. We
2653 : * assume that the conversions for each base unit are ordered from
2654 : * greatest unit to the smallest!
2655 : */
2656 1305 : if (table[i].multiplier <= 1.0 ||
2657 1241 : base_value % (int64) table[i].multiplier == 0)
2658 : {
2659 423 : *value = (int64) rint(base_value / table[i].multiplier);
2660 423 : *unit = table[i].unit;
2661 423 : break;
2662 : }
2663 : }
2664 : }
2665 :
2666 : Assert(*unit != NULL);
2667 423 : }
2668 :
2669 : /*
2670 : * Convert a floating-point value in some base unit to a human-friendly unit.
2671 : *
2672 : * Same as above, except we have to do the math a bit differently, and
2673 : * there's a possibility that we don't find any exact divisor.
2674 : */
2675 : static void
2676 178 : convert_real_from_base_unit(double base_value, int base_unit,
2677 : double *value, const char **unit)
2678 : {
2679 : const unit_conversion *table;
2680 :
2681 178 : *unit = NULL;
2682 :
2683 178 : if (base_unit & GUC_UNIT_MEMORY)
2684 0 : table = memory_unit_conversion_table;
2685 : else
2686 178 : table = time_unit_conversion_table;
2687 :
2688 906 : for (int i = 0; *table[i].unit; i++)
2689 : {
2690 906 : if (base_unit == table[i].base_unit)
2691 : {
2692 : /*
2693 : * Accept the first conversion that divides the value evenly; or
2694 : * if there is none, use the smallest (last) target unit.
2695 : *
2696 : * What we actually care about here is whether snprintf with "%g"
2697 : * will print the value as an integer, so the obvious test of
2698 : * "*value == rint(*value)" is too strict; roundoff error might
2699 : * make us choose an unreasonably small unit. As a compromise,
2700 : * accept a divisor that is within 1e-8 of producing an integer.
2701 : */
2702 906 : *value = base_value / table[i].multiplier;
2703 906 : *unit = table[i].unit;
2704 906 : if (*value > 0 &&
2705 906 : fabs((rint(*value) / *value) - 1.0) <= 1e-8)
2706 178 : break;
2707 : }
2708 : }
2709 :
2710 : Assert(*unit != NULL);
2711 178 : }
2712 :
2713 : /*
2714 : * Return the name of a GUC's base unit (e.g. "ms") given its flags.
2715 : * Return NULL if the GUC is unitless.
2716 : */
2717 : const char *
2718 818996 : get_config_unit_name(int flags)
2719 : {
2720 818996 : switch (flags & GUC_UNIT)
2721 : {
2722 661042 : case 0:
2723 661042 : return NULL; /* GUC has no units */
2724 9750 : case GUC_UNIT_BYTE:
2725 9750 : return "B";
2726 23400 : case GUC_UNIT_KB:
2727 23400 : return "kB";
2728 11700 : case GUC_UNIT_MB:
2729 11700 : return "MB";
2730 35100 : case GUC_UNIT_BLOCKS:
2731 : {
2732 : static char bbuf[8];
2733 :
2734 : /* initialize if first time through */
2735 35100 : if (bbuf[0] == '\0')
2736 396 : snprintf(bbuf, sizeof(bbuf), "%dkB", BLCKSZ / 1024);
2737 35100 : return bbuf;
2738 : }
2739 3900 : case GUC_UNIT_XBLOCKS:
2740 : {
2741 : static char xbuf[8];
2742 :
2743 : /* initialize if first time through */
2744 3900 : if (xbuf[0] == '\0')
2745 396 : snprintf(xbuf, sizeof(xbuf), "%dkB", XLOG_BLCKSZ / 1024);
2746 3900 : return xbuf;
2747 : }
2748 46804 : case GUC_UNIT_MS:
2749 46804 : return "ms";
2750 23400 : case GUC_UNIT_S:
2751 23400 : return "s";
2752 3900 : case GUC_UNIT_MIN:
2753 3900 : return "min";
2754 0 : default:
2755 0 : elog(ERROR, "unrecognized GUC units value: %d",
2756 : flags & GUC_UNIT);
2757 : return NULL;
2758 : }
2759 : }
2760 :
2761 :
2762 : /*
2763 : * Try to parse value as an integer. The accepted formats are the
2764 : * usual decimal, octal, or hexadecimal formats, as well as floating-point
2765 : * formats (which will be rounded to integer after any units conversion).
2766 : * Optionally, the value can be followed by a unit name if "flags" indicates
2767 : * a unit is allowed.
2768 : *
2769 : * If the string parses okay, return true, else false.
2770 : * If okay and result is not NULL, return the value in *result.
2771 : * If not okay and hintmsg is not NULL, *hintmsg is set to a suitable
2772 : * HINT message, or NULL if no hint provided.
2773 : */
2774 : bool
2775 71159 : parse_int(const char *value, int *result, int flags, const char **hintmsg)
2776 : {
2777 : /*
2778 : * We assume here that double is wide enough to represent any integer
2779 : * value with adequate precision.
2780 : */
2781 : double val;
2782 : char *endptr;
2783 :
2784 : /* To suppress compiler warnings, always set output params */
2785 71159 : if (result)
2786 71159 : *result = 0;
2787 71159 : if (hintmsg)
2788 64669 : *hintmsg = NULL;
2789 :
2790 : /*
2791 : * Try to parse as an integer (allowing octal or hex input). If the
2792 : * conversion stops at a decimal point or 'e', or overflows, re-parse as
2793 : * float. This should work fine as long as we have no unit names starting
2794 : * with 'e'. If we ever do, the test could be extended to check for a
2795 : * sign or digit after 'e', but for now that's unnecessary.
2796 : */
2797 71159 : errno = 0;
2798 71159 : val = strtol(value, &endptr, 0);
2799 71159 : if (*endptr == '.' || *endptr == 'e' || *endptr == 'E' ||
2800 71152 : errno == ERANGE)
2801 : {
2802 7 : errno = 0;
2803 7 : val = strtod(value, &endptr);
2804 : }
2805 :
2806 71159 : if (endptr == value || errno == ERANGE)
2807 22 : return false; /* no HINT for these cases */
2808 :
2809 : /* reject NaN (infinities will fail range check below) */
2810 71137 : if (isnan(val))
2811 0 : return false; /* treat same as syntax error; no HINT */
2812 :
2813 : /* allow whitespace between number and unit */
2814 71162 : while (isspace((unsigned char) *endptr))
2815 25 : endptr++;
2816 :
2817 : /* Handle possible unit */
2818 71137 : if (*endptr != '\0')
2819 : {
2820 8909 : if ((flags & GUC_UNIT) == 0)
2821 6 : return false; /* this setting does not accept a unit */
2822 :
2823 8903 : if (!convert_to_base_unit(val,
2824 : endptr, (flags & GUC_UNIT),
2825 : &val))
2826 : {
2827 : /* invalid unit, or garbage after the unit; set hint and fail. */
2828 0 : if (hintmsg)
2829 : {
2830 0 : if (flags & GUC_UNIT_MEMORY)
2831 0 : *hintmsg = memory_units_hint;
2832 : else
2833 0 : *hintmsg = time_units_hint;
2834 : }
2835 0 : return false;
2836 : }
2837 : }
2838 :
2839 : /* Round to int, then check for overflow */
2840 71131 : val = rint(val);
2841 :
2842 71131 : if (val > INT_MAX || val < INT_MIN)
2843 : {
2844 4 : if (hintmsg)
2845 4 : *hintmsg = gettext_noop("Value exceeds integer range.");
2846 4 : return false;
2847 : }
2848 :
2849 71127 : if (result)
2850 71127 : *result = (int) val;
2851 71127 : return true;
2852 : }
2853 :
2854 : /*
2855 : * Try to parse value as a floating point number in the usual format.
2856 : * Optionally, the value can be followed by a unit name if "flags" indicates
2857 : * a unit is allowed.
2858 : *
2859 : * If the string parses okay, return true, else false.
2860 : * If okay and result is not NULL, return the value in *result.
2861 : * If not okay and hintmsg is not NULL, *hintmsg is set to a suitable
2862 : * HINT message, or NULL if no hint provided.
2863 : */
2864 : bool
2865 6249 : parse_real(const char *value, double *result, int flags, const char **hintmsg)
2866 : {
2867 : double val;
2868 : char *endptr;
2869 :
2870 : /* To suppress compiler warnings, always set output params */
2871 6249 : if (result)
2872 6249 : *result = 0;
2873 6249 : if (hintmsg)
2874 5915 : *hintmsg = NULL;
2875 :
2876 6249 : errno = 0;
2877 6249 : val = strtod(value, &endptr);
2878 :
2879 6249 : if (endptr == value || errno == ERANGE)
2880 11 : return false; /* no HINT for these cases */
2881 :
2882 : /* reject NaN (infinities will fail range checks later) */
2883 6238 : if (isnan(val))
2884 4 : return false; /* treat same as syntax error; no HINT */
2885 :
2886 : /* allow whitespace between number and unit */
2887 6234 : while (isspace((unsigned char) *endptr))
2888 0 : endptr++;
2889 :
2890 : /* Handle possible unit */
2891 6234 : if (*endptr != '\0')
2892 : {
2893 213 : if ((flags & GUC_UNIT) == 0)
2894 2 : return false; /* this setting does not accept a unit */
2895 :
2896 211 : if (!convert_to_base_unit(val,
2897 : endptr, (flags & GUC_UNIT),
2898 : &val))
2899 : {
2900 : /* invalid unit, or garbage after the unit; set hint and fail. */
2901 0 : if (hintmsg)
2902 : {
2903 0 : if (flags & GUC_UNIT_MEMORY)
2904 0 : *hintmsg = memory_units_hint;
2905 : else
2906 0 : *hintmsg = time_units_hint;
2907 : }
2908 0 : return false;
2909 : }
2910 : }
2911 :
2912 6232 : if (result)
2913 6232 : *result = val;
2914 6232 : return true;
2915 : }
2916 :
2917 :
2918 : /*
2919 : * Lookup the name for an enum option with the selected value.
2920 : * Should only ever be called with known-valid values, so throws
2921 : * an elog(ERROR) if the enum option is not found.
2922 : *
2923 : * The returned string is a pointer to static data and not
2924 : * allocated for modification.
2925 : */
2926 : const char *
2927 274113 : config_enum_lookup_by_value(const struct config_generic *record, int val)
2928 : {
2929 628721 : for (const struct config_enum_entry *entry = record->_enum.options; entry && entry->name; entry++)
2930 : {
2931 628721 : if (entry->val == val)
2932 274113 : return entry->name;
2933 : }
2934 :
2935 0 : elog(ERROR, "could not find enum option %d for %s",
2936 : val, record->name);
2937 : return NULL; /* silence compiler */
2938 : }
2939 :
2940 :
2941 : /*
2942 : * Lookup the value for an enum option with the selected name
2943 : * (case-insensitive).
2944 : * If the enum option is found, sets the retval value and returns
2945 : * true. If it's not found, return false and retval is set to 0.
2946 : */
2947 : bool
2948 86080 : config_enum_lookup_by_name(const struct config_enum *record, const char *value,
2949 : int *retval)
2950 : {
2951 577151 : for (const struct config_enum_entry *entry = record->options; entry && entry->name; entry++)
2952 : {
2953 577124 : if (pg_strcasecmp(value, entry->name) == 0)
2954 : {
2955 86053 : *retval = entry->val;
2956 86053 : return true;
2957 : }
2958 : }
2959 :
2960 27 : *retval = 0;
2961 27 : return false;
2962 : }
2963 :
2964 :
2965 : /*
2966 : * Return a palloc'd string listing all the available options for an enum GUC
2967 : * (excluding hidden ones), separated by the given separator.
2968 : * If prefix is non-NULL, it is added before the first enum value.
2969 : * If suffix is non-NULL, it is added to the end of the string.
2970 : */
2971 : char *
2972 83495 : config_enum_get_options(const struct config_enum *record, const char *prefix,
2973 : const char *suffix, const char *separator)
2974 : {
2975 : StringInfoData retstr;
2976 : int seplen;
2977 :
2978 83495 : initStringInfo(&retstr);
2979 83495 : appendStringInfoString(&retstr, prefix);
2980 :
2981 83495 : seplen = strlen(separator);
2982 513379 : for (const struct config_enum_entry *entry = record->options; entry && entry->name; entry++)
2983 : {
2984 429884 : if (!entry->hidden)
2985 : {
2986 299210 : appendStringInfoString(&retstr, entry->name);
2987 299210 : appendBinaryStringInfo(&retstr, separator, seplen);
2988 : }
2989 : }
2990 :
2991 : /*
2992 : * All the entries may have been hidden, leaving the string empty if no
2993 : * prefix was given. This indicates a broken GUC setup, since there is no
2994 : * use for an enum without any values, so we just check to make sure we
2995 : * don't write to invalid memory instead of actually trying to do
2996 : * something smart with it.
2997 : */
2998 83495 : if (retstr.len >= seplen)
2999 : {
3000 : /* Replace final separator */
3001 81545 : retstr.data[retstr.len - seplen] = '\0';
3002 81545 : retstr.len -= seplen;
3003 : }
3004 :
3005 83495 : appendStringInfoString(&retstr, suffix);
3006 :
3007 83495 : return retstr.data;
3008 : }
3009 :
3010 : /*
3011 : * Parse and validate a proposed value for the specified configuration
3012 : * parameter.
3013 : *
3014 : * This does built-in checks (such as range limits for an integer parameter)
3015 : * and also calls any check hook the parameter may have.
3016 : *
3017 : * record: GUC variable's info record
3018 : * value: proposed value, as a string
3019 : * source: identifies source of value (check hooks may need this)
3020 : * elevel: level to log any error reports at
3021 : * newval: on success, converted parameter value is returned here
3022 : * newextra: on success, receives any "extra" data returned by check hook
3023 : * (caller must initialize *newextra to NULL)
3024 : *
3025 : * Returns true if OK, false if not (or throws error, if elevel >= ERROR)
3026 : */
3027 : static bool
3028 693330 : parse_and_validate_value(const struct config_generic *record,
3029 : const char *value,
3030 : GucSource source, int elevel,
3031 : union config_var_val *newval, void **newextra)
3032 : {
3033 693330 : switch (record->vartype)
3034 : {
3035 138808 : case PGC_BOOL:
3036 : {
3037 138808 : if (!parse_bool(value, &newval->boolval))
3038 : {
3039 0 : ereport(elevel,
3040 : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
3041 : errmsg("parameter \"%s\" requires a Boolean value",
3042 : record->name)));
3043 0 : return false;
3044 : }
3045 :
3046 138808 : if (!call_bool_check_hook(record, &newval->boolval, newextra,
3047 : source, elevel))
3048 0 : return false;
3049 : }
3050 138788 : break;
3051 64633 : case PGC_INT:
3052 : {
3053 64633 : const struct config_int *conf = &record->_int;
3054 : const char *hintmsg;
3055 :
3056 64633 : if (!parse_int(value, &newval->intval,
3057 64633 : record->flags, &hintmsg))
3058 : {
3059 4 : ereport(elevel,
3060 : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
3061 : errmsg("invalid value for parameter \"%s\": \"%s\"",
3062 : record->name, value),
3063 : hintmsg ? errhint("%s", _(hintmsg)) : 0));
3064 0 : return false;
3065 : }
3066 :
3067 64629 : if (newval->intval < conf->min || newval->intval > conf->max)
3068 : {
3069 2 : const char *unit = get_config_unit_name(record->flags);
3070 : const char *unitspace;
3071 :
3072 2 : if (unit)
3073 0 : unitspace = " ";
3074 : else
3075 2 : unit = unitspace = "";
3076 :
3077 2 : ereport(elevel,
3078 : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
3079 : errmsg("%d%s%s is outside the valid range for parameter \"%s\" (%d%s%s .. %d%s%s)",
3080 : newval->intval, unitspace, unit,
3081 : record->name,
3082 : conf->min, unitspace, unit,
3083 : conf->max, unitspace, unit)));
3084 0 : return false;
3085 : }
3086 :
3087 64627 : if (!call_int_check_hook(record, &newval->intval, newextra,
3088 : source, elevel))
3089 0 : return false;
3090 : }
3091 64627 : break;
3092 5709 : case PGC_REAL:
3093 : {
3094 5709 : const struct config_real *conf = &record->_real;
3095 : const char *hintmsg;
3096 :
3097 5709 : if (!parse_real(value, &newval->realval,
3098 5709 : record->flags, &hintmsg))
3099 : {
3100 4 : ereport(elevel,
3101 : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
3102 : errmsg("invalid value for parameter \"%s\": \"%s\"",
3103 : record->name, value),
3104 : hintmsg ? errhint("%s", _(hintmsg)) : 0));
3105 0 : return false;
3106 : }
3107 :
3108 5705 : if (newval->realval < conf->min || newval->realval > conf->max)
3109 : {
3110 4 : const char *unit = get_config_unit_name(record->flags);
3111 : const char *unitspace;
3112 :
3113 4 : if (unit)
3114 4 : unitspace = " ";
3115 : else
3116 0 : unit = unitspace = "";
3117 :
3118 4 : ereport(elevel,
3119 : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
3120 : errmsg("%g%s%s is outside the valid range for parameter \"%s\" (%g%s%s .. %g%s%s)",
3121 : newval->realval, unitspace, unit,
3122 : record->name,
3123 : conf->min, unitspace, unit,
3124 : conf->max, unitspace, unit)));
3125 0 : return false;
3126 : }
3127 :
3128 5701 : if (!call_real_check_hook(record, &newval->realval, newextra,
3129 : source, elevel))
3130 0 : return false;
3131 : }
3132 5701 : break;
3133 398100 : case PGC_STRING:
3134 : {
3135 : /*
3136 : * The value passed by the caller could be transient, so we
3137 : * always strdup it.
3138 : */
3139 398100 : newval->stringval = guc_strdup(elevel, value);
3140 398100 : if (newval->stringval == NULL)
3141 0 : return false;
3142 :
3143 : /*
3144 : * The only built-in "parsing" check we have is to apply
3145 : * truncation if GUC_IS_NAME.
3146 : */
3147 398100 : if (record->flags & GUC_IS_NAME)
3148 97973 : truncate_identifier(newval->stringval,
3149 97973 : strlen(newval->stringval),
3150 : true);
3151 :
3152 398100 : if (!call_string_check_hook(record, &newval->stringval, newextra,
3153 : source, elevel))
3154 : {
3155 0 : guc_free(newval->stringval);
3156 0 : newval->stringval = NULL;
3157 0 : return false;
3158 : }
3159 : }
3160 397996 : break;
3161 86080 : case PGC_ENUM:
3162 : {
3163 86080 : const struct config_enum *conf = &record->_enum;
3164 :
3165 86080 : if (!config_enum_lookup_by_name(conf, value, &newval->enumval))
3166 : {
3167 : char *hintmsg;
3168 :
3169 27 : hintmsg = config_enum_get_options(conf,
3170 27 : _("Available values: "),
3171 :
3172 : /*
3173 : * translator: This is the terminator of a list of entity
3174 : * names.
3175 : */
3176 27 : _("."),
3177 :
3178 : /*
3179 : * translator: This is a separator in a list of entity
3180 : * names.
3181 : */
3182 27 : _(", "));
3183 :
3184 27 : ereport(elevel,
3185 : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
3186 : errmsg("invalid value for parameter \"%s\": \"%s\"",
3187 : record->name, value),
3188 : hintmsg ? errhint("%s", hintmsg) : 0));
3189 :
3190 0 : if (hintmsg)
3191 0 : pfree(hintmsg);
3192 0 : return false;
3193 : }
3194 :
3195 86053 : if (!call_enum_check_hook(record, &newval->enumval, newextra,
3196 : source, elevel))
3197 0 : return false;
3198 : }
3199 86052 : break;
3200 : }
3201 :
3202 693164 : return true;
3203 : }
3204 :
3205 :
3206 : /*
3207 : * set_config_option: sets option `name' to given value.
3208 : *
3209 : * The value should be a string, which will be parsed and converted to
3210 : * the appropriate data type. The context and source parameters indicate
3211 : * in which context this function is being called, so that it can apply the
3212 : * access restrictions properly.
3213 : *
3214 : * If value is NULL, set the option to its default value (normally the
3215 : * reset_val, but if source == PGC_S_DEFAULT we instead use the boot_val).
3216 : *
3217 : * action indicates whether to set the value globally in the session, locally
3218 : * to the current top transaction, or just for the duration of a function call.
3219 : *
3220 : * If changeVal is false then don't really set the option but do all
3221 : * the checks to see if it would work.
3222 : *
3223 : * elevel should normally be passed as zero, allowing this function to make
3224 : * its standard choice of ereport level. However some callers need to be
3225 : * able to override that choice; they should pass the ereport level to use.
3226 : *
3227 : * is_reload should be true only when called from read_nondefault_variables()
3228 : * or RestoreGUCState(), where we are trying to load some other process's
3229 : * GUC settings into a new process.
3230 : *
3231 : * Return value:
3232 : * +1: the value is valid and was successfully applied.
3233 : * 0: the name or value is invalid, or it's invalid to try to set
3234 : * this GUC now; but elevel was less than ERROR (see below).
3235 : * -1: no error detected, but the value was not applied, either
3236 : * because changeVal is false or there is some overriding setting.
3237 : *
3238 : * If there is an error (non-existing option, invalid value, etc) then an
3239 : * ereport(ERROR) is thrown *unless* this is called for a source for which
3240 : * we don't want an ERROR (currently, those are defaults, the config file,
3241 : * and per-database or per-user settings, as well as callers who specify
3242 : * a less-than-ERROR elevel). In those cases we write a suitable error
3243 : * message via ereport() and return 0.
3244 : *
3245 : * See also SetConfigOption for an external interface.
3246 : */
3247 : int
3248 608114 : set_config_option(const char *name, const char *value,
3249 : GucContext context, GucSource source,
3250 : GucAction action, bool changeVal, int elevel,
3251 : bool is_reload)
3252 : {
3253 : Oid srole;
3254 :
3255 : /*
3256 : * Non-interactive sources should be treated as having all privileges,
3257 : * except for PGC_S_CLIENT. Note in particular that this is true for
3258 : * pg_db_role_setting sources (PGC_S_GLOBAL etc): we assume a suitable
3259 : * privilege check was done when the pg_db_role_setting entry was made.
3260 : */
3261 608114 : if (source >= PGC_S_INTERACTIVE || source == PGC_S_CLIENT)
3262 370753 : srole = GetUserId();
3263 : else
3264 237361 : srole = BOOTSTRAP_SUPERUSERID;
3265 :
3266 608114 : return set_config_with_handle(name, NULL, value,
3267 : context, source, srole,
3268 : action, changeVal, elevel,
3269 : is_reload);
3270 : }
3271 :
3272 : /*
3273 : * set_config_option_ext: sets option `name' to given value.
3274 : *
3275 : * This API adds the ability to explicitly specify which role OID
3276 : * is considered to be setting the value. Most external callers can use
3277 : * set_config_option() and let it determine that based on the GucSource,
3278 : * but there are a few that are supplying a value that was determined
3279 : * in some special way and need to override the decision. Also, when
3280 : * restoring a previously-assigned value, it's important to supply the
3281 : * same role OID that set the value originally; so all guc.c callers
3282 : * that are doing that type of thing need to call this directly.
3283 : *
3284 : * Generally, srole should be GetUserId() when the source is a SQL operation,
3285 : * or BOOTSTRAP_SUPERUSERID if the source is a config file or similar.
3286 : */
3287 : int
3288 72051 : set_config_option_ext(const char *name, const char *value,
3289 : GucContext context, GucSource source, Oid srole,
3290 : GucAction action, bool changeVal, int elevel,
3291 : bool is_reload)
3292 : {
3293 72051 : return set_config_with_handle(name, NULL, value,
3294 : context, source, srole,
3295 : action, changeVal, elevel,
3296 : is_reload);
3297 : }
3298 :
3299 :
3300 : /*
3301 : * set_config_with_handle: sets option `name' to given value.
3302 : *
3303 : * This API adds the ability to pass a 'handle' argument, which can be
3304 : * obtained by the caller from get_config_handle(). NULL has no effect,
3305 : * but a non-null value avoids the need to search the GUC tables.
3306 : *
3307 : * This should be used by callers which repeatedly set the same config
3308 : * option(s), and want to avoid the overhead of a hash lookup each time.
3309 : */
3310 : int
3311 698074 : set_config_with_handle(const char *name, config_handle *handle,
3312 : const char *value,
3313 : GucContext context, GucSource source, Oid srole,
3314 : GucAction action, bool changeVal, int elevel,
3315 : bool is_reload)
3316 : {
3317 : struct config_generic *record;
3318 : union config_var_val newval_union;
3319 698074 : void *newextra = NULL;
3320 698074 : bool prohibitValueChange = false;
3321 : bool makeDefault;
3322 :
3323 698074 : if (elevel == 0)
3324 : {
3325 608236 : if (source == PGC_S_DEFAULT || source == PGC_S_FILE)
3326 : {
3327 : /*
3328 : * To avoid cluttering the log, only the postmaster bleats loudly
3329 : * about problems with the config file.
3330 : */
3331 58607 : elevel = IsUnderPostmaster ? DEBUG3 : LOG;
3332 : }
3333 549629 : else if (source == PGC_S_GLOBAL ||
3334 522954 : source == PGC_S_DATABASE ||
3335 522952 : source == PGC_S_USER ||
3336 : source == PGC_S_DATABASE_USER)
3337 26677 : elevel = WARNING;
3338 : else
3339 522952 : elevel = ERROR;
3340 : }
3341 :
3342 : /* if handle is specified, no need to look up option */
3343 698074 : if (!handle)
3344 : {
3345 697963 : record = find_option(name, true, false, elevel);
3346 697923 : if (record == NULL)
3347 0 : return 0;
3348 : }
3349 : else
3350 111 : record = handle;
3351 :
3352 : /*
3353 : * GUC_ACTION_SAVE changes are acceptable during a parallel operation,
3354 : * because the current worker will also pop the change. We're probably
3355 : * dealing with a function having a proconfig entry. Only the function's
3356 : * body should observe the change, and peer workers do not share in the
3357 : * execution of a function call started by this worker.
3358 : *
3359 : * Also allow normal setting if the GUC is marked GUC_ALLOW_IN_PARALLEL.
3360 : *
3361 : * Other changes might need to affect other workers, so forbid them. Note,
3362 : * that parallel autovacuum leader is an exception because cost-based
3363 : * delays need to be affected to parallel autovacuum workers. These
3364 : * parameters are propagated to its workers during parallel vacuum (see
3365 : * vacuumparallel.c for details). All other changes will affect only the
3366 : * parallel autovacuum leader.
3367 : */
3368 698034 : if (IsInParallelMode() && !AmAutoVacuumWorkerProcess() && changeVal &&
3369 12 : action != GUC_ACTION_SAVE &&
3370 12 : (record->flags & GUC_ALLOW_IN_PARALLEL) == 0)
3371 : {
3372 0 : ereport(elevel,
3373 : (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
3374 : errmsg("parameter \"%s\" cannot be set during a parallel operation",
3375 : record->name)));
3376 0 : return 0;
3377 : }
3378 :
3379 : /*
3380 : * Check if the option can be set at this time. See guc.h for the precise
3381 : * rules.
3382 : */
3383 698034 : switch (record->context)
3384 : {
3385 73835 : case PGC_INTERNAL:
3386 73835 : if (context != PGC_INTERNAL)
3387 : {
3388 2 : ereport(elevel,
3389 : (errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
3390 : errmsg("parameter \"%s\" cannot be changed",
3391 : record->name)));
3392 0 : return 0;
3393 : }
3394 73833 : break;
3395 37363 : case PGC_POSTMASTER:
3396 37363 : if (context == PGC_SIGHUP)
3397 : {
3398 : /*
3399 : * We are re-reading a PGC_POSTMASTER variable from
3400 : * postgresql.conf. We can't change the setting, so we should
3401 : * give a warning if the DBA tries to change it. However,
3402 : * because of variant formats, canonicalization by check
3403 : * hooks, etc, we can't just compare the given string directly
3404 : * to what's stored. Set a flag to check below after we have
3405 : * the final storable value.
3406 : */
3407 10095 : prohibitValueChange = true;
3408 : }
3409 27268 : else if (context != PGC_POSTMASTER)
3410 : {
3411 4 : ereport(elevel,
3412 : (errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
3413 : errmsg("parameter \"%s\" cannot be changed without restarting the server",
3414 : record->name)));
3415 0 : return 0;
3416 : }
3417 37359 : break;
3418 33760 : case PGC_SIGHUP:
3419 33760 : if (context != PGC_SIGHUP && context != PGC_POSTMASTER)
3420 : {
3421 3 : ereport(elevel,
3422 : (errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
3423 : errmsg("parameter \"%s\" cannot be changed now",
3424 : record->name)));
3425 0 : return 0;
3426 : }
3427 :
3428 : /*
3429 : * Hmm, the idea of the SIGHUP context is "ought to be global, but
3430 : * can be changed after postmaster start". But there's nothing
3431 : * that prevents a crafty administrator from sending SIGHUP
3432 : * signals to individual backends only.
3433 : */
3434 33757 : break;
3435 296 : case PGC_SU_BACKEND:
3436 296 : if (context == PGC_BACKEND)
3437 : {
3438 : /*
3439 : * Check whether the requesting user has been granted
3440 : * privilege to set this GUC.
3441 : */
3442 : AclResult aclresult;
3443 :
3444 0 : aclresult = pg_parameter_aclcheck(record->name, srole, ACL_SET);
3445 0 : if (aclresult != ACLCHECK_OK)
3446 : {
3447 : /* No granted privilege */
3448 0 : ereport(elevel,
3449 : (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
3450 : errmsg("permission denied to set parameter \"%s\"",
3451 : record->name)));
3452 0 : return 0;
3453 : }
3454 : }
3455 : /* fall through to process the same as PGC_BACKEND */
3456 : pg_fallthrough;
3457 : case PGC_BACKEND:
3458 298 : if (context == PGC_SIGHUP)
3459 : {
3460 : /*
3461 : * If a PGC_BACKEND or PGC_SU_BACKEND parameter is changed in
3462 : * the config file, we want to accept the new value in the
3463 : * postmaster (whence it will propagate to
3464 : * subsequently-started backends), but ignore it in existing
3465 : * backends. This is a tad klugy, but necessary because we
3466 : * don't re-read the config file during backend start.
3467 : *
3468 : * However, if changeVal is false then plow ahead anyway since
3469 : * we are trying to find out if the value is potentially good,
3470 : * not actually use it.
3471 : *
3472 : * In EXEC_BACKEND builds, this works differently: we load all
3473 : * non-default settings from the CONFIG_EXEC_PARAMS file
3474 : * during backend start. In that case we must accept
3475 : * PGC_SIGHUP settings, so as to have the same value as if
3476 : * we'd forked from the postmaster. This can also happen when
3477 : * using RestoreGUCState() within a background worker that
3478 : * needs to have the same settings as the user backend that
3479 : * started it. is_reload will be true when either situation
3480 : * applies.
3481 : */
3482 203 : if (IsUnderPostmaster && changeVal && !is_reload)
3483 139 : return -1;
3484 : }
3485 95 : else if (context != PGC_POSTMASTER &&
3486 4 : context != PGC_BACKEND &&
3487 4 : context != PGC_SU_BACKEND &&
3488 : source != PGC_S_CLIENT)
3489 : {
3490 4 : ereport(elevel,
3491 : (errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
3492 : errmsg("parameter \"%s\" cannot be set after connection start",
3493 : record->name)));
3494 0 : return 0;
3495 : }
3496 155 : break;
3497 25623 : case PGC_SUSET:
3498 25623 : if (context == PGC_USERSET || context == PGC_BACKEND)
3499 : {
3500 : /*
3501 : * Check whether the requesting user has been granted
3502 : * privilege to set this GUC.
3503 : */
3504 : AclResult aclresult;
3505 :
3506 15 : aclresult = pg_parameter_aclcheck(record->name, srole, ACL_SET);
3507 15 : if (aclresult != ACLCHECK_OK)
3508 : {
3509 : /* No granted privilege */
3510 8 : ereport(elevel,
3511 : (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
3512 : errmsg("permission denied to set parameter \"%s\"",
3513 : record->name)));
3514 2 : return 0;
3515 : }
3516 : }
3517 25615 : break;
3518 527155 : case PGC_USERSET:
3519 : /* always okay */
3520 527155 : break;
3521 : }
3522 :
3523 : /*
3524 : * Disallow changing GUC_NOT_WHILE_SEC_REST values if we are inside a
3525 : * security restriction context. We can reject this regardless of the GUC
3526 : * context or source, mainly because sources that it might be reasonable
3527 : * to override for won't be seen while inside a function.
3528 : *
3529 : * Note: variables marked GUC_NOT_WHILE_SEC_REST should usually be marked
3530 : * GUC_NO_RESET_ALL as well, because ResetAllOptions() doesn't check this.
3531 : * An exception might be made if the reset value is assumed to be "safe".
3532 : *
3533 : * Note: this flag is currently used for "session_authorization" and
3534 : * "role". We need to prohibit changing these inside a local userid
3535 : * context because when we exit it, GUC won't be notified, leaving things
3536 : * out of sync. (This could be fixed by forcing a new GUC nesting level,
3537 : * but that would change behavior in possibly-undesirable ways.) Also, we
3538 : * prohibit changing these in a security-restricted operation because
3539 : * otherwise RESET could be used to regain the session user's privileges.
3540 : */
3541 697874 : if (record->flags & GUC_NOT_WHILE_SEC_REST)
3542 : {
3543 40825 : if (InLocalUserIdChange())
3544 : {
3545 : /*
3546 : * Phrasing of this error message is historical, but it's the most
3547 : * common case.
3548 : */
3549 0 : ereport(elevel,
3550 : (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
3551 : errmsg("cannot set parameter \"%s\" within security-definer function",
3552 : record->name)));
3553 0 : return 0;
3554 : }
3555 40825 : if (InSecurityRestrictedOperation())
3556 : {
3557 0 : ereport(elevel,
3558 : (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
3559 : errmsg("cannot set parameter \"%s\" within security-restricted operation",
3560 : record->name)));
3561 0 : return 0;
3562 : }
3563 : }
3564 :
3565 : /* Disallow resetting and saving GUC_NO_RESET values */
3566 697874 : if (record->flags & GUC_NO_RESET)
3567 : {
3568 14724 : if (value == NULL)
3569 : {
3570 12 : ereport(elevel,
3571 : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3572 : errmsg("parameter \"%s\" cannot be reset", record->name)));
3573 0 : return 0;
3574 : }
3575 14712 : if (action == GUC_ACTION_SAVE)
3576 : {
3577 4 : ereport(elevel,
3578 : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3579 : errmsg("parameter \"%s\" cannot be set locally in functions",
3580 : record->name)));
3581 0 : return 0;
3582 : }
3583 : }
3584 :
3585 : /*
3586 : * Should we set reset/stacked values? (If so, the behavior is not
3587 : * transactional.) This is done either when we get a default value from
3588 : * the database's/user's/client's default settings or when we reset a
3589 : * value to its default.
3590 : */
3591 697859 : makeDefault = changeVal && (source <= PGC_S_OVERRIDE) &&
3592 1 : ((value != NULL) || source == PGC_S_DEFAULT);
3593 :
3594 : /*
3595 : * Ignore attempted set if overridden by previously processed setting.
3596 : * However, if changeVal is false then plow ahead anyway since we are
3597 : * trying to find out if the value is potentially good, not actually use
3598 : * it. Also keep going if makeDefault is true, since we may want to set
3599 : * the reset/stacked values even if we can't set the variable itself.
3600 : */
3601 697858 : if (record->source > source)
3602 : {
3603 1351 : if (changeVal && !makeDefault)
3604 : {
3605 0 : elog(DEBUG3, "\"%s\": setting ignored because previous source is higher priority",
3606 : record->name);
3607 0 : return -1;
3608 : }
3609 1351 : changeVal = false;
3610 : }
3611 :
3612 : /*
3613 : * Evaluate value and set variable.
3614 : */
3615 697858 : switch (record->vartype)
3616 : {
3617 139844 : case PGC_BOOL:
3618 : {
3619 139844 : struct config_bool *conf = &record->_bool;
3620 :
3621 : #define newval (newval_union.boolval)
3622 :
3623 139844 : if (value)
3624 : {
3625 138796 : if (!parse_and_validate_value(record, value,
3626 : source, elevel,
3627 : &newval_union, &newextra))
3628 0 : return 0;
3629 : }
3630 1048 : else if (source == PGC_S_DEFAULT)
3631 : {
3632 0 : newval = conf->boot_val;
3633 0 : if (!call_bool_check_hook(record, &newval, &newextra,
3634 : source, elevel))
3635 0 : return 0;
3636 : }
3637 : else
3638 : {
3639 1048 : newval = conf->reset_val;
3640 1048 : newextra = record->reset_extra;
3641 1048 : source = record->reset_source;
3642 1048 : context = record->reset_scontext;
3643 1048 : srole = record->reset_srole;
3644 : }
3645 :
3646 139824 : if (prohibitValueChange)
3647 : {
3648 : /* Release newextra, unless it's reset_extra */
3649 945 : if (newextra && !extra_field_used(record, newextra))
3650 0 : guc_free(newextra);
3651 :
3652 945 : if (*conf->variable != newval)
3653 : {
3654 0 : record->status |= GUC_PENDING_RESTART;
3655 0 : ereport(elevel,
3656 : (errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
3657 : errmsg("parameter \"%s\" cannot be changed without restarting the server",
3658 : record->name)));
3659 0 : return 0;
3660 : }
3661 945 : record->status &= ~GUC_PENDING_RESTART;
3662 945 : return -1;
3663 : }
3664 :
3665 138879 : if (changeVal)
3666 : {
3667 : /* Save old value to support transaction abort */
3668 138804 : if (!makeDefault)
3669 63078 : push_old_value(record, action);
3670 :
3671 138804 : if (conf->assign_hook)
3672 0 : conf->assign_hook(newval, newextra);
3673 138804 : *conf->variable = newval;
3674 138804 : set_extra_field(record, &record->extra,
3675 : newextra);
3676 138804 : set_guc_source(record, source);
3677 138804 : record->scontext = context;
3678 138804 : record->srole = srole;
3679 : }
3680 138879 : if (makeDefault)
3681 : {
3682 75783 : if (record->reset_source <= source)
3683 : {
3684 75726 : conf->reset_val = newval;
3685 75726 : set_extra_field(record, &record->reset_extra,
3686 : newextra);
3687 75726 : record->reset_source = source;
3688 75726 : record->reset_scontext = context;
3689 75726 : record->reset_srole = srole;
3690 : }
3691 75783 : for (GucStack *stack = record->stack; stack; stack = stack->prev)
3692 : {
3693 0 : if (stack->source <= source)
3694 : {
3695 0 : stack->prior.val.boolval = newval;
3696 0 : set_extra_field(record, &stack->prior.extra,
3697 : newextra);
3698 0 : stack->source = source;
3699 0 : stack->scontext = context;
3700 0 : stack->srole = srole;
3701 : }
3702 : }
3703 : }
3704 :
3705 : /* Perhaps we didn't install newextra anywhere */
3706 138879 : if (newextra && !extra_field_used(record, newextra))
3707 0 : guc_free(newextra);
3708 138879 : break;
3709 :
3710 : #undef newval
3711 : }
3712 :
3713 65460 : case PGC_INT:
3714 : {
3715 65460 : struct config_int *conf = &record->_int;
3716 :
3717 : #define newval (newval_union.intval)
3718 :
3719 65460 : if (value)
3720 : {
3721 64611 : if (!parse_and_validate_value(record, value,
3722 : source, elevel,
3723 : &newval_union, &newextra))
3724 0 : return 0;
3725 : }
3726 849 : else if (source == PGC_S_DEFAULT)
3727 : {
3728 0 : newval = conf->boot_val;
3729 0 : if (!call_int_check_hook(record, &newval, &newextra,
3730 : source, elevel))
3731 0 : return 0;
3732 : }
3733 : else
3734 : {
3735 849 : newval = conf->reset_val;
3736 849 : newextra = record->reset_extra;
3737 849 : source = record->reset_source;
3738 849 : context = record->reset_scontext;
3739 849 : srole = record->reset_srole;
3740 : }
3741 :
3742 65456 : if (prohibitValueChange)
3743 : {
3744 : /* Release newextra, unless it's reset_extra */
3745 5262 : if (newextra && !extra_field_used(record, newextra))
3746 0 : guc_free(newextra);
3747 :
3748 5262 : if (*conf->variable != newval)
3749 : {
3750 0 : record->status |= GUC_PENDING_RESTART;
3751 0 : ereport(elevel,
3752 : (errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
3753 : errmsg("parameter \"%s\" cannot be changed without restarting the server",
3754 : record->name)));
3755 0 : return 0;
3756 : }
3757 5262 : record->status &= ~GUC_PENDING_RESTART;
3758 5262 : return -1;
3759 : }
3760 :
3761 60194 : if (changeVal)
3762 : {
3763 : /* Save old value to support transaction abort */
3764 59148 : if (!makeDefault)
3765 13698 : push_old_value(record, action);
3766 :
3767 59148 : if (conf->assign_hook)
3768 10641 : conf->assign_hook(newval, newextra);
3769 59148 : *conf->variable = newval;
3770 59148 : set_extra_field(record, &record->extra,
3771 : newextra);
3772 59148 : set_guc_source(record, source);
3773 59148 : record->scontext = context;
3774 59148 : record->srole = srole;
3775 : }
3776 60194 : if (makeDefault)
3777 : {
3778 46432 : if (record->reset_source <= source)
3779 : {
3780 45450 : conf->reset_val = newval;
3781 45450 : set_extra_field(record, &record->reset_extra,
3782 : newextra);
3783 45450 : record->reset_source = source;
3784 45450 : record->reset_scontext = context;
3785 45450 : record->reset_srole = srole;
3786 : }
3787 46432 : for (GucStack *stack = record->stack; stack; stack = stack->prev)
3788 : {
3789 0 : if (stack->source <= source)
3790 : {
3791 0 : stack->prior.val.intval = newval;
3792 0 : set_extra_field(record, &stack->prior.extra,
3793 : newextra);
3794 0 : stack->source = source;
3795 0 : stack->scontext = context;
3796 0 : stack->srole = srole;
3797 : }
3798 : }
3799 : }
3800 :
3801 : /* Perhaps we didn't install newextra anywhere */
3802 60194 : if (newextra && !extra_field_used(record, newextra))
3803 0 : guc_free(newextra);
3804 60194 : break;
3805 :
3806 : #undef newval
3807 : }
3808 :
3809 5831 : case PGC_REAL:
3810 : {
3811 5831 : struct config_real *conf = &record->_real;
3812 :
3813 : #define newval (newval_union.realval)
3814 :
3815 5831 : if (value)
3816 : {
3817 5708 : if (!parse_and_validate_value(record, value,
3818 : source, elevel,
3819 : &newval_union, &newextra))
3820 0 : return 0;
3821 : }
3822 123 : else if (source == PGC_S_DEFAULT)
3823 : {
3824 0 : newval = conf->boot_val;
3825 0 : if (!call_real_check_hook(record, &newval, &newextra,
3826 : source, elevel))
3827 0 : return 0;
3828 : }
3829 : else
3830 : {
3831 123 : newval = conf->reset_val;
3832 123 : newextra = record->reset_extra;
3833 123 : source = record->reset_source;
3834 123 : context = record->reset_scontext;
3835 123 : srole = record->reset_srole;
3836 : }
3837 :
3838 5823 : if (prohibitValueChange)
3839 : {
3840 : /* Release newextra, unless it's reset_extra */
3841 0 : if (newextra && !extra_field_used(record, newextra))
3842 0 : guc_free(newextra);
3843 :
3844 0 : if (*conf->variable != newval)
3845 : {
3846 0 : record->status |= GUC_PENDING_RESTART;
3847 0 : ereport(elevel,
3848 : (errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
3849 : errmsg("parameter \"%s\" cannot be changed without restarting the server",
3850 : record->name)));
3851 0 : return 0;
3852 : }
3853 0 : record->status &= ~GUC_PENDING_RESTART;
3854 0 : return -1;
3855 : }
3856 :
3857 5823 : if (changeVal)
3858 : {
3859 : /* Save old value to support transaction abort */
3860 5815 : if (!makeDefault)
3861 5804 : push_old_value(record, action);
3862 :
3863 5815 : if (conf->assign_hook)
3864 0 : conf->assign_hook(newval, newextra);
3865 5815 : *conf->variable = newval;
3866 5815 : set_extra_field(record, &record->extra,
3867 : newextra);
3868 5815 : set_guc_source(record, source);
3869 5815 : record->scontext = context;
3870 5815 : record->srole = srole;
3871 : }
3872 5823 : if (makeDefault)
3873 : {
3874 11 : if (record->reset_source <= source)
3875 : {
3876 11 : conf->reset_val = newval;
3877 11 : set_extra_field(record, &record->reset_extra,
3878 : newextra);
3879 11 : record->reset_source = source;
3880 11 : record->reset_scontext = context;
3881 11 : record->reset_srole = srole;
3882 : }
3883 11 : for (GucStack *stack = record->stack; stack; stack = stack->prev)
3884 : {
3885 0 : if (stack->source <= source)
3886 : {
3887 0 : stack->prior.val.realval = newval;
3888 0 : set_extra_field(record, &stack->prior.extra,
3889 : newextra);
3890 0 : stack->source = source;
3891 0 : stack->scontext = context;
3892 0 : stack->srole = srole;
3893 : }
3894 : }
3895 : }
3896 :
3897 : /* Perhaps we didn't install newextra anywhere */
3898 5823 : if (newextra && !extra_field_used(record, newextra))
3899 0 : guc_free(newextra);
3900 5823 : break;
3901 :
3902 : #undef newval
3903 : }
3904 :
3905 400257 : case PGC_STRING:
3906 : {
3907 400257 : struct config_string *conf = &record->_string;
3908 400257 : GucContext orig_context = context;
3909 400257 : GucSource orig_source = source;
3910 400257 : Oid orig_srole = srole;
3911 :
3912 : #define newval (newval_union.stringval)
3913 :
3914 400257 : if (value)
3915 : {
3916 398061 : if (!parse_and_validate_value(record, value,
3917 : source, elevel,
3918 : &newval_union, &newextra))
3919 0 : return 0;
3920 : }
3921 2196 : else if (source == PGC_S_DEFAULT)
3922 : {
3923 : /* non-NULL boot_val must always get strdup'd */
3924 1 : if (conf->boot_val != NULL)
3925 : {
3926 1 : newval = guc_strdup(elevel, conf->boot_val);
3927 1 : if (newval == NULL)
3928 0 : return 0;
3929 : }
3930 : else
3931 0 : newval = NULL;
3932 :
3933 1 : if (!call_string_check_hook(record, &newval, &newextra,
3934 : source, elevel))
3935 : {
3936 0 : guc_free(newval);
3937 0 : return 0;
3938 : }
3939 : }
3940 : else
3941 : {
3942 : /*
3943 : * strdup not needed, since reset_val is already under
3944 : * guc.c's control
3945 : */
3946 2195 : newval = conf->reset_val;
3947 2195 : newextra = record->reset_extra;
3948 2195 : source = record->reset_source;
3949 2195 : context = record->reset_scontext;
3950 2195 : srole = record->reset_srole;
3951 : }
3952 :
3953 400161 : if (prohibitValueChange)
3954 : {
3955 : bool newval_different;
3956 :
3957 : /* newval shouldn't be NULL, so we're a bit sloppy here */
3958 5547 : newval_different = (*conf->variable == NULL ||
3959 3698 : newval == NULL ||
3960 1849 : strcmp(*conf->variable, newval) != 0);
3961 :
3962 : /* Release newval, unless it's reset_val */
3963 1849 : if (newval && !string_field_used(record, newval))
3964 1849 : guc_free(newval);
3965 : /* Release newextra, unless it's reset_extra */
3966 1849 : if (newextra && !extra_field_used(record, newextra))
3967 0 : guc_free(newextra);
3968 :
3969 1849 : if (newval_different)
3970 : {
3971 0 : record->status |= GUC_PENDING_RESTART;
3972 0 : ereport(elevel,
3973 : (errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
3974 : errmsg("parameter \"%s\" cannot be changed without restarting the server",
3975 : record->name)));
3976 0 : return 0;
3977 : }
3978 1849 : record->status &= ~GUC_PENDING_RESTART;
3979 1849 : return -1;
3980 : }
3981 :
3982 398312 : if (changeVal)
3983 : {
3984 : /* Save old value to support transaction abort */
3985 397379 : if (!makeDefault)
3986 222499 : push_old_value(record, action);
3987 :
3988 397379 : if (conf->assign_hook)
3989 363368 : conf->assign_hook(newval, newextra);
3990 397378 : set_string_field(record, conf->variable, newval);
3991 397378 : set_extra_field(record, &record->extra,
3992 : newextra);
3993 397378 : set_guc_source(record, source);
3994 397378 : record->scontext = context;
3995 397378 : record->srole = srole;
3996 :
3997 : /*
3998 : * Ugly hack: during SET session_authorization, forcibly
3999 : * do SET ROLE NONE with the same context/source/etc, so
4000 : * that the effects will have identical lifespan. This is
4001 : * required by the SQL spec, and it's not possible to do
4002 : * it within the variable's check hook or assign hook
4003 : * because our APIs for those don't pass enough info.
4004 : * However, don't do it if is_reload: in that case we
4005 : * expect that if "role" isn't supposed to be default, it
4006 : * has been or will be set by a separate reload action.
4007 : *
4008 : * Also, for the call from InitializeSessionUserId with
4009 : * source == PGC_S_OVERRIDE, use PGC_S_DYNAMIC_DEFAULT for
4010 : * "role"'s source, so that it's still possible to set
4011 : * "role" from pg_db_role_setting entries. (See notes in
4012 : * InitializeSessionUserId before changing this.)
4013 : *
4014 : * A fine point: for RESET session_authorization, we do
4015 : * "RESET role" not "SET ROLE NONE" (by passing down NULL
4016 : * rather than "none" for the value). This would have the
4017 : * same effects in typical cases, but if the reset value
4018 : * of "role" is not "none" it seems better to revert to
4019 : * that.
4020 : */
4021 397378 : if (!is_reload &&
4022 368507 : strcmp(record->name, "session_authorization") == 0)
4023 17798 : (void) set_config_with_handle("role", NULL,
4024 : value ? "none" : NULL,
4025 : orig_context,
4026 : (orig_source == PGC_S_OVERRIDE)
4027 : ? PGC_S_DYNAMIC_DEFAULT
4028 : : orig_source,
4029 : orig_srole,
4030 : action,
4031 : true,
4032 : elevel,
4033 : false);
4034 : }
4035 :
4036 398311 : if (makeDefault)
4037 : {
4038 175141 : if (record->reset_source <= source)
4039 : {
4040 174879 : set_string_field(record, &conf->reset_val, newval);
4041 174879 : set_extra_field(record, &record->reset_extra,
4042 : newextra);
4043 174879 : record->reset_source = source;
4044 174879 : record->reset_scontext = context;
4045 174879 : record->reset_srole = srole;
4046 : }
4047 175141 : for (GucStack *stack = record->stack; stack; stack = stack->prev)
4048 : {
4049 0 : if (stack->source <= source)
4050 : {
4051 0 : set_string_field(record, &stack->prior.val.stringval,
4052 : newval);
4053 0 : set_extra_field(record, &stack->prior.extra,
4054 : newextra);
4055 0 : stack->source = source;
4056 0 : stack->scontext = context;
4057 0 : stack->srole = srole;
4058 : }
4059 : }
4060 : }
4061 :
4062 : /* Perhaps we didn't install newval anywhere */
4063 398311 : if (newval && !string_field_used(record, newval))
4064 919 : guc_free(newval);
4065 : /* Perhaps we didn't install newextra anywhere */
4066 398311 : if (newextra && !extra_field_used(record, newextra))
4067 268 : guc_free(newextra);
4068 398311 : break;
4069 :
4070 : #undef newval
4071 : }
4072 :
4073 86466 : case PGC_ENUM:
4074 : {
4075 86466 : struct config_enum *conf = &record->_enum;
4076 :
4077 : #define newval (newval_union.enumval)
4078 :
4079 86466 : if (value)
4080 : {
4081 86079 : if (!parse_and_validate_value(record, value,
4082 : source, elevel,
4083 : &newval_union, &newextra))
4084 0 : return 0;
4085 : }
4086 387 : else if (source == PGC_S_DEFAULT)
4087 : {
4088 0 : newval = conf->boot_val;
4089 0 : if (!call_enum_check_hook(record, &newval, &newextra,
4090 : source, elevel))
4091 0 : return 0;
4092 : }
4093 : else
4094 : {
4095 387 : newval = conf->reset_val;
4096 387 : newextra = record->reset_extra;
4097 387 : source = record->reset_source;
4098 387 : context = record->reset_scontext;
4099 387 : srole = record->reset_srole;
4100 : }
4101 :
4102 86438 : if (prohibitValueChange)
4103 : {
4104 : /* Release newextra, unless it's reset_extra */
4105 2039 : if (newextra && !extra_field_used(record, newextra))
4106 0 : guc_free(newextra);
4107 :
4108 2039 : if (*conf->variable != newval)
4109 : {
4110 0 : record->status |= GUC_PENDING_RESTART;
4111 0 : ereport(elevel,
4112 : (errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
4113 : errmsg("parameter \"%s\" cannot be changed without restarting the server",
4114 : record->name)));
4115 0 : return 0;
4116 : }
4117 2039 : record->status &= ~GUC_PENDING_RESTART;
4118 2039 : return -1;
4119 : }
4120 :
4121 84399 : if (changeVal)
4122 : {
4123 : /* Save old value to support transaction abort */
4124 84278 : if (!makeDefault)
4125 55203 : push_old_value(record, action);
4126 :
4127 84278 : if (conf->assign_hook)
4128 4914 : conf->assign_hook(newval, newextra);
4129 84278 : *conf->variable = newval;
4130 84278 : set_extra_field(record, &record->extra,
4131 : newextra);
4132 84278 : set_guc_source(record, source);
4133 84278 : record->scontext = context;
4134 84278 : record->srole = srole;
4135 : }
4136 84399 : if (makeDefault)
4137 : {
4138 29075 : if (record->reset_source <= source)
4139 : {
4140 29075 : conf->reset_val = newval;
4141 29075 : set_extra_field(record, &record->reset_extra,
4142 : newextra);
4143 29075 : record->reset_source = source;
4144 29075 : record->reset_scontext = context;
4145 29075 : record->reset_srole = srole;
4146 : }
4147 29075 : for (GucStack *stack = record->stack; stack; stack = stack->prev)
4148 : {
4149 0 : if (stack->source <= source)
4150 : {
4151 0 : stack->prior.val.enumval = newval;
4152 0 : set_extra_field(record, &stack->prior.extra,
4153 : newextra);
4154 0 : stack->source = source;
4155 0 : stack->scontext = context;
4156 0 : stack->srole = srole;
4157 : }
4158 : }
4159 : }
4160 :
4161 : /* Perhaps we didn't install newextra anywhere */
4162 84399 : if (newextra && !extra_field_used(record, newextra))
4163 0 : guc_free(newextra);
4164 84399 : break;
4165 :
4166 : #undef newval
4167 : }
4168 : }
4169 :
4170 687606 : if (changeVal && (record->flags & GUC_REPORT) &&
4171 369652 : !(record->status & GUC_NEEDS_REPORT))
4172 : {
4173 149534 : record->status |= GUC_NEEDS_REPORT;
4174 149534 : slist_push_head(&guc_report_list, &record->report_link);
4175 : }
4176 :
4177 687606 : return changeVal ? 1 : -1;
4178 : }
4179 :
4180 :
4181 : /*
4182 : * Retrieve a config_handle for the given name, suitable for calling
4183 : * set_config_with_handle(). Only return handle to permanent GUC.
4184 : */
4185 : config_handle *
4186 78 : get_config_handle(const char *name)
4187 : {
4188 78 : struct config_generic *gen = find_option(name, false, false, 0);
4189 :
4190 78 : if (gen && ((gen->flags & GUC_CUSTOM_PLACEHOLDER) == 0))
4191 78 : return gen;
4192 :
4193 0 : return NULL;
4194 : }
4195 :
4196 :
4197 : /*
4198 : * Set the fields for source file and line number the setting came from.
4199 : */
4200 : static void
4201 93683 : set_config_sourcefile(const char *name, char *sourcefile, int sourceline)
4202 : {
4203 : struct config_generic *record;
4204 : int elevel;
4205 :
4206 : /*
4207 : * To avoid cluttering the log, only the postmaster bleats loudly about
4208 : * problems with the config file.
4209 : */
4210 93683 : elevel = IsUnderPostmaster ? DEBUG3 : LOG;
4211 :
4212 93683 : record = find_option(name, true, false, elevel);
4213 : /* should not happen */
4214 93683 : if (record == NULL)
4215 0 : return;
4216 :
4217 93683 : sourcefile = guc_strdup(elevel, sourcefile);
4218 93683 : guc_free(record->sourcefile);
4219 93683 : record->sourcefile = sourcefile;
4220 93683 : record->sourceline = sourceline;
4221 : }
4222 :
4223 : /*
4224 : * Set a config option to the given value.
4225 : *
4226 : * See also set_config_option; this is just the wrapper to be called from
4227 : * outside GUC. (This function should be used when possible, because its API
4228 : * is more stable than set_config_option's.)
4229 : *
4230 : * Note: there is no support here for setting source file/line, as it
4231 : * is currently not needed.
4232 : */
4233 : void
4234 179204 : SetConfigOption(const char *name, const char *value,
4235 : GucContext context, GucSource source)
4236 : {
4237 179204 : (void) set_config_option(name, value, context, source,
4238 : GUC_ACTION_SET, true, 0, false);
4239 179177 : }
4240 :
4241 :
4242 :
4243 : /*
4244 : * Fetch the current value of the option `name', as a string.
4245 : *
4246 : * If the option doesn't exist, return NULL if missing_ok is true,
4247 : * otherwise throw an ereport and don't return.
4248 : *
4249 : * If restrict_privileged is true, we also enforce that only superusers and
4250 : * members of the pg_read_all_settings role can see GUC_SUPERUSER_ONLY
4251 : * variables. This should only be passed as true in user-driven calls.
4252 : *
4253 : * The string is *not* allocated for modification and is really only
4254 : * valid until the next call to configuration related functions.
4255 : */
4256 : const char *
4257 8189 : GetConfigOption(const char *name, bool missing_ok, bool restrict_privileged)
4258 : {
4259 : struct config_generic *record;
4260 : static char buffer[256];
4261 :
4262 8189 : record = find_option(name, false, missing_ok, ERROR);
4263 8189 : if (record == NULL)
4264 1 : return NULL;
4265 8188 : if (restrict_privileged &&
4266 0 : !ConfigOptionIsVisible(record))
4267 0 : ereport(ERROR,
4268 : (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
4269 : errmsg("permission denied to examine \"%s\"", name),
4270 : errdetail("Only roles with privileges of the \"%s\" role may examine this parameter.",
4271 : "pg_read_all_settings")));
4272 :
4273 8188 : switch (record->vartype)
4274 : {
4275 1393 : case PGC_BOOL:
4276 1393 : return *record->_bool.variable ? "on" : "off";
4277 :
4278 2093 : case PGC_INT:
4279 2093 : snprintf(buffer, sizeof(buffer), "%d",
4280 2093 : *record->_int.variable);
4281 2093 : return buffer;
4282 :
4283 2 : case PGC_REAL:
4284 2 : snprintf(buffer, sizeof(buffer), "%g",
4285 2 : *record->_real.variable);
4286 2 : return buffer;
4287 :
4288 3986 : case PGC_STRING:
4289 3986 : return *record->_string.variable ?
4290 3986 : *record->_string.variable : "";
4291 :
4292 714 : case PGC_ENUM:
4293 714 : return config_enum_lookup_by_value(record,
4294 714 : *record->_enum.variable);
4295 : }
4296 0 : return NULL;
4297 : }
4298 :
4299 : /*
4300 : * Get the RESET value associated with the given option.
4301 : *
4302 : * Note: this is not re-entrant, due to use of static result buffer;
4303 : * not to mention that a string variable could have its reset_val changed.
4304 : * Beware of assuming the result value is good for very long.
4305 : */
4306 : const char *
4307 0 : GetConfigOptionResetString(const char *name)
4308 : {
4309 : struct config_generic *record;
4310 : static char buffer[256];
4311 :
4312 0 : record = find_option(name, false, false, ERROR);
4313 : Assert(record != NULL);
4314 0 : if (!ConfigOptionIsVisible(record))
4315 0 : ereport(ERROR,
4316 : (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
4317 : errmsg("permission denied to examine \"%s\"", name),
4318 : errdetail("Only roles with privileges of the \"%s\" role may examine this parameter.",
4319 : "pg_read_all_settings")));
4320 :
4321 0 : switch (record->vartype)
4322 : {
4323 0 : case PGC_BOOL:
4324 0 : return record->_bool.reset_val ? "on" : "off";
4325 :
4326 0 : case PGC_INT:
4327 0 : snprintf(buffer, sizeof(buffer), "%d",
4328 : record->_int.reset_val);
4329 0 : return buffer;
4330 :
4331 0 : case PGC_REAL:
4332 0 : snprintf(buffer, sizeof(buffer), "%g",
4333 : record->_real.reset_val);
4334 0 : return buffer;
4335 :
4336 0 : case PGC_STRING:
4337 0 : return record->_string.reset_val ?
4338 0 : record->_string.reset_val : "";
4339 :
4340 0 : case PGC_ENUM:
4341 0 : return config_enum_lookup_by_value(record,
4342 : record->_enum.reset_val);
4343 : }
4344 0 : return NULL;
4345 : }
4346 :
4347 : /*
4348 : * Get the GUC flags associated with the given option.
4349 : *
4350 : * If the option doesn't exist, return 0 if missing_ok is true,
4351 : * otherwise throw an ereport and don't return.
4352 : */
4353 : int
4354 50 : GetConfigOptionFlags(const char *name, bool missing_ok)
4355 : {
4356 : struct config_generic *record;
4357 :
4358 50 : record = find_option(name, false, missing_ok, ERROR);
4359 50 : if (record == NULL)
4360 0 : return 0;
4361 50 : return record->flags;
4362 : }
4363 :
4364 :
4365 : /*
4366 : * Write updated configuration parameter values into a temporary file.
4367 : * This function traverses the list of parameters and quotes the string
4368 : * values before writing them.
4369 : */
4370 : static void
4371 88 : write_auto_conf_file(int fd, const char *filename, ConfigVariable *head)
4372 : {
4373 : StringInfoData buf;
4374 :
4375 88 : initStringInfo(&buf);
4376 :
4377 : /* Emit file header containing warning comment */
4378 88 : appendStringInfoString(&buf, "# Do not edit this file manually!\n");
4379 88 : appendStringInfoString(&buf, "# It will be overwritten by the ALTER SYSTEM command.\n");
4380 :
4381 88 : errno = 0;
4382 88 : if (write(fd, buf.data, buf.len) != buf.len)
4383 : {
4384 : /* if write didn't set errno, assume problem is no disk space */
4385 0 : if (errno == 0)
4386 0 : errno = ENOSPC;
4387 0 : ereport(ERROR,
4388 : (errcode_for_file_access(),
4389 : errmsg("could not write to file \"%s\": %m", filename)));
4390 : }
4391 :
4392 : /* Emit each parameter, properly quoting the value */
4393 199 : for (ConfigVariable *item = head; item != NULL; item = item->next)
4394 : {
4395 : char *escaped;
4396 :
4397 111 : resetStringInfo(&buf);
4398 :
4399 111 : appendStringInfoString(&buf, item->name);
4400 111 : appendStringInfoString(&buf, " = '");
4401 :
4402 111 : escaped = escape_single_quotes_ascii(item->value);
4403 111 : if (!escaped)
4404 0 : ereport(ERROR,
4405 : (errcode(ERRCODE_OUT_OF_MEMORY),
4406 : errmsg("out of memory")));
4407 111 : appendStringInfoString(&buf, escaped);
4408 111 : free(escaped);
4409 :
4410 111 : appendStringInfoString(&buf, "'\n");
4411 :
4412 111 : errno = 0;
4413 111 : if (write(fd, buf.data, buf.len) != buf.len)
4414 : {
4415 : /* if write didn't set errno, assume problem is no disk space */
4416 0 : if (errno == 0)
4417 0 : errno = ENOSPC;
4418 0 : ereport(ERROR,
4419 : (errcode_for_file_access(),
4420 : errmsg("could not write to file \"%s\": %m", filename)));
4421 : }
4422 : }
4423 :
4424 : /* fsync before considering the write to be successful */
4425 88 : if (pg_fsync(fd) != 0)
4426 0 : ereport(ERROR,
4427 : (errcode_for_file_access(),
4428 : errmsg("could not fsync file \"%s\": %m", filename)));
4429 :
4430 88 : pfree(buf.data);
4431 88 : }
4432 :
4433 : /*
4434 : * Update the given list of configuration parameters, adding, replacing
4435 : * or deleting the entry for item "name" (delete if "value" == NULL).
4436 : */
4437 : static void
4438 88 : replace_auto_config_value(ConfigVariable **head_p, ConfigVariable **tail_p,
4439 : const char *name, const char *value)
4440 : {
4441 : ConfigVariable *newitem,
4442 : *next,
4443 88 : *prev = NULL;
4444 :
4445 : /*
4446 : * Remove any existing match(es) for "name". Normally there'd be at most
4447 : * one, but if external tools have modified the config file, there could
4448 : * be more.
4449 : */
4450 176 : for (ConfigVariable *item = *head_p; item != NULL; item = next)
4451 : {
4452 88 : next = item->next;
4453 88 : if (guc_name_compare(item->name, name) == 0)
4454 : {
4455 : /* found a match, delete it */
4456 43 : if (prev)
4457 6 : prev->next = next;
4458 : else
4459 37 : *head_p = next;
4460 43 : if (next == NULL)
4461 40 : *tail_p = prev;
4462 :
4463 43 : pfree(item->name);
4464 43 : pfree(item->value);
4465 43 : pfree(item->filename);
4466 43 : pfree(item);
4467 : }
4468 : else
4469 45 : prev = item;
4470 : }
4471 :
4472 : /* Done if we're trying to delete it */
4473 88 : if (value == NULL)
4474 22 : return;
4475 :
4476 : /* OK, append a new entry */
4477 66 : newitem = palloc_object(ConfigVariable);
4478 66 : newitem->name = pstrdup(name);
4479 66 : newitem->value = pstrdup(value);
4480 66 : newitem->errmsg = NULL;
4481 66 : newitem->filename = pstrdup(""); /* new item has no location */
4482 66 : newitem->sourceline = 0;
4483 66 : newitem->ignore = false;
4484 66 : newitem->applied = false;
4485 66 : newitem->next = NULL;
4486 :
4487 66 : if (*head_p == NULL)
4488 48 : *head_p = newitem;
4489 : else
4490 18 : (*tail_p)->next = newitem;
4491 66 : *tail_p = newitem;
4492 : }
4493 :
4494 :
4495 : /*
4496 : * Execute ALTER SYSTEM statement.
4497 : *
4498 : * Read the old PG_AUTOCONF_FILENAME file, merge in the new variable value,
4499 : * and write out an updated file. If the command is ALTER SYSTEM RESET ALL,
4500 : * we can skip reading the old file and just write an empty file.
4501 : *
4502 : * An LWLock is used to serialize updates of the configuration file.
4503 : *
4504 : * In case of an error, we leave the original automatic
4505 : * configuration file (PG_AUTOCONF_FILENAME) intact.
4506 : */
4507 : void
4508 118 : AlterSystemSetConfigFile(AlterSystemStmt *altersysstmt)
4509 : {
4510 : char *name;
4511 : char *value;
4512 118 : bool resetall = false;
4513 118 : ConfigVariable *head = NULL;
4514 118 : ConfigVariable *tail = NULL;
4515 : volatile int Tmpfd;
4516 : char AutoConfFileName[MAXPGPATH];
4517 : char AutoConfTmpFileName[MAXPGPATH];
4518 :
4519 : /*
4520 : * Extract statement arguments
4521 : */
4522 118 : name = altersysstmt->setstmt->name;
4523 :
4524 118 : if (!AllowAlterSystem)
4525 0 : ereport(ERROR,
4526 : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4527 : errmsg("ALTER SYSTEM is not allowed in this environment")));
4528 :
4529 118 : switch (altersysstmt->setstmt->kind)
4530 : {
4531 89 : case VAR_SET_VALUE:
4532 89 : value = ExtractSetVariableArgs(altersysstmt->setstmt);
4533 89 : break;
4534 :
4535 28 : case VAR_SET_DEFAULT:
4536 : case VAR_RESET:
4537 28 : value = NULL;
4538 28 : break;
4539 :
4540 1 : case VAR_RESET_ALL:
4541 1 : value = NULL;
4542 1 : resetall = true;
4543 1 : break;
4544 :
4545 0 : default:
4546 0 : elog(ERROR, "unrecognized alter system stmt type: %d",
4547 : altersysstmt->setstmt->kind);
4548 : break;
4549 : }
4550 :
4551 : /*
4552 : * Check permission to run ALTER SYSTEM on the target variable
4553 : */
4554 118 : if (!superuser())
4555 : {
4556 23 : if (resetall)
4557 1 : ereport(ERROR,
4558 : (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
4559 : errmsg("permission denied to perform ALTER SYSTEM RESET ALL")));
4560 : else
4561 : {
4562 : AclResult aclresult;
4563 :
4564 22 : aclresult = pg_parameter_aclcheck(name, GetUserId(),
4565 : ACL_ALTER_SYSTEM);
4566 22 : if (aclresult != ACLCHECK_OK)
4567 13 : ereport(ERROR,
4568 : (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
4569 : errmsg("permission denied to set parameter \"%s\"",
4570 : name)));
4571 : }
4572 : }
4573 :
4574 : /*
4575 : * Unless it's RESET_ALL, validate the target variable and value
4576 : */
4577 104 : if (!resetall)
4578 : {
4579 : struct config_generic *record;
4580 :
4581 : /* We don't want to create a placeholder if there's not one already */
4582 104 : record = find_option(name, false, true, DEBUG5);
4583 104 : if (record != NULL)
4584 : {
4585 : /*
4586 : * Don't allow parameters that can't be set in configuration files
4587 : * to be set in PG_AUTOCONF_FILENAME file.
4588 : */
4589 102 : if ((record->context == PGC_INTERNAL) ||
4590 100 : (record->flags & GUC_DISALLOW_IN_FILE) ||
4591 96 : (record->flags & GUC_DISALLOW_IN_AUTO_FILE))
4592 6 : ereport(ERROR,
4593 : (errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
4594 : errmsg("parameter \"%s\" cannot be changed",
4595 : name)));
4596 :
4597 : /*
4598 : * If a value is specified, verify that it's sane.
4599 : */
4600 96 : if (value)
4601 : {
4602 : union config_var_val newval;
4603 75 : void *newextra = NULL;
4604 :
4605 75 : if (!parse_and_validate_value(record, value,
4606 : PGC_S_FILE, ERROR,
4607 : &newval, &newextra))
4608 0 : ereport(ERROR,
4609 : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4610 : errmsg("invalid value for parameter \"%s\": \"%s\"",
4611 : name, value)));
4612 :
4613 65 : if (record->vartype == PGC_STRING && newval.stringval != NULL)
4614 31 : guc_free(newval.stringval);
4615 65 : guc_free(newextra);
4616 : }
4617 : }
4618 : else
4619 : {
4620 : /*
4621 : * Variable not known; check we'd be allowed to create it. (We
4622 : * cannot validate the value, but that's fine. A non-core GUC in
4623 : * the config file cannot cause postmaster start to fail, so we
4624 : * don't have to be too tense about possibly installing a bad
4625 : * value.)
4626 : *
4627 : * As an exception, we skip this check if this is a RESET command
4628 : * for an unknown custom GUC, else there'd be no way for users to
4629 : * remove such settings with reserved prefixes.
4630 : */
4631 2 : if (value || !valid_custom_variable_name(name))
4632 1 : (void) assignable_custom_variable_name(name, false, ERROR);
4633 : }
4634 :
4635 : /*
4636 : * We must also reject values containing newlines, because the grammar
4637 : * for config files doesn't support embedded newlines in string
4638 : * literals.
4639 : */
4640 88 : if (value && strchr(value, '\n'))
4641 0 : ereport(ERROR,
4642 : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4643 : errmsg("parameter value for ALTER SYSTEM must not contain a newline")));
4644 : }
4645 :
4646 : /*
4647 : * PG_AUTOCONF_FILENAME and its corresponding temporary file are always in
4648 : * the data directory, so we can reference them by simple relative paths.
4649 : */
4650 88 : snprintf(AutoConfFileName, sizeof(AutoConfFileName), "%s",
4651 : PG_AUTOCONF_FILENAME);
4652 88 : snprintf(AutoConfTmpFileName, sizeof(AutoConfTmpFileName), "%s.%s",
4653 : AutoConfFileName,
4654 : "tmp");
4655 :
4656 : /*
4657 : * Only one backend is allowed to operate on PG_AUTOCONF_FILENAME at a
4658 : * time. Use AutoFileLock to ensure that. We must hold the lock while
4659 : * reading the old file contents.
4660 : */
4661 88 : LWLockAcquire(AutoFileLock, LW_EXCLUSIVE);
4662 :
4663 : /*
4664 : * If we're going to reset everything, then no need to open or parse the
4665 : * old file. We'll just write out an empty list.
4666 : */
4667 88 : if (!resetall)
4668 : {
4669 : struct stat st;
4670 :
4671 88 : if (stat(AutoConfFileName, &st) == 0)
4672 : {
4673 : /* open old file PG_AUTOCONF_FILENAME */
4674 : FILE *infile;
4675 :
4676 88 : infile = AllocateFile(AutoConfFileName, "r");
4677 88 : if (infile == NULL)
4678 0 : ereport(ERROR,
4679 : (errcode_for_file_access(),
4680 : errmsg("could not open file \"%s\": %m",
4681 : AutoConfFileName)));
4682 :
4683 : /* parse it */
4684 88 : if (!ParseConfigFp(infile, AutoConfFileName, CONF_FILE_START_DEPTH,
4685 : LOG, &head, &tail))
4686 0 : ereport(ERROR,
4687 : (errcode(ERRCODE_CONFIG_FILE_ERROR),
4688 : errmsg("could not parse contents of file \"%s\"",
4689 : AutoConfFileName)));
4690 :
4691 88 : FreeFile(infile);
4692 : }
4693 :
4694 : /*
4695 : * Now, replace any existing entry with the new value, or add it if
4696 : * not present.
4697 : */
4698 88 : replace_auto_config_value(&head, &tail, name, value);
4699 : }
4700 :
4701 : /*
4702 : * Invoke the post-alter hook for setting this GUC variable. GUCs
4703 : * typically do not have corresponding entries in pg_parameter_acl, so we
4704 : * call the hook using the name rather than a potentially-non-existent
4705 : * OID. Nonetheless, we pass ParameterAclRelationId so that this call
4706 : * context can be distinguished from others. (Note that "name" will be
4707 : * NULL in the RESET ALL case.)
4708 : *
4709 : * We do this here rather than at the end, because ALTER SYSTEM is not
4710 : * transactional. If the hook aborts our transaction, it will be cleaner
4711 : * to do so before we touch any files.
4712 : */
4713 88 : InvokeObjectPostAlterHookArgStr(ParameterAclRelationId, name,
4714 : ACL_ALTER_SYSTEM,
4715 : altersysstmt->setstmt->kind,
4716 : false);
4717 :
4718 : /*
4719 : * To ensure crash safety, first write the new file data to a temp file,
4720 : * then atomically rename it into place.
4721 : *
4722 : * If there is a temp file left over due to a previous crash, it's okay to
4723 : * truncate and reuse it.
4724 : */
4725 88 : Tmpfd = BasicOpenFile(AutoConfTmpFileName,
4726 : O_CREAT | O_RDWR | O_TRUNC);
4727 88 : if (Tmpfd < 0)
4728 0 : ereport(ERROR,
4729 : (errcode_for_file_access(),
4730 : errmsg("could not open file \"%s\": %m",
4731 : AutoConfTmpFileName)));
4732 :
4733 : /*
4734 : * Use a TRY block to clean up the file if we fail. Since we need a TRY
4735 : * block anyway, OK to use BasicOpenFile rather than OpenTransientFile.
4736 : */
4737 88 : PG_TRY();
4738 : {
4739 : /* Write and sync the new contents to the temporary file */
4740 88 : write_auto_conf_file(Tmpfd, AutoConfTmpFileName, head);
4741 :
4742 : /* Close before renaming; may be required on some platforms */
4743 88 : close(Tmpfd);
4744 88 : Tmpfd = -1;
4745 :
4746 : /*
4747 : * As the rename is atomic operation, if any problem occurs after this
4748 : * at worst it can lose the parameters set by last ALTER SYSTEM
4749 : * command.
4750 : */
4751 88 : durable_rename(AutoConfTmpFileName, AutoConfFileName, ERROR);
4752 : }
4753 0 : PG_CATCH();
4754 : {
4755 : /* Close file first, else unlink might fail on some platforms */
4756 0 : if (Tmpfd >= 0)
4757 0 : close(Tmpfd);
4758 :
4759 : /* Unlink, but ignore any error */
4760 0 : (void) unlink(AutoConfTmpFileName);
4761 :
4762 0 : PG_RE_THROW();
4763 : }
4764 88 : PG_END_TRY();
4765 :
4766 88 : FreeConfigVariables(head);
4767 :
4768 88 : LWLockRelease(AutoFileLock);
4769 88 : }
4770 :
4771 :
4772 : /*
4773 : * Common code for DefineCustomXXXVariable subroutines: allocate the
4774 : * new variable's config struct and fill in generic fields.
4775 : */
4776 : static struct config_generic *
4777 12315 : init_custom_variable(const char *name,
4778 : const char *short_desc,
4779 : const char *long_desc,
4780 : GucContext context,
4781 : int flags,
4782 : enum config_type type)
4783 : {
4784 : struct config_generic *gen;
4785 :
4786 : /*
4787 : * Only allow custom PGC_POSTMASTER variables to be created during shared
4788 : * library preload; any later than that, we can't ensure that the value
4789 : * doesn't change after startup. This is a fatal elog if it happens; just
4790 : * erroring out isn't safe because we don't know what the calling loadable
4791 : * module might already have hooked into.
4792 : */
4793 12315 : if (context == PGC_POSTMASTER &&
4794 12 : !process_shared_preload_libraries_in_progress)
4795 0 : elog(FATAL, "cannot create PGC_POSTMASTER variables after startup");
4796 :
4797 : /*
4798 : * We can't support custom GUC_LIST_QUOTE variables, because the wrong
4799 : * things would happen if such a variable were set or pg_dump'd when the
4800 : * defining extension isn't loaded. Again, treat this as fatal because
4801 : * the loadable module may be partly initialized already.
4802 : */
4803 12315 : if (flags & GUC_LIST_QUOTE)
4804 0 : elog(FATAL, "extensions cannot define GUC_LIST_QUOTE variables");
4805 :
4806 : /*
4807 : * Before pljava commit 398f3b876ed402bdaec8bc804f29e2be95c75139
4808 : * (2015-12-15), two of that module's PGC_USERSET variables facilitated
4809 : * trivial escalation to superuser privileges. Restrict the variables to
4810 : * protect sites that have yet to upgrade pljava.
4811 : */
4812 12315 : if (context == PGC_USERSET &&
4813 9509 : (strcmp(name, "pljava.classpath") == 0 ||
4814 9509 : strcmp(name, "pljava.vmoptions") == 0))
4815 0 : context = PGC_SUSET;
4816 :
4817 : /* As above, an OOM here is FATAL */
4818 12315 : gen = (struct config_generic *) guc_malloc(FATAL, sizeof(struct config_generic));
4819 12315 : memset(gen, 0, sizeof(struct config_generic));
4820 :
4821 12315 : gen->name = guc_strdup(FATAL, name);
4822 12315 : gen->context = context;
4823 12315 : gen->group = CUSTOM_OPTIONS;
4824 12315 : gen->short_desc = short_desc;
4825 12315 : gen->long_desc = long_desc;
4826 12315 : gen->flags = flags;
4827 12315 : gen->vartype = type;
4828 :
4829 12315 : return gen;
4830 : }
4831 :
4832 : /*
4833 : * Common code for DefineCustomXXXVariable subroutines: insert the new
4834 : * variable into the GUC variable hash, replacing any placeholder.
4835 : */
4836 : static void
4837 12315 : define_custom_variable(struct config_generic *variable)
4838 : {
4839 12315 : const char *name = variable->name;
4840 : GUCHashEntry *hentry;
4841 : struct config_generic *pHolder;
4842 :
4843 : /* Check mapping between initial and default value */
4844 : Assert(check_GUC_init(variable));
4845 :
4846 : /*
4847 : * See if there's a placeholder by the same name.
4848 : */
4849 12315 : hentry = (GUCHashEntry *) hash_search(guc_hashtab,
4850 : &name,
4851 : HASH_FIND,
4852 : NULL);
4853 12315 : if (hentry == NULL)
4854 : {
4855 : /*
4856 : * No placeholder to replace, so we can just add it ... but first,
4857 : * make sure it's initialized to its default value.
4858 : */
4859 12245 : InitializeOneGUCOption(variable);
4860 12245 : add_guc_variable(variable, ERROR);
4861 12245 : return;
4862 : }
4863 :
4864 : /*
4865 : * This better be a placeholder
4866 : */
4867 70 : if ((hentry->gucvar->flags & GUC_CUSTOM_PLACEHOLDER) == 0)
4868 0 : ereport(ERROR,
4869 : (errcode(ERRCODE_INTERNAL_ERROR),
4870 : errmsg("attempt to redefine parameter \"%s\"", name)));
4871 :
4872 : Assert(hentry->gucvar->vartype == PGC_STRING);
4873 70 : pHolder = hentry->gucvar;
4874 :
4875 : /*
4876 : * First, set the variable to its default value. We must do this even
4877 : * though we intend to immediately apply a new value, since it's possible
4878 : * that the new value is invalid.
4879 : */
4880 70 : InitializeOneGUCOption(variable);
4881 :
4882 : /*
4883 : * Replace the placeholder in the hash table. We aren't changing the name
4884 : * (at least up to case-folding), so the hash value is unchanged.
4885 : */
4886 70 : hentry->gucname = name;
4887 70 : hentry->gucvar = variable;
4888 :
4889 : /*
4890 : * Remove the placeholder from any lists it's in, too.
4891 : */
4892 70 : RemoveGUCFromLists(pHolder);
4893 :
4894 : /*
4895 : * Assign the string value(s) stored in the placeholder to the real
4896 : * variable. Essentially, we need to duplicate all the active and stacked
4897 : * values, but with appropriate validation and datatype adjustment.
4898 : *
4899 : * If an assignment fails, we report a WARNING and keep going. We don't
4900 : * want to throw ERROR for bad values, because it'd bollix the add-on
4901 : * module that's presumably halfway through getting loaded. In such cases
4902 : * the default or previous state will become active instead.
4903 : */
4904 :
4905 : /* First, apply the reset value if any */
4906 70 : if (pHolder->_string.reset_val)
4907 67 : (void) set_config_option_ext(name, pHolder->_string.reset_val,
4908 : pHolder->reset_scontext,
4909 : pHolder->reset_source,
4910 : pHolder->reset_srole,
4911 : GUC_ACTION_SET, true, WARNING, false);
4912 : /* That should not have resulted in stacking anything */
4913 : Assert(variable->stack == NULL);
4914 :
4915 : /* Now, apply current and stacked values, in the order they were stacked */
4916 70 : reapply_stacked_values(variable, pHolder, pHolder->stack,
4917 70 : *(pHolder->_string.variable),
4918 : pHolder->scontext, pHolder->source,
4919 : pHolder->srole);
4920 :
4921 : /* Also copy over any saved source-location information */
4922 70 : if (pHolder->sourcefile)
4923 58 : set_config_sourcefile(name, pHolder->sourcefile,
4924 : pHolder->sourceline);
4925 :
4926 : /* Now we can free the no-longer-referenced placeholder variable */
4927 70 : free_placeholder(pHolder);
4928 : }
4929 :
4930 : /*
4931 : * Recursive subroutine for define_custom_variable: reapply non-reset values
4932 : *
4933 : * We recurse so that the values are applied in the same order as originally.
4934 : * At each recursion level, apply the upper-level value (passed in) in the
4935 : * fashion implied by the stack entry.
4936 : */
4937 : static void
4938 70 : reapply_stacked_values(struct config_generic *variable,
4939 : struct config_generic *pHolder,
4940 : GucStack *stack,
4941 : const char *curvalue,
4942 : GucContext curscontext, GucSource cursource,
4943 : Oid cursrole)
4944 : {
4945 70 : const char *name = variable->name;
4946 70 : GucStack *oldvarstack = variable->stack;
4947 :
4948 70 : if (stack != NULL)
4949 : {
4950 : /* First, recurse, so that stack items are processed bottom to top */
4951 0 : reapply_stacked_values(variable, pHolder, stack->prev,
4952 0 : stack->prior.val.stringval,
4953 : stack->scontext, stack->source, stack->srole);
4954 :
4955 : /* See how to apply the passed-in value */
4956 0 : switch (stack->state)
4957 : {
4958 0 : case GUC_SAVE:
4959 0 : (void) set_config_option_ext(name, curvalue,
4960 : curscontext, cursource, cursrole,
4961 : GUC_ACTION_SAVE, true,
4962 : WARNING, false);
4963 0 : break;
4964 :
4965 0 : case GUC_SET:
4966 0 : (void) set_config_option_ext(name, curvalue,
4967 : curscontext, cursource, cursrole,
4968 : GUC_ACTION_SET, true,
4969 : WARNING, false);
4970 0 : break;
4971 :
4972 0 : case GUC_LOCAL:
4973 0 : (void) set_config_option_ext(name, curvalue,
4974 : curscontext, cursource, cursrole,
4975 : GUC_ACTION_LOCAL, true,
4976 : WARNING, false);
4977 0 : break;
4978 :
4979 0 : case GUC_SET_LOCAL:
4980 : /* first, apply the masked value as SET */
4981 0 : (void) set_config_option_ext(name, stack->masked.val.stringval,
4982 : stack->masked_scontext,
4983 : PGC_S_SESSION,
4984 : stack->masked_srole,
4985 : GUC_ACTION_SET, true,
4986 : WARNING, false);
4987 : /* then apply the current value as LOCAL */
4988 0 : (void) set_config_option_ext(name, curvalue,
4989 : curscontext, cursource, cursrole,
4990 : GUC_ACTION_LOCAL, true,
4991 : WARNING, false);
4992 0 : break;
4993 : }
4994 :
4995 : /* If we successfully made a stack entry, adjust its nest level */
4996 0 : if (variable->stack != oldvarstack)
4997 0 : variable->stack->nest_level = stack->nest_level;
4998 : }
4999 : else
5000 : {
5001 : /*
5002 : * We are at the end of the stack. If the active/previous value is
5003 : * different from the reset value, it must represent a previously
5004 : * committed session value. Apply it, and then drop the stack entry
5005 : * that set_config_option will have created under the impression that
5006 : * this is to be just a transactional assignment. (We leak the stack
5007 : * entry.)
5008 : */
5009 70 : if (curvalue != pHolder->_string.reset_val ||
5010 67 : curscontext != pHolder->reset_scontext ||
5011 67 : cursource != pHolder->reset_source ||
5012 67 : cursrole != pHolder->reset_srole)
5013 : {
5014 3 : (void) set_config_option_ext(name, curvalue,
5015 : curscontext, cursource, cursrole,
5016 : GUC_ACTION_SET, true, WARNING, false);
5017 3 : if (variable->stack != NULL)
5018 : {
5019 2 : slist_delete(&guc_stack_list, &variable->stack_link);
5020 2 : variable->stack = NULL;
5021 : }
5022 : }
5023 : }
5024 70 : }
5025 :
5026 : /*
5027 : * Free up a no-longer-referenced placeholder GUC variable.
5028 : *
5029 : * This neglects any stack items, so it's possible for some memory to be
5030 : * leaked. Since this can only happen once per session per variable, it
5031 : * doesn't seem worth spending much code on.
5032 : */
5033 : static void
5034 75 : free_placeholder(struct config_generic *pHolder)
5035 : {
5036 : /* Placeholders are always STRING type, so free their values */
5037 : Assert(pHolder->vartype == PGC_STRING);
5038 75 : set_string_field(pHolder, pHolder->_string.variable, NULL);
5039 75 : set_string_field(pHolder, &pHolder->_string.reset_val, NULL);
5040 :
5041 75 : guc_free(unconstify(char *, pHolder->name));
5042 75 : guc_free(pHolder);
5043 75 : }
5044 :
5045 : /*
5046 : * Functions for extensions to call to define their custom GUC variables.
5047 : */
5048 : void
5049 4940 : DefineCustomBoolVariable(const char *name,
5050 : const char *short_desc,
5051 : const char *long_desc,
5052 : bool *valueAddr,
5053 : bool bootValue,
5054 : GucContext context,
5055 : int flags,
5056 : GucBoolCheckHook check_hook,
5057 : GucBoolAssignHook assign_hook,
5058 : GucShowHook show_hook)
5059 : {
5060 : struct config_generic *var;
5061 :
5062 4940 : var = init_custom_variable(name, short_desc, long_desc, context, flags, PGC_BOOL);
5063 4940 : var->_bool.variable = valueAddr;
5064 4940 : var->_bool.boot_val = bootValue;
5065 4940 : var->_bool.reset_val = bootValue;
5066 4940 : var->_bool.check_hook = check_hook;
5067 4940 : var->_bool.assign_hook = assign_hook;
5068 4940 : var->_bool.show_hook = show_hook;
5069 4940 : define_custom_variable(var);
5070 4940 : }
5071 :
5072 : void
5073 67 : DefineCustomIntVariable(const char *name,
5074 : const char *short_desc,
5075 : const char *long_desc,
5076 : int *valueAddr,
5077 : int bootValue,
5078 : int minValue,
5079 : int maxValue,
5080 : GucContext context,
5081 : int flags,
5082 : GucIntCheckHook check_hook,
5083 : GucIntAssignHook assign_hook,
5084 : GucShowHook show_hook)
5085 : {
5086 : struct config_generic *var;
5087 :
5088 67 : var = init_custom_variable(name, short_desc, long_desc, context, flags, PGC_INT);
5089 67 : var->_int.variable = valueAddr;
5090 67 : var->_int.boot_val = bootValue;
5091 67 : var->_int.reset_val = bootValue;
5092 67 : var->_int.min = minValue;
5093 67 : var->_int.max = maxValue;
5094 67 : var->_int.check_hook = check_hook;
5095 67 : var->_int.assign_hook = assign_hook;
5096 67 : var->_int.show_hook = show_hook;
5097 67 : define_custom_variable(var);
5098 67 : }
5099 :
5100 : void
5101 28 : DefineCustomRealVariable(const char *name,
5102 : const char *short_desc,
5103 : const char *long_desc,
5104 : double *valueAddr,
5105 : double bootValue,
5106 : double minValue,
5107 : double maxValue,
5108 : GucContext context,
5109 : int flags,
5110 : GucRealCheckHook check_hook,
5111 : GucRealAssignHook assign_hook,
5112 : GucShowHook show_hook)
5113 : {
5114 : struct config_generic *var;
5115 :
5116 28 : var = init_custom_variable(name, short_desc, long_desc, context, flags, PGC_REAL);
5117 28 : var->_real.variable = valueAddr;
5118 28 : var->_real.boot_val = bootValue;
5119 28 : var->_real.reset_val = bootValue;
5120 28 : var->_real.min = minValue;
5121 28 : var->_real.max = maxValue;
5122 28 : var->_real.check_hook = check_hook;
5123 28 : var->_real.assign_hook = assign_hook;
5124 28 : var->_real.show_hook = show_hook;
5125 28 : define_custom_variable(var);
5126 28 : }
5127 :
5128 : void
5129 4873 : DefineCustomStringVariable(const char *name,
5130 : const char *short_desc,
5131 : const char *long_desc,
5132 : char **valueAddr,
5133 : const char *bootValue,
5134 : GucContext context,
5135 : int flags,
5136 : GucStringCheckHook check_hook,
5137 : GucStringAssignHook assign_hook,
5138 : GucShowHook show_hook)
5139 : {
5140 : struct config_generic *var;
5141 :
5142 4873 : var = init_custom_variable(name, short_desc, long_desc, context, flags, PGC_STRING);
5143 4873 : var->_string.variable = valueAddr;
5144 4873 : var->_string.boot_val = bootValue;
5145 4873 : var->_string.check_hook = check_hook;
5146 4873 : var->_string.assign_hook = assign_hook;
5147 4873 : var->_string.show_hook = show_hook;
5148 4873 : define_custom_variable(var);
5149 4873 : }
5150 :
5151 : void
5152 2407 : DefineCustomEnumVariable(const char *name,
5153 : const char *short_desc,
5154 : const char *long_desc,
5155 : int *valueAddr,
5156 : int bootValue,
5157 : const struct config_enum_entry *options,
5158 : GucContext context,
5159 : int flags,
5160 : GucEnumCheckHook check_hook,
5161 : GucEnumAssignHook assign_hook,
5162 : GucShowHook show_hook)
5163 : {
5164 : struct config_generic *var;
5165 :
5166 2407 : var = init_custom_variable(name, short_desc, long_desc, context, flags, PGC_ENUM);
5167 2407 : var->_enum.variable = valueAddr;
5168 2407 : var->_enum.boot_val = bootValue;
5169 2407 : var->_enum.reset_val = bootValue;
5170 2407 : var->_enum.options = options;
5171 2407 : var->_enum.check_hook = check_hook;
5172 2407 : var->_enum.assign_hook = assign_hook;
5173 2407 : var->_enum.show_hook = show_hook;
5174 2407 : define_custom_variable(var);
5175 2407 : }
5176 :
5177 : /*
5178 : * Mark the given GUC prefix as "reserved".
5179 : *
5180 : * This deletes any existing placeholders matching the prefix,
5181 : * and then prevents new ones from being created.
5182 : * Extensions should call this after they've defined all of their custom
5183 : * GUCs, to help catch misspelled config-file entries.
5184 : */
5185 : void
5186 2498 : MarkGUCPrefixReserved(const char *className)
5187 : {
5188 2498 : int classLen = strlen(className);
5189 : HASH_SEQ_STATUS status;
5190 : GUCHashEntry *hentry;
5191 : MemoryContext oldcontext;
5192 :
5193 : /*
5194 : * Check for existing placeholders. We must actually remove invalid
5195 : * placeholders, else future parallel worker startups will fail.
5196 : */
5197 2498 : hash_seq_init(&status, guc_hashtab);
5198 1073797 : while ((hentry = (GUCHashEntry *) hash_seq_search(&status)) != NULL)
5199 : {
5200 1071299 : struct config_generic *var = hentry->gucvar;
5201 :
5202 1071299 : if ((var->flags & GUC_CUSTOM_PLACEHOLDER) != 0 &&
5203 16 : strncmp(className, var->name, classLen) == 0 &&
5204 5 : var->name[classLen] == GUC_QUALIFIER_SEPARATOR)
5205 : {
5206 5 : ereport(WARNING,
5207 : (errcode(ERRCODE_INVALID_NAME),
5208 : errmsg("invalid configuration parameter name \"%s\", removing it",
5209 : var->name),
5210 : errdetail("\"%s\" is now a reserved prefix.",
5211 : className)));
5212 : /* Remove it from the hash table */
5213 5 : hash_search(guc_hashtab,
5214 5 : &var->name,
5215 : HASH_REMOVE,
5216 : NULL);
5217 : /* Remove it from any lists it's in, too */
5218 5 : RemoveGUCFromLists(var);
5219 : /* And free it */
5220 5 : free_placeholder(var);
5221 : }
5222 : }
5223 :
5224 : /* And remember the name so we can prevent future mistakes. */
5225 2498 : oldcontext = MemoryContextSwitchTo(GUCMemoryContext);
5226 2498 : reserved_class_prefix = lappend(reserved_class_prefix, pstrdup(className));
5227 2498 : MemoryContextSwitchTo(oldcontext);
5228 2498 : }
5229 :
5230 :
5231 : /*
5232 : * Return an array of modified GUC options to show in EXPLAIN.
5233 : *
5234 : * We only report options related to query planning (marked with GUC_EXPLAIN),
5235 : * with values different from their built-in defaults.
5236 : */
5237 : struct config_generic **
5238 8 : get_explain_guc_options(int *num)
5239 : {
5240 : struct config_generic **result;
5241 : dlist_iter iter;
5242 :
5243 8 : *num = 0;
5244 :
5245 : /*
5246 : * While only a fraction of all the GUC variables are marked GUC_EXPLAIN,
5247 : * it doesn't seem worth dynamically resizing this array.
5248 : */
5249 8 : result = palloc_array(struct config_generic *, hash_get_num_entries(guc_hashtab));
5250 :
5251 : /* We need only consider GUCs with source not PGC_S_DEFAULT */
5252 488 : dlist_foreach(iter, &guc_nondef_list)
5253 : {
5254 480 : struct config_generic *conf = dlist_container(struct config_generic,
5255 : nondef_link, iter.cur);
5256 : bool modified;
5257 :
5258 : /* return only parameters marked for inclusion in explain */
5259 480 : if (!(conf->flags & GUC_EXPLAIN))
5260 464 : continue;
5261 :
5262 : /* return only options visible to the current user */
5263 16 : if (!ConfigOptionIsVisible(conf))
5264 0 : continue;
5265 :
5266 : /* return only options that are different from their boot values */
5267 16 : modified = false;
5268 :
5269 16 : switch (conf->vartype)
5270 : {
5271 8 : case PGC_BOOL:
5272 : {
5273 8 : struct config_bool *lconf = &conf->_bool;
5274 :
5275 8 : modified = (lconf->boot_val != *(lconf->variable));
5276 : }
5277 8 : break;
5278 :
5279 0 : case PGC_INT:
5280 : {
5281 0 : struct config_int *lconf = &conf->_int;
5282 :
5283 0 : modified = (lconf->boot_val != *(lconf->variable));
5284 : }
5285 0 : break;
5286 :
5287 0 : case PGC_REAL:
5288 : {
5289 0 : struct config_real *lconf = &conf->_real;
5290 :
5291 0 : modified = (lconf->boot_val != *(lconf->variable));
5292 : }
5293 0 : break;
5294 :
5295 0 : case PGC_STRING:
5296 : {
5297 0 : struct config_string *lconf = &conf->_string;
5298 :
5299 0 : if (lconf->boot_val == NULL &&
5300 0 : *lconf->variable == NULL)
5301 0 : modified = false;
5302 0 : else if (lconf->boot_val == NULL ||
5303 0 : *lconf->variable == NULL)
5304 0 : modified = true;
5305 : else
5306 0 : modified = (strcmp(lconf->boot_val, *(lconf->variable)) != 0);
5307 : }
5308 0 : break;
5309 :
5310 8 : case PGC_ENUM:
5311 : {
5312 8 : struct config_enum *lconf = &conf->_enum;
5313 :
5314 8 : modified = (lconf->boot_val != *(lconf->variable));
5315 : }
5316 8 : break;
5317 :
5318 0 : default:
5319 0 : elog(ERROR, "unexpected GUC type: %d", conf->vartype);
5320 : }
5321 :
5322 16 : if (!modified)
5323 8 : continue;
5324 :
5325 : /* OK, report it */
5326 8 : result[*num] = conf;
5327 8 : *num = *num + 1;
5328 : }
5329 :
5330 8 : return result;
5331 : }
5332 :
5333 : /*
5334 : * Return GUC variable value by name; optionally return canonical form of
5335 : * name. If the GUC is unset, then throw an error unless missing_ok is true,
5336 : * in which case return NULL. Return value is palloc'd (but *varname isn't).
5337 : */
5338 : char *
5339 7222 : GetConfigOptionByName(const char *name, const char **varname, bool missing_ok)
5340 : {
5341 : struct config_generic *record;
5342 :
5343 7222 : record = find_option(name, false, missing_ok, ERROR);
5344 7197 : if (record == NULL)
5345 : {
5346 4 : if (varname)
5347 0 : *varname = NULL;
5348 4 : return NULL;
5349 : }
5350 :
5351 7193 : if (!ConfigOptionIsVisible(record))
5352 1 : ereport(ERROR,
5353 : (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
5354 : errmsg("permission denied to examine \"%s\"", name),
5355 : errdetail("Only roles with privileges of the \"%s\" role may examine this parameter.",
5356 : "pg_read_all_settings")));
5357 :
5358 7192 : if (varname)
5359 1740 : *varname = record->name;
5360 :
5361 7192 : return ShowGUCOption(record, true);
5362 : }
5363 :
5364 : /*
5365 : * ShowGUCOption: get string value of variable
5366 : *
5367 : * We express a numeric value in appropriate units if it has units and
5368 : * use_units is true; else you just get the raw number.
5369 : * The result string is palloc'd.
5370 : */
5371 : char *
5372 1193474 : ShowGUCOption(const struct config_generic *record, bool use_units)
5373 : {
5374 : char buffer[256];
5375 : const char *val;
5376 :
5377 1193474 : switch (record->vartype)
5378 : {
5379 327186 : case PGC_BOOL:
5380 : {
5381 327186 : const struct config_bool *conf = &record->_bool;
5382 :
5383 327186 : if (conf->show_hook)
5384 17305 : val = conf->show_hook();
5385 : else
5386 309881 : val = *conf->variable ? "on" : "off";
5387 : }
5388 327186 : break;
5389 :
5390 308315 : case PGC_INT:
5391 : {
5392 308315 : const struct config_int *conf = &record->_int;
5393 :
5394 308315 : if (conf->show_hook)
5395 14069 : val = conf->show_hook();
5396 : else
5397 : {
5398 : /*
5399 : * Use int64 arithmetic to avoid overflows in units
5400 : * conversion.
5401 : */
5402 294246 : int64 result = *conf->variable;
5403 : const char *unit;
5404 :
5405 294246 : if (use_units && result > 0 && (record->flags & GUC_UNIT))
5406 423 : convert_int_from_base_unit(result,
5407 423 : record->flags & GUC_UNIT,
5408 : &result, &unit);
5409 : else
5410 293823 : unit = "";
5411 :
5412 294246 : snprintf(buffer, sizeof(buffer), INT64_FORMAT "%s",
5413 : result, unit);
5414 294246 : val = buffer;
5415 : }
5416 : }
5417 308315 : break;
5418 :
5419 60696 : case PGC_REAL:
5420 : {
5421 60696 : const struct config_real *conf = &record->_real;
5422 :
5423 60696 : if (conf->show_hook)
5424 0 : val = conf->show_hook();
5425 : else
5426 : {
5427 60696 : double result = *conf->variable;
5428 : const char *unit;
5429 :
5430 60696 : if (use_units && result > 0 && (record->flags & GUC_UNIT))
5431 178 : convert_real_from_base_unit(result,
5432 178 : record->flags & GUC_UNIT,
5433 : &result, &unit);
5434 : else
5435 60518 : unit = "";
5436 :
5437 60696 : snprintf(buffer, sizeof(buffer), "%g%s",
5438 : result, unit);
5439 60696 : val = buffer;
5440 : }
5441 : }
5442 60696 : break;
5443 :
5444 394511 : case PGC_STRING:
5445 : {
5446 394511 : const struct config_string *conf = &record->_string;
5447 :
5448 394511 : if (conf->show_hook)
5449 35409 : val = conf->show_hook();
5450 359102 : else if (*conf->variable && **conf->variable)
5451 275088 : val = *conf->variable;
5452 : else
5453 84014 : val = "";
5454 : }
5455 394511 : break;
5456 :
5457 102766 : case PGC_ENUM:
5458 : {
5459 102766 : const struct config_enum *conf = &record->_enum;
5460 :
5461 102766 : if (conf->show_hook)
5462 1985 : val = conf->show_hook();
5463 : else
5464 100781 : val = config_enum_lookup_by_value(record, *conf->variable);
5465 : }
5466 102766 : break;
5467 :
5468 0 : default:
5469 : /* just to keep compiler quiet */
5470 0 : val = "???";
5471 0 : break;
5472 : }
5473 :
5474 1193474 : return pstrdup(val);
5475 : }
5476 :
5477 :
5478 : #ifdef EXEC_BACKEND
5479 :
5480 : /*
5481 : * These routines dump out all non-default GUC options into a binary
5482 : * file that is read by all exec'ed backends. The format is:
5483 : *
5484 : * variable name, string, null terminated
5485 : * variable value, string, null terminated
5486 : * variable sourcefile, string, null terminated (empty if none)
5487 : * variable sourceline, integer
5488 : * variable source, integer
5489 : * variable scontext, integer
5490 : * variable srole, OID
5491 : */
5492 : static void
5493 : write_one_nondefault_variable(FILE *fp, struct config_generic *gconf)
5494 : {
5495 : Assert(gconf->source != PGC_S_DEFAULT);
5496 :
5497 : fprintf(fp, "%s", gconf->name);
5498 : fputc(0, fp);
5499 :
5500 : switch (gconf->vartype)
5501 : {
5502 : case PGC_BOOL:
5503 : {
5504 : struct config_bool *conf = &gconf->_bool;
5505 :
5506 : if (*conf->variable)
5507 : fprintf(fp, "true");
5508 : else
5509 : fprintf(fp, "false");
5510 : }
5511 : break;
5512 :
5513 : case PGC_INT:
5514 : {
5515 : struct config_int *conf = &gconf->_int;
5516 :
5517 : fprintf(fp, "%d", *conf->variable);
5518 : }
5519 : break;
5520 :
5521 : case PGC_REAL:
5522 : {
5523 : struct config_real *conf = &gconf->_real;
5524 :
5525 : fprintf(fp, "%.17g", *conf->variable);
5526 : }
5527 : break;
5528 :
5529 : case PGC_STRING:
5530 : {
5531 : struct config_string *conf = &gconf->_string;
5532 :
5533 : if (*conf->variable)
5534 : fprintf(fp, "%s", *conf->variable);
5535 : }
5536 : break;
5537 :
5538 : case PGC_ENUM:
5539 : {
5540 : struct config_enum *conf = &gconf->_enum;
5541 :
5542 : fprintf(fp, "%s",
5543 : config_enum_lookup_by_value(gconf, *conf->variable));
5544 : }
5545 : break;
5546 : }
5547 :
5548 : fputc(0, fp);
5549 :
5550 : if (gconf->sourcefile)
5551 : fprintf(fp, "%s", gconf->sourcefile);
5552 : fputc(0, fp);
5553 :
5554 : fwrite(&gconf->sourceline, 1, sizeof(gconf->sourceline), fp);
5555 : fwrite(&gconf->source, 1, sizeof(gconf->source), fp);
5556 : fwrite(&gconf->scontext, 1, sizeof(gconf->scontext), fp);
5557 : fwrite(&gconf->srole, 1, sizeof(gconf->srole), fp);
5558 : }
5559 :
5560 : void
5561 : write_nondefault_variables(GucContext context)
5562 : {
5563 : int elevel;
5564 : FILE *fp;
5565 : dlist_iter iter;
5566 :
5567 : Assert(context == PGC_POSTMASTER || context == PGC_SIGHUP);
5568 :
5569 : elevel = (context == PGC_SIGHUP) ? LOG : ERROR;
5570 :
5571 : /*
5572 : * Open file
5573 : */
5574 : fp = AllocateFile(CONFIG_EXEC_PARAMS_NEW, "w");
5575 : if (!fp)
5576 : {
5577 : ereport(elevel,
5578 : (errcode_for_file_access(),
5579 : errmsg("could not write to file \"%s\": %m",
5580 : CONFIG_EXEC_PARAMS_NEW)));
5581 : return;
5582 : }
5583 :
5584 : /* We need only consider GUCs with source not PGC_S_DEFAULT */
5585 : dlist_foreach(iter, &guc_nondef_list)
5586 : {
5587 : struct config_generic *gconf = dlist_container(struct config_generic,
5588 : nondef_link, iter.cur);
5589 :
5590 : write_one_nondefault_variable(fp, gconf);
5591 : }
5592 :
5593 : if (FreeFile(fp))
5594 : {
5595 : ereport(elevel,
5596 : (errcode_for_file_access(),
5597 : errmsg("could not write to file \"%s\": %m",
5598 : CONFIG_EXEC_PARAMS_NEW)));
5599 : return;
5600 : }
5601 :
5602 : /*
5603 : * Put new file in place. This could delay on Win32, but we don't hold
5604 : * any exclusive locks.
5605 : */
5606 : rename(CONFIG_EXEC_PARAMS_NEW, CONFIG_EXEC_PARAMS);
5607 : }
5608 :
5609 :
5610 : /*
5611 : * Read string, including null byte from file
5612 : *
5613 : * Return NULL on EOF and nothing read
5614 : */
5615 : static char *
5616 : read_string_with_null(FILE *fp)
5617 : {
5618 : int i = 0,
5619 : ch,
5620 : maxlen = 256;
5621 : char *str = NULL;
5622 :
5623 : do
5624 : {
5625 : if ((ch = fgetc(fp)) == EOF)
5626 : {
5627 : if (i == 0)
5628 : return NULL;
5629 : else
5630 : elog(FATAL, "invalid format of exec config params file");
5631 : }
5632 : if (i == 0)
5633 : str = guc_malloc(FATAL, maxlen);
5634 : else if (i == maxlen)
5635 : str = guc_realloc(FATAL, str, maxlen *= 2);
5636 : str[i++] = ch;
5637 : } while (ch != 0);
5638 :
5639 : return str;
5640 : }
5641 :
5642 :
5643 : /*
5644 : * This routine loads a previous postmaster dump of its non-default
5645 : * settings.
5646 : */
5647 : void
5648 : read_nondefault_variables(void)
5649 : {
5650 : FILE *fp;
5651 : char *varname,
5652 : *varvalue,
5653 : *varsourcefile;
5654 : int varsourceline;
5655 : GucSource varsource;
5656 : GucContext varscontext;
5657 : Oid varsrole;
5658 :
5659 : /*
5660 : * Open file
5661 : */
5662 : fp = AllocateFile(CONFIG_EXEC_PARAMS, "r");
5663 : if (!fp)
5664 : {
5665 : /* File not found is fine */
5666 : if (errno != ENOENT)
5667 : ereport(FATAL,
5668 : (errcode_for_file_access(),
5669 : errmsg("could not read from file \"%s\": %m",
5670 : CONFIG_EXEC_PARAMS)));
5671 : return;
5672 : }
5673 :
5674 : for (;;)
5675 : {
5676 : if ((varname = read_string_with_null(fp)) == NULL)
5677 : break;
5678 :
5679 : if (find_option(varname, true, false, FATAL) == NULL)
5680 : elog(FATAL, "failed to locate variable \"%s\" in exec config params file", varname);
5681 :
5682 : if ((varvalue = read_string_with_null(fp)) == NULL)
5683 : elog(FATAL, "invalid format of exec config params file");
5684 : if ((varsourcefile = read_string_with_null(fp)) == NULL)
5685 : elog(FATAL, "invalid format of exec config params file");
5686 : if (fread(&varsourceline, 1, sizeof(varsourceline), fp) != sizeof(varsourceline))
5687 : elog(FATAL, "invalid format of exec config params file");
5688 : if (fread(&varsource, 1, sizeof(varsource), fp) != sizeof(varsource))
5689 : elog(FATAL, "invalid format of exec config params file");
5690 : if (fread(&varscontext, 1, sizeof(varscontext), fp) != sizeof(varscontext))
5691 : elog(FATAL, "invalid format of exec config params file");
5692 : if (fread(&varsrole, 1, sizeof(varsrole), fp) != sizeof(varsrole))
5693 : elog(FATAL, "invalid format of exec config params file");
5694 :
5695 : (void) set_config_option_ext(varname, varvalue,
5696 : varscontext, varsource, varsrole,
5697 : GUC_ACTION_SET, true, 0, true);
5698 : if (varsourcefile[0])
5699 : set_config_sourcefile(varname, varsourcefile, varsourceline);
5700 :
5701 : guc_free(varname);
5702 : guc_free(varvalue);
5703 : guc_free(varsourcefile);
5704 : }
5705 :
5706 : FreeFile(fp);
5707 : }
5708 : #endif /* EXEC_BACKEND */
5709 :
5710 : /*
5711 : * can_skip_gucvar:
5712 : * Decide whether SerializeGUCState can skip sending this GUC variable,
5713 : * or whether RestoreGUCState can skip resetting this GUC to default.
5714 : *
5715 : * It is somewhat magical and fragile that the same test works for both cases.
5716 : * Realize in particular that we are very likely selecting different sets of
5717 : * GUCs on the leader and worker sides! Be sure you've understood the
5718 : * comments here and in RestoreGUCState thoroughly before changing this.
5719 : */
5720 : static bool
5721 191517 : can_skip_gucvar(struct config_generic *gconf)
5722 : {
5723 : /*
5724 : * We can skip GUCs that are guaranteed to have the same values in leaders
5725 : * and workers. (Note it is critical that the leader and worker have the
5726 : * same idea of which GUCs fall into this category. It's okay to consider
5727 : * context and name for this purpose, since those are unchanging
5728 : * properties of a GUC.)
5729 : *
5730 : * PGC_POSTMASTER variables always have the same value in every child of a
5731 : * particular postmaster, so the worker will certainly have the right
5732 : * value already. Likewise, PGC_INTERNAL variables are set by special
5733 : * mechanisms (if indeed they aren't compile-time constants). So we may
5734 : * always skip these.
5735 : *
5736 : * For all other GUCs, we skip if the GUC has its compiled-in default
5737 : * value (i.e., source == PGC_S_DEFAULT). On the leader side, this means
5738 : * we don't send GUCs that have their default values, which typically
5739 : * saves lots of work. On the worker side, this means we don't need to
5740 : * reset the GUC to default because it already has that value. See
5741 : * comments in RestoreGUCState for more info.
5742 : */
5743 311658 : return gconf->context == PGC_POSTMASTER ||
5744 288068 : gconf->context == PGC_INTERNAL ||
5745 96551 : gconf->source == PGC_S_DEFAULT;
5746 : }
5747 :
5748 : /*
5749 : * estimate_variable_size:
5750 : * Compute space needed for dumping the given GUC variable.
5751 : *
5752 : * It's OK to overestimate, but not to underestimate.
5753 : */
5754 : static Size
5755 42594 : estimate_variable_size(struct config_generic *gconf)
5756 : {
5757 : Size size;
5758 42594 : Size valsize = 0;
5759 :
5760 : /* Skippable GUCs consume zero space. */
5761 42594 : if (can_skip_gucvar(gconf))
5762 19170 : return 0;
5763 :
5764 : /* Name, plus trailing zero byte. */
5765 23424 : size = strlen(gconf->name) + 1;
5766 :
5767 : /* Get the maximum display length of the GUC value. */
5768 23424 : switch (gconf->vartype)
5769 : {
5770 4936 : case PGC_BOOL:
5771 : {
5772 4936 : valsize = 5; /* max(strlen('true'), strlen('false')) */
5773 : }
5774 4936 : break;
5775 :
5776 4600 : case PGC_INT:
5777 : {
5778 4600 : struct config_int *conf = &gconf->_int;
5779 :
5780 : /*
5781 : * Instead of getting the exact display length, use max
5782 : * length. Also reduce the max length for typical ranges of
5783 : * small values. Maximum value is 2147483647, i.e. 10 chars.
5784 : * Include one byte for sign.
5785 : */
5786 4600 : if (abs(*conf->variable) < 1000)
5787 3523 : valsize = 3 + 1;
5788 : else
5789 1077 : valsize = 10 + 1;
5790 : }
5791 4600 : break;
5792 :
5793 1170 : case PGC_REAL:
5794 : {
5795 : /*
5796 : * We are going to print it with %e with REALTYPE_PRECISION
5797 : * fractional digits. Account for sign, leading digit,
5798 : * decimal point, and exponent with up to 3 digits. E.g.
5799 : * -3.99329042340000021e+110
5800 : */
5801 1170 : valsize = 1 + 1 + 1 + REALTYPE_PRECISION + 5;
5802 : }
5803 1170 : break;
5804 :
5805 9877 : case PGC_STRING:
5806 : {
5807 9877 : struct config_string *conf = &gconf->_string;
5808 :
5809 : /*
5810 : * If the value is NULL, we transmit it as an empty string.
5811 : * Although this is not physically the same value, GUC
5812 : * generally treats a NULL the same as empty string.
5813 : */
5814 9877 : if (*conf->variable)
5815 9877 : valsize = strlen(*conf->variable);
5816 : else
5817 0 : valsize = 0;
5818 : }
5819 9877 : break;
5820 :
5821 2841 : case PGC_ENUM:
5822 : {
5823 2841 : struct config_enum *conf = &gconf->_enum;
5824 :
5825 2841 : valsize = strlen(config_enum_lookup_by_value(gconf, *conf->variable));
5826 : }
5827 2841 : break;
5828 : }
5829 :
5830 : /* Allow space for terminating zero-byte for value */
5831 23424 : size = add_size(size, valsize + 1);
5832 :
5833 23424 : if (gconf->sourcefile)
5834 11911 : size = add_size(size, strlen(gconf->sourcefile));
5835 :
5836 : /* Allow space for terminating zero-byte for sourcefile */
5837 23424 : size = add_size(size, 1);
5838 :
5839 : /* Include line whenever file is nonempty. */
5840 23424 : if (gconf->sourcefile && gconf->sourcefile[0])
5841 11911 : size = add_size(size, sizeof(gconf->sourceline));
5842 :
5843 23424 : size = add_size(size, sizeof(gconf->source));
5844 23424 : size = add_size(size, sizeof(gconf->scontext));
5845 23424 : size = add_size(size, sizeof(gconf->srole));
5846 :
5847 23424 : return size;
5848 : }
5849 :
5850 : /*
5851 : * EstimateGUCStateSpace:
5852 : * Returns the size needed to store the GUC state for the current process
5853 : */
5854 : Size
5855 681 : EstimateGUCStateSpace(void)
5856 : {
5857 : Size size;
5858 : dlist_iter iter;
5859 :
5860 : /* Add space reqd for saving the data size of the guc state */
5861 681 : size = sizeof(Size);
5862 :
5863 : /*
5864 : * Add up the space needed for each GUC variable.
5865 : *
5866 : * We need only process non-default GUCs.
5867 : */
5868 43275 : dlist_foreach(iter, &guc_nondef_list)
5869 : {
5870 42594 : struct config_generic *gconf = dlist_container(struct config_generic,
5871 : nondef_link, iter.cur);
5872 :
5873 42594 : size = add_size(size, estimate_variable_size(gconf));
5874 : }
5875 :
5876 681 : return size;
5877 : }
5878 :
5879 : /*
5880 : * do_serialize:
5881 : * Copies the formatted string into the destination. Moves ahead the
5882 : * destination pointer, and decrements the maxbytes by that many bytes. If
5883 : * maxbytes is not sufficient to copy the string, error out.
5884 : */
5885 : static void
5886 70272 : do_serialize(char **destptr, Size *maxbytes, const char *fmt,...)
5887 : {
5888 : va_list vargs;
5889 : int n;
5890 :
5891 70272 : if (*maxbytes <= 0)
5892 0 : elog(ERROR, "not enough space to serialize GUC state");
5893 :
5894 70272 : va_start(vargs, fmt);
5895 70272 : n = vsnprintf(*destptr, *maxbytes, fmt, vargs);
5896 70272 : va_end(vargs);
5897 :
5898 70272 : if (n < 0)
5899 : {
5900 : /* Shouldn't happen. Better show errno description. */
5901 0 : elog(ERROR, "vsnprintf failed: %m with format string \"%s\"", fmt);
5902 : }
5903 70272 : if (n >= *maxbytes)
5904 : {
5905 : /* This shouldn't happen either, really. */
5906 0 : elog(ERROR, "not enough space to serialize GUC state");
5907 : }
5908 :
5909 : /* Shift the destptr ahead of the null terminator */
5910 70272 : *destptr += n + 1;
5911 70272 : *maxbytes -= n + 1;
5912 70272 : }
5913 :
5914 : /* Binary copy version of do_serialize() */
5915 : static void
5916 82183 : do_serialize_binary(char **destptr, Size *maxbytes, void *val, Size valsize)
5917 : {
5918 82183 : if (valsize > *maxbytes)
5919 0 : elog(ERROR, "not enough space to serialize GUC state");
5920 :
5921 82183 : memcpy(*destptr, val, valsize);
5922 82183 : *destptr += valsize;
5923 82183 : *maxbytes -= valsize;
5924 82183 : }
5925 :
5926 : /*
5927 : * serialize_variable:
5928 : * Dumps name, value and other information of a GUC variable into destptr.
5929 : */
5930 : static void
5931 42594 : serialize_variable(char **destptr, Size *maxbytes,
5932 : struct config_generic *gconf)
5933 : {
5934 : /* Ignore skippable GUCs. */
5935 42594 : if (can_skip_gucvar(gconf))
5936 19170 : return;
5937 :
5938 23424 : do_serialize(destptr, maxbytes, "%s", gconf->name);
5939 :
5940 23424 : switch (gconf->vartype)
5941 : {
5942 4936 : case PGC_BOOL:
5943 : {
5944 4936 : struct config_bool *conf = &gconf->_bool;
5945 :
5946 4936 : do_serialize(destptr, maxbytes,
5947 4936 : (*conf->variable ? "true" : "false"));
5948 : }
5949 4936 : break;
5950 :
5951 4600 : case PGC_INT:
5952 : {
5953 4600 : struct config_int *conf = &gconf->_int;
5954 :
5955 4600 : do_serialize(destptr, maxbytes, "%d", *conf->variable);
5956 : }
5957 4600 : break;
5958 :
5959 1170 : case PGC_REAL:
5960 : {
5961 1170 : struct config_real *conf = &gconf->_real;
5962 :
5963 1170 : do_serialize(destptr, maxbytes, "%.*e",
5964 1170 : REALTYPE_PRECISION, *conf->variable);
5965 : }
5966 1170 : break;
5967 :
5968 9877 : case PGC_STRING:
5969 : {
5970 9877 : struct config_string *conf = &gconf->_string;
5971 :
5972 : /* NULL becomes empty string, see estimate_variable_size() */
5973 9877 : do_serialize(destptr, maxbytes, "%s",
5974 9877 : *conf->variable ? *conf->variable : "");
5975 : }
5976 9877 : break;
5977 :
5978 2841 : case PGC_ENUM:
5979 : {
5980 2841 : struct config_enum *conf = &gconf->_enum;
5981 :
5982 2841 : do_serialize(destptr, maxbytes, "%s",
5983 2841 : config_enum_lookup_by_value(gconf, *conf->variable));
5984 : }
5985 2841 : break;
5986 : }
5987 :
5988 23424 : do_serialize(destptr, maxbytes, "%s",
5989 23424 : (gconf->sourcefile ? gconf->sourcefile : ""));
5990 :
5991 23424 : if (gconf->sourcefile && gconf->sourcefile[0])
5992 11911 : do_serialize_binary(destptr, maxbytes, &gconf->sourceline,
5993 : sizeof(gconf->sourceline));
5994 :
5995 23424 : do_serialize_binary(destptr, maxbytes, &gconf->source,
5996 : sizeof(gconf->source));
5997 23424 : do_serialize_binary(destptr, maxbytes, &gconf->scontext,
5998 : sizeof(gconf->scontext));
5999 23424 : do_serialize_binary(destptr, maxbytes, &gconf->srole,
6000 : sizeof(gconf->srole));
6001 : }
6002 :
6003 : /*
6004 : * SerializeGUCState:
6005 : * Dumps the complete GUC state onto the memory location at start_address.
6006 : */
6007 : void
6008 681 : SerializeGUCState(Size maxsize, char *start_address)
6009 : {
6010 : char *curptr;
6011 : Size actual_size;
6012 : Size bytes_left;
6013 : dlist_iter iter;
6014 :
6015 : /* Reserve space for saving the actual size of the guc state */
6016 : Assert(maxsize > sizeof(actual_size));
6017 681 : curptr = start_address + sizeof(actual_size);
6018 681 : bytes_left = maxsize - sizeof(actual_size);
6019 :
6020 : /* We need only consider GUCs with source not PGC_S_DEFAULT */
6021 43275 : dlist_foreach(iter, &guc_nondef_list)
6022 : {
6023 42594 : struct config_generic *gconf = dlist_container(struct config_generic,
6024 : nondef_link, iter.cur);
6025 :
6026 42594 : serialize_variable(&curptr, &bytes_left, gconf);
6027 : }
6028 :
6029 : /* Store actual size without assuming alignment of start_address. */
6030 681 : actual_size = maxsize - bytes_left - sizeof(actual_size);
6031 681 : memcpy(start_address, &actual_size, sizeof(actual_size));
6032 681 : }
6033 :
6034 : /*
6035 : * read_gucstate:
6036 : * Actually it does not read anything, just returns the srcptr. But it does
6037 : * move the srcptr past the terminating zero byte, so that the caller is ready
6038 : * to read the next string.
6039 : */
6040 : static char *
6041 215910 : read_gucstate(char **srcptr, char *srcend)
6042 : {
6043 215910 : char *retptr = *srcptr;
6044 : char *ptr;
6045 :
6046 215910 : if (*srcptr >= srcend)
6047 0 : elog(ERROR, "incomplete GUC state");
6048 :
6049 : /* The string variables are all null terminated */
6050 5634066 : for (ptr = *srcptr; ptr < srcend && *ptr != '\0'; ptr++)
6051 : ;
6052 :
6053 215910 : if (ptr >= srcend)
6054 0 : elog(ERROR, "could not find null terminator in GUC state");
6055 :
6056 : /* Set the new position to the byte following the terminating NUL */
6057 215910 : *srcptr = ptr + 1;
6058 :
6059 215910 : return retptr;
6060 : }
6061 :
6062 : /* Binary read version of read_gucstate(). Copies into dest */
6063 : static void
6064 251039 : read_gucstate_binary(char **srcptr, char *srcend, void *dest, Size size)
6065 : {
6066 251039 : if (*srcptr + size > srcend)
6067 0 : elog(ERROR, "incomplete GUC state");
6068 :
6069 251039 : memcpy(dest, *srcptr, size);
6070 251039 : *srcptr += size;
6071 251039 : }
6072 :
6073 : /*
6074 : * Callback used to add a context message when reporting errors that occur
6075 : * while trying to restore GUCs in parallel workers.
6076 : */
6077 : static void
6078 0 : guc_restore_error_context_callback(void *arg)
6079 : {
6080 0 : char **error_context_name_and_value = (char **) arg;
6081 :
6082 0 : if (error_context_name_and_value)
6083 0 : errcontext("while setting parameter \"%s\" to \"%s\"",
6084 : error_context_name_and_value[0],
6085 0 : error_context_name_and_value[1]);
6086 0 : }
6087 :
6088 : /*
6089 : * RestoreGUCState:
6090 : * Reads the GUC state at the specified address and sets this process's
6091 : * GUCs to match.
6092 : *
6093 : * Note that this provides the worker with only a very shallow view of the
6094 : * leader's GUC state: we'll know about the currently active values, but not
6095 : * about stacked or reset values. That's fine since the worker is just
6096 : * executing one part of a query, within which the active values won't change
6097 : * and the stacked values are invisible.
6098 : */
6099 : void
6100 2008 : RestoreGUCState(void *gucstate)
6101 : {
6102 : char *varname,
6103 : *varvalue,
6104 : *varsourcefile;
6105 : int varsourceline;
6106 : GucSource varsource;
6107 : GucContext varscontext;
6108 : Oid varsrole;
6109 2008 : char *srcptr = (char *) gucstate;
6110 : char *srcend;
6111 : Size len;
6112 : dlist_mutable_iter iter;
6113 : ErrorContextCallback error_context_callback;
6114 :
6115 : /*
6116 : * First, ensure that all potentially-shippable GUCs are reset to their
6117 : * default values. We must not touch those GUCs that the leader will
6118 : * never ship, while there is no need to touch those that are shippable
6119 : * but already have their default values. Thus, this ends up being the
6120 : * same test that SerializeGUCState uses, even though the sets of
6121 : * variables involved may well be different since the leader's set of
6122 : * variables-not-at-default-values can differ from the set that are
6123 : * not-default in this freshly started worker.
6124 : *
6125 : * Once we have set all the potentially-shippable GUCs to default values,
6126 : * restoring the GUCs that the leader sent (because they had non-default
6127 : * values over there) leads us to exactly the set of GUC values that the
6128 : * leader has. This is true even though the worker may have initially
6129 : * absorbed postgresql.conf settings that the leader hasn't yet seen, or
6130 : * ALTER USER/DATABASE SET settings that were established after the leader
6131 : * started.
6132 : *
6133 : * Note that ensuring all the potential target GUCs are at PGC_S_DEFAULT
6134 : * also ensures that set_config_option won't refuse to set them because of
6135 : * source-priority comparisons.
6136 : */
6137 108337 : dlist_foreach_modify(iter, &guc_nondef_list)
6138 : {
6139 106329 : struct config_generic *gconf = dlist_container(struct config_generic,
6140 : nondef_link, iter.cur);
6141 :
6142 : /* Do nothing if non-shippable or if already at PGC_S_DEFAULT. */
6143 106329 : if (can_skip_gucvar(gconf))
6144 56626 : continue;
6145 :
6146 : /*
6147 : * We can use InitializeOneGUCOption to reset the GUC to default, but
6148 : * first we must free any existing subsidiary data to avoid leaking
6149 : * memory. The stack must be empty, but we have to clean up all other
6150 : * fields. Beware that there might be duplicate value or "extra"
6151 : * pointers. We also have to be sure to take it out of any lists it's
6152 : * in.
6153 : */
6154 : Assert(gconf->stack == NULL);
6155 49703 : guc_free(gconf->extra);
6156 49703 : guc_free(gconf->last_reported);
6157 49703 : guc_free(gconf->sourcefile);
6158 49703 : switch (gconf->vartype)
6159 : {
6160 27111 : case PGC_BOOL:
6161 : case PGC_INT:
6162 : case PGC_REAL:
6163 : case PGC_ENUM:
6164 : /* no need to do anything */
6165 27111 : break;
6166 22592 : case PGC_STRING:
6167 : {
6168 22592 : struct config_string *conf = &gconf->_string;
6169 :
6170 22592 : guc_free(*conf->variable);
6171 22592 : if (conf->reset_val && conf->reset_val != *conf->variable)
6172 0 : guc_free(conf->reset_val);
6173 22592 : break;
6174 : }
6175 : }
6176 49703 : if (gconf->reset_extra && gconf->reset_extra != gconf->extra)
6177 0 : guc_free(gconf->reset_extra);
6178 : /* Remove it from any lists it's in. */
6179 49703 : RemoveGUCFromLists(gconf);
6180 : /* Now we can reset the struct to PGS_S_DEFAULT state. */
6181 49703 : InitializeOneGUCOption(gconf);
6182 : }
6183 :
6184 : /* First item is the length of the subsequent data */
6185 2008 : memcpy(&len, gucstate, sizeof(len));
6186 :
6187 2008 : srcptr += sizeof(len);
6188 2008 : srcend = srcptr + len;
6189 :
6190 : /* If the GUC value check fails, we want errors to show useful context. */
6191 2008 : error_context_callback.callback = guc_restore_error_context_callback;
6192 2008 : error_context_callback.previous = error_context_stack;
6193 2008 : error_context_callback.arg = NULL;
6194 2008 : error_context_stack = &error_context_callback;
6195 :
6196 : /* Restore all the listed GUCs. */
6197 73978 : while (srcptr < srcend)
6198 : {
6199 : int result;
6200 : char *error_context_name_and_value[2];
6201 :
6202 71970 : varname = read_gucstate(&srcptr, srcend);
6203 71970 : varvalue = read_gucstate(&srcptr, srcend);
6204 71970 : varsourcefile = read_gucstate(&srcptr, srcend);
6205 71970 : if (varsourcefile[0])
6206 35129 : read_gucstate_binary(&srcptr, srcend,
6207 : &varsourceline, sizeof(varsourceline));
6208 : else
6209 36841 : varsourceline = 0;
6210 71970 : read_gucstate_binary(&srcptr, srcend,
6211 : &varsource, sizeof(varsource));
6212 71970 : read_gucstate_binary(&srcptr, srcend,
6213 : &varscontext, sizeof(varscontext));
6214 71970 : read_gucstate_binary(&srcptr, srcend,
6215 : &varsrole, sizeof(varsrole));
6216 :
6217 71970 : error_context_name_and_value[0] = varname;
6218 71970 : error_context_name_and_value[1] = varvalue;
6219 71970 : error_context_callback.arg = &error_context_name_and_value[0];
6220 71970 : result = set_config_option_ext(varname, varvalue,
6221 : varscontext, varsource, varsrole,
6222 : GUC_ACTION_SET, true, ERROR, true);
6223 71970 : if (result <= 0)
6224 0 : ereport(ERROR,
6225 : (errcode(ERRCODE_INTERNAL_ERROR),
6226 : errmsg("parameter \"%s\" could not be set", varname)));
6227 71970 : if (varsourcefile[0])
6228 35129 : set_config_sourcefile(varname, varsourcefile, varsourceline);
6229 71970 : error_context_callback.arg = NULL;
6230 : }
6231 :
6232 2008 : error_context_stack = error_context_callback.previous;
6233 2008 : }
6234 :
6235 : /*
6236 : * A little "long argument" simulation, although not quite GNU
6237 : * compliant. Takes a string of the form "some-option=some value" and
6238 : * returns name = "some_option" and value = "some value" in palloc'ed
6239 : * storage. Note that '-' is converted to '_' in the option name. If
6240 : * there is no '=' in the input string then value will be NULL.
6241 : */
6242 : void
6243 34880 : ParseLongOption(const char *string, char **name, char **value)
6244 : {
6245 : size_t equal_pos;
6246 :
6247 : Assert(string);
6248 : Assert(name);
6249 : Assert(value);
6250 :
6251 34880 : equal_pos = strcspn(string, "=");
6252 :
6253 34880 : if (string[equal_pos] == '=')
6254 : {
6255 34879 : *name = palloc(equal_pos + 1);
6256 34879 : strlcpy(*name, string, equal_pos + 1);
6257 :
6258 34879 : *value = pstrdup(&string[equal_pos + 1]);
6259 : }
6260 : else
6261 : {
6262 : /* no equal sign in string */
6263 1 : *name = pstrdup(string);
6264 1 : *value = NULL;
6265 : }
6266 :
6267 486591 : for (char *cp = *name; *cp; cp++)
6268 451711 : if (*cp == '-')
6269 949 : *cp = '_';
6270 34880 : }
6271 :
6272 :
6273 : /*
6274 : * Transform array of GUC settings into lists of names and values. The lists
6275 : * are faster to process in cases where the settings must be applied
6276 : * repeatedly (e.g. for each function invocation).
6277 : */
6278 : void
6279 4579 : TransformGUCArray(ArrayType *array, List **names, List **values)
6280 : {
6281 : Assert(array != NULL);
6282 : Assert(ARR_ELEMTYPE(array) == TEXTOID);
6283 : Assert(ARR_NDIM(array) == 1);
6284 : Assert(ARR_LBOUND(array)[0] == 1);
6285 :
6286 4579 : *names = NIL;
6287 4579 : *values = NIL;
6288 31406 : for (int i = 1; i <= ARR_DIMS(array)[0]; i++)
6289 : {
6290 : Datum d;
6291 : bool isnull;
6292 : char *s;
6293 : char *name;
6294 : char *value;
6295 :
6296 26827 : d = array_ref(array, 1, &i,
6297 : -1 /* varlenarray */ ,
6298 : -1 /* TEXT's typlen */ ,
6299 : false /* TEXT's typbyval */ ,
6300 : TYPALIGN_INT /* TEXT's typalign */ ,
6301 : &isnull);
6302 :
6303 26827 : if (isnull)
6304 0 : continue;
6305 :
6306 26827 : s = TextDatumGetCString(d);
6307 :
6308 26827 : ParseLongOption(s, &name, &value);
6309 26827 : if (!value)
6310 : {
6311 0 : ereport(WARNING,
6312 : (errcode(ERRCODE_SYNTAX_ERROR),
6313 : errmsg("could not parse setting for parameter \"%s\"",
6314 : name)));
6315 0 : pfree(name);
6316 0 : continue;
6317 : }
6318 :
6319 26827 : *names = lappend(*names, name);
6320 26827 : *values = lappend(*values, value);
6321 :
6322 26827 : pfree(s);
6323 : }
6324 4579 : }
6325 :
6326 :
6327 : /*
6328 : * Handle options fetched from pg_db_role_setting.setconfig,
6329 : * pg_proc.proconfig, etc. Caller must specify proper context/source/action.
6330 : *
6331 : * The array parameter must be an array of TEXT (it must not be NULL).
6332 : */
6333 : void
6334 4501 : ProcessGUCArray(ArrayType *array,
6335 : GucContext context, GucSource source, GucAction action)
6336 : {
6337 : List *gucNames;
6338 : List *gucValues;
6339 : ListCell *lc1;
6340 : ListCell *lc2;
6341 :
6342 4501 : TransformGUCArray(array, &gucNames, &gucValues);
6343 31242 : forboth(lc1, gucNames, lc2, gucValues)
6344 : {
6345 26749 : char *name = lfirst(lc1);
6346 26749 : char *value = lfirst(lc2);
6347 :
6348 26749 : (void) set_config_option(name, value,
6349 : context, source,
6350 : action, true, 0, false);
6351 :
6352 26741 : pfree(name);
6353 26741 : pfree(value);
6354 : }
6355 :
6356 4493 : list_free(gucNames);
6357 4493 : list_free(gucValues);
6358 4493 : }
6359 :
6360 :
6361 : /*
6362 : * Add an entry to an option array. The array parameter may be NULL
6363 : * to indicate the current table entry is NULL.
6364 : */
6365 : ArrayType *
6366 793 : GUCArrayAdd(ArrayType *array, const char *name, const char *value)
6367 : {
6368 : struct config_generic *record;
6369 : Datum datum;
6370 : char *newval;
6371 : ArrayType *a;
6372 :
6373 : Assert(name);
6374 : Assert(value);
6375 :
6376 : /* test if the option is valid and we're allowed to set it */
6377 793 : (void) validate_option_array_item(name, value, false);
6378 :
6379 : /* normalize name (converts obsolete GUC names to modern spellings) */
6380 791 : record = find_option(name, false, true, WARNING);
6381 791 : if (record)
6382 791 : name = record->name;
6383 :
6384 : /* build new item for array */
6385 791 : newval = psprintf("%s=%s", name, value);
6386 791 : datum = CStringGetTextDatum(newval);
6387 :
6388 791 : if (array)
6389 : {
6390 : int index;
6391 : bool isnull;
6392 :
6393 : Assert(ARR_ELEMTYPE(array) == TEXTOID);
6394 : Assert(ARR_NDIM(array) == 1);
6395 : Assert(ARR_LBOUND(array)[0] == 1);
6396 :
6397 587 : index = ARR_DIMS(array)[0] + 1; /* add after end */
6398 :
6399 2321 : for (int i = 1; i <= ARR_DIMS(array)[0]; i++)
6400 : {
6401 : Datum d;
6402 : char *current;
6403 :
6404 1742 : d = array_ref(array, 1, &i,
6405 : -1 /* varlenarray */ ,
6406 : -1 /* TEXT's typlen */ ,
6407 : false /* TEXT's typbyval */ ,
6408 : TYPALIGN_INT /* TEXT's typalign */ ,
6409 : &isnull);
6410 1742 : if (isnull)
6411 0 : continue;
6412 1742 : current = TextDatumGetCString(d);
6413 :
6414 : /* check for match up through and including '=' */
6415 1742 : if (strncmp(current, newval, strlen(name) + 1) == 0)
6416 : {
6417 8 : index = i;
6418 8 : break;
6419 : }
6420 : }
6421 :
6422 587 : a = array_set(array, 1, &index,
6423 : datum,
6424 : false,
6425 : -1 /* varlena array */ ,
6426 : -1 /* TEXT's typlen */ ,
6427 : false /* TEXT's typbyval */ ,
6428 : TYPALIGN_INT /* TEXT's typalign */ );
6429 : }
6430 : else
6431 204 : a = construct_array_builtin(&datum, 1, TEXTOID);
6432 :
6433 791 : return a;
6434 : }
6435 :
6436 :
6437 : /*
6438 : * Delete an entry from an option array. The array parameter may be NULL
6439 : * to indicate the current table entry is NULL. Also, if the return value
6440 : * is NULL then a null should be stored.
6441 : */
6442 : ArrayType *
6443 20 : GUCArrayDelete(ArrayType *array, const char *name)
6444 : {
6445 : struct config_generic *record;
6446 : ArrayType *newarray;
6447 : int index;
6448 :
6449 : Assert(name);
6450 :
6451 : /* test if the option is valid and we're allowed to set it */
6452 20 : (void) validate_option_array_item(name, NULL, false);
6453 :
6454 : /* normalize name (converts obsolete GUC names to modern spellings) */
6455 18 : record = find_option(name, false, true, WARNING);
6456 18 : if (record)
6457 15 : name = record->name;
6458 :
6459 : /* if array is currently null, then surely nothing to delete */
6460 18 : if (!array)
6461 2 : return NULL;
6462 :
6463 16 : newarray = NULL;
6464 16 : index = 1;
6465 :
6466 51 : for (int i = 1; i <= ARR_DIMS(array)[0]; i++)
6467 : {
6468 : Datum d;
6469 : char *val;
6470 : bool isnull;
6471 :
6472 35 : d = array_ref(array, 1, &i,
6473 : -1 /* varlenarray */ ,
6474 : -1 /* TEXT's typlen */ ,
6475 : false /* TEXT's typbyval */ ,
6476 : TYPALIGN_INT /* TEXT's typalign */ ,
6477 : &isnull);
6478 35 : if (isnull)
6479 16 : continue;
6480 35 : val = TextDatumGetCString(d);
6481 :
6482 : /* ignore entry if it's what we want to delete */
6483 35 : if (strncmp(val, name, strlen(name)) == 0
6484 16 : && val[strlen(name)] == '=')
6485 16 : continue;
6486 :
6487 : /* else add it to the output array */
6488 19 : if (newarray)
6489 15 : newarray = array_set(newarray, 1, &index,
6490 : d,
6491 : false,
6492 : -1 /* varlenarray */ ,
6493 : -1 /* TEXT's typlen */ ,
6494 : false /* TEXT's typbyval */ ,
6495 : TYPALIGN_INT /* TEXT's typalign */ );
6496 : else
6497 4 : newarray = construct_array_builtin(&d, 1, TEXTOID);
6498 :
6499 19 : index++;
6500 : }
6501 :
6502 16 : return newarray;
6503 : }
6504 :
6505 :
6506 : /*
6507 : * Given a GUC array, delete all settings from it that our permission
6508 : * level allows: if superuser, delete them all; if regular user, only
6509 : * those that are PGC_USERSET or we have permission to set
6510 : */
6511 : ArrayType *
6512 1 : GUCArrayReset(ArrayType *array)
6513 : {
6514 : ArrayType *newarray;
6515 : int index;
6516 :
6517 : /* if array is currently null, nothing to do */
6518 1 : if (!array)
6519 0 : return NULL;
6520 :
6521 : /* if we're superuser, we can delete everything, so just do it */
6522 1 : if (superuser())
6523 0 : return NULL;
6524 :
6525 1 : newarray = NULL;
6526 1 : index = 1;
6527 :
6528 3 : for (int i = 1; i <= ARR_DIMS(array)[0]; i++)
6529 : {
6530 : Datum d;
6531 : char *val;
6532 : char *eqsgn;
6533 : bool isnull;
6534 :
6535 2 : d = array_ref(array, 1, &i,
6536 : -1 /* varlenarray */ ,
6537 : -1 /* TEXT's typlen */ ,
6538 : false /* TEXT's typbyval */ ,
6539 : TYPALIGN_INT /* TEXT's typalign */ ,
6540 : &isnull);
6541 2 : if (isnull)
6542 1 : continue;
6543 2 : val = TextDatumGetCString(d);
6544 :
6545 2 : eqsgn = strchr(val, '=');
6546 2 : *eqsgn = '\0';
6547 :
6548 : /* skip if we have permission to delete it */
6549 2 : if (validate_option_array_item(val, NULL, true))
6550 1 : continue;
6551 :
6552 : /* else add it to the output array */
6553 1 : if (newarray)
6554 0 : newarray = array_set(newarray, 1, &index,
6555 : d,
6556 : false,
6557 : -1 /* varlenarray */ ,
6558 : -1 /* TEXT's typlen */ ,
6559 : false /* TEXT's typbyval */ ,
6560 : TYPALIGN_INT /* TEXT's typalign */ );
6561 : else
6562 1 : newarray = construct_array_builtin(&d, 1, TEXTOID);
6563 :
6564 1 : index++;
6565 1 : pfree(val);
6566 : }
6567 :
6568 1 : return newarray;
6569 : }
6570 :
6571 : /*
6572 : * Validate a proposed option setting for GUCArrayAdd/Delete/Reset.
6573 : *
6574 : * name is the option name. value is the proposed value for the Add case,
6575 : * or NULL for the Delete/Reset cases. If skipIfNoPermissions is true, it's
6576 : * not an error to have no permissions to set the option.
6577 : *
6578 : * Returns true if OK, false if skipIfNoPermissions is true and user does not
6579 : * have permission to change this option (all other error cases result in an
6580 : * error being thrown).
6581 : */
6582 : static bool
6583 815 : validate_option_array_item(const char *name, const char *value,
6584 : bool skipIfNoPermissions)
6585 :
6586 : {
6587 : struct config_generic *gconf;
6588 : bool reset_custom;
6589 :
6590 : /*
6591 : * There are three cases to consider:
6592 : *
6593 : * name is a known GUC variable. Check the value normally, check
6594 : * permissions normally (i.e., allow if variable is USERSET, or if it's
6595 : * SUSET and user is superuser or holds ACL_SET permissions).
6596 : *
6597 : * name is not known, but exists or can be created as a placeholder (i.e.,
6598 : * it has a valid custom name). We allow this case if you're a superuser,
6599 : * otherwise not. Superusers are assumed to know what they're doing. We
6600 : * can't allow it for other users, because when the placeholder is
6601 : * resolved it might turn out to be a SUSET variable. (With currently
6602 : * available infrastructure, we can actually handle such cases within the
6603 : * current session --- but once an entry is made in pg_db_role_setting,
6604 : * it's assumed to be fully validated.)
6605 : *
6606 : * name is not known and can't be created as a placeholder. Throw error,
6607 : * unless skipIfNoPermissions or reset_custom is true. If reset_custom is
6608 : * true, this is a RESET or RESET ALL operation for an unknown custom GUC
6609 : * with a reserved prefix, in which case we want to fall through to the
6610 : * placeholder case described in the preceding paragraph (else there'd be
6611 : * no way for users to remove them). Otherwise, return false.
6612 : */
6613 815 : reset_custom = (!value && valid_custom_variable_name(name));
6614 815 : gconf = find_option(name, true, skipIfNoPermissions || reset_custom, ERROR);
6615 812 : if (!gconf && !reset_custom)
6616 : {
6617 : /* not known, failed to make a placeholder */
6618 0 : return false;
6619 : }
6620 :
6621 812 : if (!gconf || gconf->flags & GUC_CUSTOM_PLACEHOLDER)
6622 : {
6623 : /*
6624 : * We cannot do any meaningful check on the value, so only permissions
6625 : * are useful to check.
6626 : */
6627 6 : if (superuser() ||
6628 0 : pg_parameter_aclcheck(name, GetUserId(), ACL_SET) == ACLCHECK_OK)
6629 6 : return true;
6630 0 : if (skipIfNoPermissions)
6631 0 : return false;
6632 0 : ereport(ERROR,
6633 : (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
6634 : errmsg("permission denied to set parameter \"%s\"", name)));
6635 : }
6636 :
6637 : /* manual permissions check so we can avoid an error being thrown */
6638 806 : if (gconf->context == PGC_USERSET)
6639 : /* ok */ ;
6640 232 : else if (gconf->context == PGC_SUSET &&
6641 122 : (superuser() ||
6642 6 : pg_parameter_aclcheck(name, GetUserId(), ACL_SET) == ACLCHECK_OK))
6643 : /* ok */ ;
6644 2 : else if (skipIfNoPermissions)
6645 1 : return false;
6646 : /* if a permissions error should be thrown, let set_config_option do it */
6647 :
6648 : /* test for permissions and valid option value */
6649 805 : (void) set_config_option(name, value,
6650 805 : superuser() ? PGC_SUSET : PGC_USERSET,
6651 : PGC_S_TEST, GUC_ACTION_SET, false, 0, false);
6652 :
6653 804 : return true;
6654 : }
6655 :
6656 :
6657 : /*
6658 : * Called by check_hooks that want to override the normal
6659 : * ERRCODE_INVALID_PARAMETER_VALUE SQLSTATE for check hook failures.
6660 : *
6661 : * Note that GUC_check_errmsg() etc are just macros that result in a direct
6662 : * assignment to the associated variables. That is ugly, but forced by the
6663 : * limitations of C's macro mechanisms.
6664 : */
6665 : void
6666 33 : GUC_check_errcode(int sqlerrcode)
6667 : {
6668 33 : GUC_check_errcode_value = sqlerrcode;
6669 33 : }
6670 :
6671 :
6672 : /*
6673 : * Convenience functions to manage calling a variable's check_hook.
6674 : * These mostly take care of the protocol for letting check hooks supply
6675 : * portions of the error report on failure.
6676 : */
6677 :
6678 : static bool
6679 308271 : call_bool_check_hook(const struct config_generic *conf, bool *newval, void **extra,
6680 : GucSource source, int elevel)
6681 : {
6682 : /* Quick success if no hook */
6683 308271 : if (!conf->_bool.check_hook)
6684 281928 : return true;
6685 :
6686 : /* Reset variables that might be set by hook */
6687 26343 : GUC_check_errcode_value = ERRCODE_INVALID_PARAMETER_VALUE;
6688 26343 : GUC_check_errmsg_string = NULL;
6689 26343 : GUC_check_errdetail_string = NULL;
6690 26343 : GUC_check_errhint_string = NULL;
6691 :
6692 26343 : if (!conf->_bool.check_hook(newval, extra, source))
6693 : {
6694 20 : ereport(elevel,
6695 : (errcode(GUC_check_errcode_value),
6696 : GUC_check_errmsg_string ?
6697 : errmsg_internal("%s", GUC_check_errmsg_string) :
6698 : errmsg("invalid value for parameter \"%s\": %d",
6699 : conf->name, (int) *newval),
6700 : GUC_check_errdetail_string ?
6701 : errdetail_internal("%s", GUC_check_errdetail_string) : 0,
6702 : GUC_check_errhint_string ?
6703 : errhint("%s", GUC_check_errhint_string) : 0));
6704 : /* Flush strings created in ErrorContext (ereport might not have) */
6705 0 : FlushErrorState();
6706 0 : return false;
6707 : }
6708 :
6709 26323 : return true;
6710 : }
6711 :
6712 : static bool
6713 266822 : call_int_check_hook(const struct config_generic *conf, int *newval, void **extra,
6714 : GucSource source, int elevel)
6715 : {
6716 : /* Quick success if no hook */
6717 266822 : if (!conf->_int.check_hook)
6718 232827 : return true;
6719 :
6720 : /* Reset variables that might be set by hook */
6721 33995 : GUC_check_errcode_value = ERRCODE_INVALID_PARAMETER_VALUE;
6722 33995 : GUC_check_errmsg_string = NULL;
6723 33995 : GUC_check_errdetail_string = NULL;
6724 33995 : GUC_check_errhint_string = NULL;
6725 :
6726 33995 : if (!conf->_int.check_hook(newval, extra, source))
6727 : {
6728 0 : ereport(elevel,
6729 : (errcode(GUC_check_errcode_value),
6730 : GUC_check_errmsg_string ?
6731 : errmsg_internal("%s", GUC_check_errmsg_string) :
6732 : errmsg("invalid value for parameter \"%s\": %d",
6733 : conf->name, *newval),
6734 : GUC_check_errdetail_string ?
6735 : errdetail_internal("%s", GUC_check_errdetail_string) : 0,
6736 : GUC_check_errhint_string ?
6737 : errhint("%s", GUC_check_errhint_string) : 0));
6738 : /* Flush strings created in ErrorContext (ereport might not have) */
6739 0 : FlushErrorState();
6740 0 : return false;
6741 : }
6742 :
6743 33995 : return true;
6744 : }
6745 :
6746 : static bool
6747 46530 : call_real_check_hook(const struct config_generic *conf, double *newval, void **extra,
6748 : GucSource source, int elevel)
6749 : {
6750 : /* Quick success if no hook */
6751 46530 : if (!conf->_real.check_hook)
6752 45255 : return true;
6753 :
6754 : /* Reset variables that might be set by hook */
6755 1275 : GUC_check_errcode_value = ERRCODE_INVALID_PARAMETER_VALUE;
6756 1275 : GUC_check_errmsg_string = NULL;
6757 1275 : GUC_check_errdetail_string = NULL;
6758 1275 : GUC_check_errhint_string = NULL;
6759 :
6760 1275 : if (!conf->_real.check_hook(newval, extra, source))
6761 : {
6762 0 : ereport(elevel,
6763 : (errcode(GUC_check_errcode_value),
6764 : GUC_check_errmsg_string ?
6765 : errmsg_internal("%s", GUC_check_errmsg_string) :
6766 : errmsg("invalid value for parameter \"%s\": %g",
6767 : conf->name, *newval),
6768 : GUC_check_errdetail_string ?
6769 : errdetail_internal("%s", GUC_check_errdetail_string) : 0,
6770 : GUC_check_errhint_string ?
6771 : errhint("%s", GUC_check_errhint_string) : 0));
6772 : /* Flush strings created in ErrorContext (ereport might not have) */
6773 0 : FlushErrorState();
6774 0 : return false;
6775 : }
6776 :
6777 1275 : return true;
6778 : }
6779 :
6780 : static bool
6781 523741 : call_string_check_hook(const struct config_generic *conf, char **newval, void **extra,
6782 : GucSource source, int elevel)
6783 : {
6784 523741 : volatile bool result = true;
6785 :
6786 : /* Quick success if no hook */
6787 523741 : if (!conf->_string.check_hook)
6788 87548 : return true;
6789 :
6790 : /*
6791 : * If elevel is ERROR, or if the check_hook itself throws an elog
6792 : * (undesirable, but not always avoidable), make sure we don't leak the
6793 : * already-malloc'd newval string.
6794 : */
6795 436193 : PG_TRY();
6796 : {
6797 : /* Reset variables that might be set by hook */
6798 436193 : GUC_check_errcode_value = ERRCODE_INVALID_PARAMETER_VALUE;
6799 436193 : GUC_check_errmsg_string = NULL;
6800 436193 : GUC_check_errdetail_string = NULL;
6801 436193 : GUC_check_errhint_string = NULL;
6802 :
6803 436193 : if (!conf->_string.check_hook(newval, extra, source))
6804 : {
6805 100 : ereport(elevel,
6806 : (errcode(GUC_check_errcode_value),
6807 : GUC_check_errmsg_string ?
6808 : errmsg_internal("%s", GUC_check_errmsg_string) :
6809 : errmsg("invalid value for parameter \"%s\": \"%s\"",
6810 : conf->name, *newval ? *newval : ""),
6811 : GUC_check_errdetail_string ?
6812 : errdetail_internal("%s", GUC_check_errdetail_string) : 0,
6813 : GUC_check_errhint_string ?
6814 : errhint("%s", GUC_check_errhint_string) : 0));
6815 : /* Flush strings created in ErrorContext (ereport might not have) */
6816 0 : FlushErrorState();
6817 0 : result = false;
6818 : }
6819 : }
6820 104 : PG_CATCH();
6821 : {
6822 104 : guc_free(*newval);
6823 104 : PG_RE_THROW();
6824 : }
6825 436089 : PG_END_TRY();
6826 :
6827 436089 : return result;
6828 : }
6829 :
6830 : static bool
6831 147994 : call_enum_check_hook(const struct config_generic *conf, int *newval, void **extra,
6832 : GucSource source, int elevel)
6833 : {
6834 : /* Quick success if no hook */
6835 147994 : if (!conf->_enum.check_hook)
6836 136226 : return true;
6837 :
6838 : /* Reset variables that might be set by hook */
6839 11768 : GUC_check_errcode_value = ERRCODE_INVALID_PARAMETER_VALUE;
6840 11768 : GUC_check_errmsg_string = NULL;
6841 11768 : GUC_check_errdetail_string = NULL;
6842 11768 : GUC_check_errhint_string = NULL;
6843 :
6844 11768 : if (!conf->_enum.check_hook(newval, extra, source))
6845 : {
6846 1 : ereport(elevel,
6847 : (errcode(GUC_check_errcode_value),
6848 : GUC_check_errmsg_string ?
6849 : errmsg_internal("%s", GUC_check_errmsg_string) :
6850 : errmsg("invalid value for parameter \"%s\": \"%s\"",
6851 : conf->name,
6852 : config_enum_lookup_by_value(conf, *newval)),
6853 : GUC_check_errdetail_string ?
6854 : errdetail_internal("%s", GUC_check_errdetail_string) : 0,
6855 : GUC_check_errhint_string ?
6856 : errhint("%s", GUC_check_errhint_string) : 0));
6857 : /* Flush strings created in ErrorContext (ereport might not have) */
6858 0 : FlushErrorState();
6859 0 : return false;
6860 : }
6861 :
6862 11767 : return true;
6863 : }
|