PostgreSQL Source Code  git master
guc.c File Reference
#include "postgres.h"
#include <limits.h>
#include <sys/stat.h>
#include <unistd.h>
#include "access/xact.h"
#include "access/xlog.h"
#include "catalog/objectaccess.h"
#include "catalog/pg_authid.h"
#include "catalog/pg_parameter_acl.h"
#include "guc_internal.h"
#include "libpq/pqformat.h"
#include "parser/scansup.h"
#include "port/pg_bitutils.h"
#include "storage/fd.h"
#include "storage/lwlock.h"
#include "storage/shmem.h"
#include "tcop/tcopprot.h"
#include "utils/acl.h"
#include "utils/backend_status.h"
#include "utils/builtins.h"
#include "utils/conffiles.h"
#include "utils/float.h"
#include "utils/guc_tables.h"
#include "utils/memutils.h"
#include "utils/timestamp.h"
Include dependency graph for guc.c:

Go to the source code of this file.

Data Structures

struct  unit_conversion
 
struct  GUCHashEntry
 

Macros

#define CONFIG_FILENAME   "postgresql.conf"
 
#define HBA_FILENAME   "pg_hba.conf"
 
#define IDENT_FILENAME   "pg_ident.conf"
 
#define REALTYPE_PRECISION   17
 
#define MAX_UNIT_LEN   3 /* length of longest recognized unit string */
 
#define newval   (newval_union.boolval)
 
#define newval   (newval_union.intval)
 
#define newval   (newval_union.realval)
 
#define newval   (newval_union.stringval)
 
#define newval   (newval_union.enumval)
 

Functions

static int guc_var_compare (const void *a, const void *b)
 
static uint32 guc_name_hash (const void *key, Size keysize)
 
static int guc_name_match (const void *key1, const void *key2, Size keysize)
 
static void InitializeGUCOptionsFromEnvironment (void)
 
static void InitializeOneGUCOption (struct config_generic *gconf)
 
static void RemoveGUCFromLists (struct config_generic *gconf)
 
static void set_guc_source (struct config_generic *gconf, GucSource newsource)
 
static void pg_timezone_abbrev_initialize (void)
 
static void push_old_value (struct config_generic *gconf, GucAction action)
 
static void ReportGUCOption (struct config_generic *record)
 
static void set_config_sourcefile (const char *name, char *sourcefile, int sourceline)
 
static void reapply_stacked_values (struct config_generic *variable, struct config_string *pHolder, GucStack *stack, const char *curvalue, GucContext curscontext, GucSource cursource, Oid cursrole)
 
static bool validate_option_array_item (const char *name, const char *value, bool skipIfNoPermissions)
 
static void write_auto_conf_file (int fd, const char *filename, ConfigVariable *head)
 
static void replace_auto_config_value (ConfigVariable **head_p, ConfigVariable **tail_p, const char *name, const char *value)
 
static bool valid_custom_variable_name (const char *name)
 
static void do_serialize (char **destptr, Size *maxbytes, const char *fmt,...) pg_attribute_printf(3
 
static void static bool call_bool_check_hook (struct config_bool *conf, bool *newval, void **extra, GucSource source, int elevel)
 
static bool call_int_check_hook (struct config_int *conf, int *newval, void **extra, GucSource source, int elevel)
 
static bool call_real_check_hook (struct config_real *conf, double *newval, void **extra, GucSource source, int elevel)
 
static bool call_string_check_hook (struct config_string *conf, char **newval, void **extra, GucSource source, int elevel)
 
static bool call_enum_check_hook (struct config_enum *conf, int *newval, void **extra, GucSource source, int elevel)
 
ConfigVariableProcessConfigFileInternal (GucContext context, bool applySettings, int elevel)
 
void * guc_malloc (int elevel, size_t size)
 
void * guc_realloc (int elevel, void *old, size_t size)
 
char * guc_strdup (int elevel, const char *src)
 
void guc_free (void *ptr)
 
static bool string_field_used (struct config_string *conf, char *strval)
 
static void set_string_field (struct config_string *conf, char **field, char *newval)
 
static bool extra_field_used (struct config_generic *gconf, void *extra)
 
static void set_extra_field (struct config_generic *gconf, void **field, void *newval)
 
static void set_stack_value (struct config_generic *gconf, config_var_value *val)
 
static void discard_stack_value (struct config_generic *gconf, config_var_value *val)
 
struct config_generic ** get_guc_variables (int *num_vars)
 
void build_guc_variables (void)
 
static bool add_guc_variable (struct config_generic *var, int elevel)
 
static struct config_genericadd_placeholder_variable (const char *name, int elevel)
 
struct config_genericfind_option (const char *name, bool create_placeholders, bool skip_errors, int elevel)
 
int guc_name_compare (const char *namea, const char *nameb)
 
char * convert_GUC_name_for_parameter_acl (const char *name)
 
bool check_GUC_name_for_parameter_acl (const char *name)
 
void InitializeGUCOptions (void)
 
bool SelectConfigFiles (const char *userDoption, const char *progname)
 
void ResetAllOptions (void)
 
void AtStart_GUC (void)
 
int NewGUCNestLevel (void)
 
void AtEOXact_GUC (bool isCommit, int nestLevel)
 
void BeginReportingGUCOptions (void)
 
void ReportChangedGUCOptions (void)
 
static bool convert_to_base_unit (double value, const char *unit, int base_unit, double *base_value)
 
static void convert_int_from_base_unit (int64 base_value, int base_unit, int64 *value, const char **unit)
 
static void convert_real_from_base_unit (double base_value, int base_unit, double *value, const char **unit)
 
const char * get_config_unit_name (int flags)
 
bool parse_int (const char *value, int *result, int flags, const char **hintmsg)
 
bool parse_real (const char *value, double *result, int flags, const char **hintmsg)
 
const char * config_enum_lookup_by_value (struct config_enum *record, int val)
 
bool config_enum_lookup_by_name (struct config_enum *record, const char *value, int *retval)
 
char * config_enum_get_options (struct config_enum *record, const char *prefix, const char *suffix, const char *separator)
 
static bool parse_and_validate_value (struct config_generic *record, const char *name, const char *value, GucSource source, int elevel, union config_var_val *newval, void **newextra)
 
int set_config_option (const char *name, const char *value, GucContext context, GucSource source, GucAction action, bool changeVal, int elevel, bool is_reload)
 
int set_config_option_ext (const char *name, const char *value, GucContext context, GucSource source, Oid srole, GucAction action, bool changeVal, int elevel, bool is_reload)
 
void SetConfigOption (const char *name, const char *value, GucContext context, GucSource source)
 
const char * GetConfigOption (const char *name, bool missing_ok, bool restrict_privileged)
 
const char * GetConfigOptionResetString (const char *name)
 
int GetConfigOptionFlags (const char *name, bool missing_ok)
 
void AlterSystemSetConfigFile (AlterSystemStmt *altersysstmt)
 
static struct config_genericinit_custom_variable (const char *name, const char *short_desc, const char *long_desc, GucContext context, int flags, enum config_type type, size_t sz)
 
static void define_custom_variable (struct config_generic *variable)
 
void DefineCustomBoolVariable (const char *name, const char *short_desc, const char *long_desc, bool *valueAddr, bool bootValue, GucContext context, int flags, GucBoolCheckHook check_hook, GucBoolAssignHook assign_hook, GucShowHook show_hook)
 
void DefineCustomIntVariable (const char *name, const char *short_desc, const char *long_desc, int *valueAddr, int bootValue, int minValue, int maxValue, GucContext context, int flags, GucIntCheckHook check_hook, GucIntAssignHook assign_hook, GucShowHook show_hook)
 
void DefineCustomRealVariable (const char *name, const char *short_desc, const char *long_desc, double *valueAddr, double bootValue, double minValue, double maxValue, GucContext context, int flags, GucRealCheckHook check_hook, GucRealAssignHook assign_hook, GucShowHook show_hook)
 
void DefineCustomStringVariable (const char *name, const char *short_desc, const char *long_desc, char **valueAddr, const char *bootValue, GucContext context, int flags, GucStringCheckHook check_hook, GucStringAssignHook assign_hook, GucShowHook show_hook)
 
void DefineCustomEnumVariable (const char *name, const char *short_desc, const char *long_desc, int *valueAddr, int bootValue, const struct config_enum_entry *options, GucContext context, int flags, GucEnumCheckHook check_hook, GucEnumAssignHook assign_hook, GucShowHook show_hook)
 
void MarkGUCPrefixReserved (const char *className)
 
struct config_generic ** get_explain_guc_options (int *num)
 
char * GetConfigOptionByName (const char *name, const char **varname, bool missing_ok)
 
char * ShowGUCOption (struct config_generic *record, bool use_units)
 
static bool can_skip_gucvar (struct config_generic *gconf)
 
static Size estimate_variable_size (struct config_generic *gconf)
 
Size EstimateGUCStateSpace (void)
 
static void do_serialize_binary (char **destptr, Size *maxbytes, void *val, Size valsize)
 
static void serialize_variable (char **destptr, Size *maxbytes, struct config_generic *gconf)
 
void SerializeGUCState (Size maxsize, char *start_address)
 
static char * read_gucstate (char **srcptr, char *srcend)
 
static void read_gucstate_binary (char **srcptr, char *srcend, void *dest, Size size)
 
static void guc_restore_error_context_callback (void *arg)
 
void RestoreGUCState (void *gucstate)
 
void ParseLongOption (const char *string, char **name, char **value)
 
void ProcessGUCArray (ArrayType *array, GucContext context, GucSource source, GucAction action)
 
ArrayTypeGUCArrayAdd (ArrayType *array, const char *name, const char *value)
 
ArrayTypeGUCArrayDelete (ArrayType *array, const char *name)
 
ArrayTypeGUCArrayReset (ArrayType *array)
 
void GUC_check_errcode (int sqlerrcode)
 

Variables

static int GUC_check_errcode_value
 
static Listreserved_class_prefix = NIL
 
char * GUC_check_errmsg_string
 
char * GUC_check_errdetail_string
 
char * GUC_check_errhint_string
 
bool in_hot_standby_guc
 
static const char * memory_units_hint = gettext_noop("Valid units for this parameter are \"B\", \"kB\", \"MB\", \"GB\", and \"TB\".")
 
static const unit_conversion memory_unit_conversion_table []
 
static const char * time_units_hint = gettext_noop("Valid units for this parameter are \"us\", \"ms\", \"s\", \"min\", \"h\", and \"d\".")
 
static const unit_conversion time_unit_conversion_table []
 
static const char *const map_old_guc_names []
 
static MemoryContext GUCMemoryContext
 
static HTABguc_hashtab
 
static dlist_head guc_nondef_list
 
static slist_head guc_stack_list
 
static slist_head guc_report_list
 
static bool reporting_enabled
 
static int GUCNestLevel = 0
 

Macro Definition Documentation

◆ CONFIG_FILENAME

#define CONFIG_FILENAME   "postgresql.conf"

Definition at line 54 of file guc.c.

◆ HBA_FILENAME

#define HBA_FILENAME   "pg_hba.conf"

Definition at line 55 of file guc.c.

◆ IDENT_FILENAME

#define IDENT_FILENAME   "pg_ident.conf"

Definition at line 56 of file guc.c.

◆ MAX_UNIT_LEN

#define MAX_UNIT_LEN   3 /* length of longest recognized unit string */

Definition at line 97 of file guc.c.

◆ newval [1/5]

#define newval   (newval_union.boolval)

◆ newval [2/5]

#define newval   (newval_union.intval)

◆ newval [3/5]

#define newval   (newval_union.realval)

◆ newval [4/5]

#define newval   (newval_union.stringval)

◆ newval [5/5]

#define newval   (newval_union.enumval)

◆ REALTYPE_PRECISION

#define REALTYPE_PRECISION   17

Definition at line 67 of file guc.c.

Function Documentation

◆ add_guc_variable()

static bool add_guc_variable ( struct config_generic var,
int  elevel 
)
static

Definition at line 1040 of file guc.c.

1041 {
1042  GUCHashEntry *hentry;
1043  bool found;
1044 
1045  hentry = (GUCHashEntry *) hash_search(guc_hashtab,
1046  &var->name,
1048  &found);
1049  if (unlikely(hentry == NULL))
1050  {
1051  ereport(elevel,
1052  (errcode(ERRCODE_OUT_OF_MEMORY),
1053  errmsg("out of memory")));
1054  return false; /* out of memory */
1055  }
1056  Assert(!found);
1057  hentry->gucvar = var;
1058  return true;
1059 }
#define unlikely(x)
Definition: c.h:295
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
Definition: dynahash.c:953
int errcode(int sqlerrcode)
Definition: elog.c:695
int errmsg(const char *fmt,...)
Definition: elog.c:906
#define ereport(elevel,...)
Definition: elog.h:145
static HTAB * guc_hashtab
Definition: guc.c:207
@ HASH_ENTER_NULL
Definition: hsearch.h:116
Assert(fmt[strlen(fmt) - 1] !='\n')
struct config_generic * gucvar
Definition: guc.c:204
const char * name
Definition: guc_tables.h:155

References Assert(), ereport, errcode(), errmsg(), guc_hashtab, GUCHashEntry::gucvar, HASH_ENTER_NULL, hash_search(), config_generic::name, and unlikely.

Referenced by add_placeholder_variable(), and define_custom_variable().

◆ add_placeholder_variable()

static struct config_generic* add_placeholder_variable ( const char *  name,
int  elevel 
)
static

Definition at line 1105 of file guc.c.

1106 {
1107  size_t sz = sizeof(struct config_string) + sizeof(char *);
1108  struct config_string *var;
1109  struct config_generic *gen;
1110 
1111  var = (struct config_string *) guc_malloc(elevel, sz);
1112  if (var == NULL)
1113  return NULL;
1114  memset(var, 0, sz);
1115  gen = &var->gen;
1116 
1117  gen->name = guc_strdup(elevel, name);
1118  if (gen->name == NULL)
1119  {
1120  guc_free(var);
1121  return NULL;
1122  }
1123 
1124  gen->context = PGC_USERSET;
1126  gen->short_desc = "GUC placeholder variable";
1128  gen->vartype = PGC_STRING;
1129 
1130  /*
1131  * The char* is allocated at the end of the struct since we have no
1132  * 'static' place to point to. Note that the current value, as well as
1133  * the boot and reset values, start out NULL.
1134  */
1135  var->variable = (char **) (var + 1);
1136 
1137  if (!add_guc_variable((struct config_generic *) var, elevel))
1138  {
1139  guc_free(unconstify(char *, gen->name));
1140  guc_free(var);
1141  return NULL;
1142  }
1143 
1144  return gen;
1145 }
#define unconstify(underlying_type, expr)
Definition: c.h:1181
const char * name
Definition: encode.c:561
void * guc_malloc(int elevel, size_t size)
Definition: guc.c:631
void guc_free(void *ptr)
Definition: guc.c:682
static bool add_guc_variable(struct config_generic *var, int elevel)
Definition: guc.c:1040
char * guc_strdup(int elevel, const char *src)
Definition: guc.c:670
#define GUC_CUSTOM_PLACEHOLDER
Definition: guc.h:217
#define GUC_NO_SHOW_ALL
Definition: guc.h:210
@ PGC_USERSET
Definition: guc.h:75
#define GUC_NOT_IN_SAMPLE
Definition: guc.h:215
@ CUSTOM_OPTIONS
Definition: guc_tables.h:99
@ PGC_STRING
Definition: guc_tables.h:28
enum config_group group
Definition: guc_tables.h:157
GucContext context
Definition: guc_tables.h:156
const char * short_desc
Definition: guc_tables.h:158
enum config_type vartype
Definition: guc_tables.h:162
struct config_generic gen
Definition: guc_tables.h:245
char ** variable
Definition: guc_tables.h:247

References add_guc_variable(), config_generic::context, CUSTOM_OPTIONS, config_generic::flags, config_string::gen, config_generic::group, GUC_CUSTOM_PLACEHOLDER, guc_free(), guc_malloc(), GUC_NO_SHOW_ALL, GUC_NOT_IN_SAMPLE, guc_strdup(), name, config_generic::name, PGC_STRING, PGC_USERSET, config_generic::short_desc, unconstify, config_string::variable, and config_generic::vartype.

Referenced by find_option().

◆ AlterSystemSetConfigFile()

void AlterSystemSetConfigFile ( AlterSystemStmt altersysstmt)

Definition at line 4432 of file guc.c.

4433 {
4434  char *name;
4435  char *value;
4436  bool resetall = false;
4437  ConfigVariable *head = NULL;
4438  ConfigVariable *tail = NULL;
4439  volatile int Tmpfd;
4440  char AutoConfFileName[MAXPGPATH];
4441  char AutoConfTmpFileName[MAXPGPATH];
4442 
4443  /*
4444  * Extract statement arguments
4445  */
4446  name = altersysstmt->setstmt->name;
4447 
4448  switch (altersysstmt->setstmt->kind)
4449  {
4450  case VAR_SET_VALUE:
4451  value = ExtractSetVariableArgs(altersysstmt->setstmt);
4452  break;
4453 
4454  case VAR_SET_DEFAULT:
4455  case VAR_RESET:
4456  value = NULL;
4457  break;
4458 
4459  case VAR_RESET_ALL:
4460  value = NULL;
4461  resetall = true;
4462  break;
4463 
4464  default:
4465  elog(ERROR, "unrecognized alter system stmt type: %d",
4466  altersysstmt->setstmt->kind);
4467  break;
4468  }
4469 
4470  /*
4471  * Check permission to run ALTER SYSTEM on the target variable
4472  */
4473  if (!superuser())
4474  {
4475  if (resetall)
4476  ereport(ERROR,
4477  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
4478  errmsg("permission denied to perform ALTER SYSTEM RESET ALL")));
4479  else
4480  {
4481  AclResult aclresult;
4482 
4483  aclresult = pg_parameter_aclcheck(name, GetUserId(),
4485  if (aclresult != ACLCHECK_OK)
4486  ereport(ERROR,
4487  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
4488  errmsg("permission denied to set parameter \"%s\"",
4489  name)));
4490  }
4491  }
4492 
4493  /*
4494  * Unless it's RESET_ALL, validate the target variable and value
4495  */
4496  if (!resetall)
4497  {
4498  struct config_generic *record;
4499 
4500  record = find_option(name, false, false, ERROR);
4501  Assert(record != NULL);
4502 
4503  /*
4504  * Don't allow parameters that can't be set in configuration files to
4505  * be set in PG_AUTOCONF_FILENAME file.
4506  */
4507  if ((record->context == PGC_INTERNAL) ||
4508  (record->flags & GUC_DISALLOW_IN_FILE) ||
4509  (record->flags & GUC_DISALLOW_IN_AUTO_FILE))
4510  ereport(ERROR,
4511  (errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
4512  errmsg("parameter \"%s\" cannot be changed",
4513  name)));
4514 
4515  /*
4516  * If a value is specified, verify that it's sane.
4517  */
4518  if (value)
4519  {
4520  union config_var_val newval;
4521  void *newextra = NULL;
4522 
4523  /* Check that it's acceptable for the indicated parameter */
4524  if (!parse_and_validate_value(record, name, value,
4525  PGC_S_FILE, ERROR,
4526  &newval, &newextra))
4527  ereport(ERROR,
4528  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4529  errmsg("invalid value for parameter \"%s\": \"%s\"",
4530  name, value)));
4531 
4532  if (record->vartype == PGC_STRING && newval.stringval != NULL)
4533  guc_free(newval.stringval);
4534  guc_free(newextra);
4535 
4536  /*
4537  * We must also reject values containing newlines, because the
4538  * grammar for config files doesn't support embedded newlines in
4539  * string literals.
4540  */
4541  if (strchr(value, '\n'))
4542  ereport(ERROR,
4543  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4544  errmsg("parameter value for ALTER SYSTEM must not contain a newline")));
4545  }
4546  }
4547 
4548  /*
4549  * PG_AUTOCONF_FILENAME and its corresponding temporary file are always in
4550  * the data directory, so we can reference them by simple relative paths.
4551  */
4552  snprintf(AutoConfFileName, sizeof(AutoConfFileName), "%s",
4554  snprintf(AutoConfTmpFileName, sizeof(AutoConfTmpFileName), "%s.%s",
4555  AutoConfFileName,
4556  "tmp");
4557 
4558  /*
4559  * Only one backend is allowed to operate on PG_AUTOCONF_FILENAME at a
4560  * time. Use AutoFileLock to ensure that. We must hold the lock while
4561  * reading the old file contents.
4562  */
4563  LWLockAcquire(AutoFileLock, LW_EXCLUSIVE);
4564 
4565  /*
4566  * If we're going to reset everything, then no need to open or parse the
4567  * old file. We'll just write out an empty list.
4568  */
4569  if (!resetall)
4570  {
4571  struct stat st;
4572 
4573  if (stat(AutoConfFileName, &st) == 0)
4574  {
4575  /* open old file PG_AUTOCONF_FILENAME */
4576  FILE *infile;
4577 
4578  infile = AllocateFile(AutoConfFileName, "r");
4579  if (infile == NULL)
4580  ereport(ERROR,
4582  errmsg("could not open file \"%s\": %m",
4583  AutoConfFileName)));
4584 
4585  /* parse it */
4586  if (!ParseConfigFp(infile, AutoConfFileName, CONF_FILE_START_DEPTH,
4587  LOG, &head, &tail))
4588  ereport(ERROR,
4589  (errcode(ERRCODE_CONFIG_FILE_ERROR),
4590  errmsg("could not parse contents of file \"%s\"",
4591  AutoConfFileName)));
4592 
4593  FreeFile(infile);
4594  }
4595 
4596  /*
4597  * Now, replace any existing entry with the new value, or add it if
4598  * not present.
4599  */
4600  replace_auto_config_value(&head, &tail, name, value);
4601  }
4602 
4603  /*
4604  * Invoke the post-alter hook for setting this GUC variable. GUCs
4605  * typically do not have corresponding entries in pg_parameter_acl, so we
4606  * call the hook using the name rather than a potentially-non-existent
4607  * OID. Nonetheless, we pass ParameterAclRelationId so that this call
4608  * context can be distinguished from others. (Note that "name" will be
4609  * NULL in the RESET ALL case.)
4610  *
4611  * We do this here rather than at the end, because ALTER SYSTEM is not
4612  * transactional. If the hook aborts our transaction, it will be cleaner
4613  * to do so before we touch any files.
4614  */
4615  InvokeObjectPostAlterHookArgStr(ParameterAclRelationId, name,
4617  altersysstmt->setstmt->kind,
4618  false);
4619 
4620  /*
4621  * To ensure crash safety, first write the new file data to a temp file,
4622  * then atomically rename it into place.
4623  *
4624  * If there is a temp file left over due to a previous crash, it's okay to
4625  * truncate and reuse it.
4626  */
4627  Tmpfd = BasicOpenFile(AutoConfTmpFileName,
4628  O_CREAT | O_RDWR | O_TRUNC);
4629  if (Tmpfd < 0)
4630  ereport(ERROR,
4632  errmsg("could not open file \"%s\": %m",
4633  AutoConfTmpFileName)));
4634 
4635  /*
4636  * Use a TRY block to clean up the file if we fail. Since we need a TRY
4637  * block anyway, OK to use BasicOpenFile rather than OpenTransientFile.
4638  */
4639  PG_TRY();
4640  {
4641  /* Write and sync the new contents to the temporary file */
4642  write_auto_conf_file(Tmpfd, AutoConfTmpFileName, head);
4643 
4644  /* Close before renaming; may be required on some platforms */
4645  close(Tmpfd);
4646  Tmpfd = -1;
4647 
4648  /*
4649  * As the rename is atomic operation, if any problem occurs after this
4650  * at worst it can lose the parameters set by last ALTER SYSTEM
4651  * command.
4652  */
4653  durable_rename(AutoConfTmpFileName, AutoConfFileName, ERROR);
4654  }
4655  PG_CATCH();
4656  {
4657  /* Close file first, else unlink might fail on some platforms */
4658  if (Tmpfd >= 0)
4659  close(Tmpfd);
4660 
4661  /* Unlink, but ignore any error */
4662  (void) unlink(AutoConfTmpFileName);
4663 
4664  PG_RE_THROW();
4665  }
4666  PG_END_TRY();
4667 
4668  FreeConfigVariables(head);
4669 
4670  LWLockRelease(AutoFileLock);
4671 }
AclResult
Definition: acl.h:183
@ ACLCHECK_OK
Definition: acl.h:184
AclResult pg_parameter_aclcheck(const char *name, Oid roleid, AclMode mode)
Definition: aclchk.c:4773
#define CONF_FILE_START_DEPTH
Definition: conffiles.h:17
int errcode_for_file_access(void)
Definition: elog.c:718
#define LOG
Definition: elog.h:27
#define PG_RE_THROW()
Definition: elog.h:350
#define PG_TRY(...)
Definition: elog.h:309
#define PG_END_TRY(...)
Definition: elog.h:334
#define ERROR
Definition: elog.h:35
#define PG_CATCH(...)
Definition: elog.h:319
FILE * AllocateFile(const char *name, const char *mode)
Definition: fd.c:2383
int durable_rename(const char *oldfile, const char *newfile, int elevel)
Definition: fd.c:688
int BasicOpenFile(const char *fileName, int fileFlags)
Definition: fd.c:993
int FreeFile(FILE *file)
Definition: fd.c:2581
struct config_generic * find_option(const char *name, bool create_placeholders, bool skip_errors, int elevel)
Definition: guc.c:1163
static bool parse_and_validate_value(struct config_generic *record, const char *name, const char *value, GucSource source, int elevel, union config_var_val *newval, void **newextra)
Definition: guc.c:3065
static void write_auto_conf_file(int fd, const char *filename, ConfigVariable *head)
Definition: guc.c:4294
#define newval
static void replace_auto_config_value(ConfigVariable **head_p, ConfigVariable **tail_p, const char *name, const char *value)
Definition: guc.c:4362
#define PG_AUTOCONF_FILENAME
Definition: guc.h:33
void FreeConfigVariables(ConfigVariable *list)
bool ParseConfigFp(FILE *fp, const char *config_file, int depth, int elevel, ConfigVariable **head_p, ConfigVariable **tail_p)
#define GUC_DISALLOW_IN_FILE
Definition: guc.h:216
@ PGC_S_FILE
Definition: guc.h:112
#define GUC_DISALLOW_IN_AUTO_FILE
Definition: guc.h:221
@ PGC_INTERNAL
Definition: guc.h:69
char * ExtractSetVariableArgs(VariableSetStmt *stmt)
Definition: guc_funcs.c:167
static struct @143 value
#define close(a)
Definition: win32.h:12
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1194
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1802
@ LW_EXCLUSIVE
Definition: lwlock.h:112
Oid GetUserId(void)
Definition: miscinit.c:497
#define InvokeObjectPostAlterHookArgStr(classId, objectName, subId, auxiliaryId, is_internal)
Definition: objectaccess.h:247
@ VAR_SET_DEFAULT
Definition: parsenodes.h:2219
@ VAR_RESET
Definition: parsenodes.h:2222
@ VAR_SET_VALUE
Definition: parsenodes.h:2218
@ VAR_RESET_ALL
Definition: parsenodes.h:2223
#define ACL_ALTER_SYSTEM
Definition: parsenodes.h:96
#define MAXPGPATH
#define snprintf
Definition: port.h:238
VariableSetStmt * setstmt
Definition: parsenodes.h:3423
VariableSetKind kind
Definition: parsenodes.h:2229
bool superuser(void)
Definition: superuser.c:46
#define stat
Definition: win32_port.h:286
static void infile(const char *name)
Definition: zic.c:1243

References ACL_ALTER_SYSTEM, ACLCHECK_OK, AllocateFile(), Assert(), BasicOpenFile(), close, CONF_FILE_START_DEPTH, config_generic::context, durable_rename(), elog(), ereport, errcode(), errcode_for_file_access(), errmsg(), ERROR, ExtractSetVariableArgs(), find_option(), config_generic::flags, FreeConfigVariables(), FreeFile(), GetUserId(), GUC_DISALLOW_IN_AUTO_FILE, GUC_DISALLOW_IN_FILE, guc_free(), infile(), InvokeObjectPostAlterHookArgStr, VariableSetStmt::kind, LOG, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), MAXPGPATH, name, VariableSetStmt::name, newval, parse_and_validate_value(), ParseConfigFp(), PG_AUTOCONF_FILENAME, PG_CATCH, PG_END_TRY, pg_parameter_aclcheck(), PG_RE_THROW, PG_TRY, PGC_INTERNAL, PGC_S_FILE, PGC_STRING, replace_auto_config_value(), AlterSystemStmt::setstmt, snprintf, stat, superuser(), value, VAR_RESET, VAR_RESET_ALL, VAR_SET_DEFAULT, VAR_SET_VALUE, config_generic::vartype, and write_auto_conf_file().

Referenced by standard_ProcessUtility().

◆ AtEOXact_GUC()

void AtEOXact_GUC ( bool  isCommit,
int  nestLevel 
)

Definition at line 2197 of file guc.c.

2198 {
2199  slist_mutable_iter iter;
2200 
2201  /*
2202  * Note: it's possible to get here with GUCNestLevel == nestLevel-1 during
2203  * abort, if there is a failure during transaction start before
2204  * AtStart_GUC is called.
2205  */
2206  Assert(nestLevel > 0 &&
2207  (nestLevel <= GUCNestLevel ||
2208  (nestLevel == GUCNestLevel + 1 && !isCommit)));
2209 
2210  /* We need only process GUCs having nonempty stacks */
2212  {
2213  struct config_generic *gconf = slist_container(struct config_generic,
2214  stack_link, iter.cur);
2215  GucStack *stack;
2216 
2217  /*
2218  * Process and pop each stack entry within the nest level. To simplify
2219  * fmgr_security_definer() and other places that use GUC_ACTION_SAVE,
2220  * we allow failure exit from code that uses a local nest level to be
2221  * recovered at the surrounding transaction or subtransaction abort;
2222  * so there could be more than one stack entry to pop.
2223  */
2224  while ((stack = gconf->stack) != NULL &&
2225  stack->nest_level >= nestLevel)
2226  {
2227  GucStack *prev = stack->prev;
2228  bool restorePrior = false;
2229  bool restoreMasked = false;
2230  bool changed;
2231 
2232  /*
2233  * In this next bit, if we don't set either restorePrior or
2234  * restoreMasked, we must "discard" any unwanted fields of the
2235  * stack entries to avoid leaking memory. If we do set one of
2236  * those flags, unused fields will be cleaned up after restoring.
2237  */
2238  if (!isCommit) /* if abort, always restore prior value */
2239  restorePrior = true;
2240  else if (stack->state == GUC_SAVE)
2241  restorePrior = true;
2242  else if (stack->nest_level == 1)
2243  {
2244  /* transaction commit */
2245  if (stack->state == GUC_SET_LOCAL)
2246  restoreMasked = true;
2247  else if (stack->state == GUC_SET)
2248  {
2249  /* we keep the current active value */
2250  discard_stack_value(gconf, &stack->prior);
2251  }
2252  else /* must be GUC_LOCAL */
2253  restorePrior = true;
2254  }
2255  else if (prev == NULL ||
2256  prev->nest_level < stack->nest_level - 1)
2257  {
2258  /* decrement entry's level and do not pop it */
2259  stack->nest_level--;
2260  continue;
2261  }
2262  else
2263  {
2264  /*
2265  * We have to merge this stack entry into prev. See README for
2266  * discussion of this bit.
2267  */
2268  switch (stack->state)
2269  {
2270  case GUC_SAVE:
2271  Assert(false); /* can't get here */
2272  break;
2273 
2274  case GUC_SET:
2275  /* next level always becomes SET */
2276  discard_stack_value(gconf, &stack->prior);
2277  if (prev->state == GUC_SET_LOCAL)
2278  discard_stack_value(gconf, &prev->masked);
2279  prev->state = GUC_SET;
2280  break;
2281 
2282  case GUC_LOCAL:
2283  if (prev->state == GUC_SET)
2284  {
2285  /* LOCAL migrates down */
2286  prev->masked_scontext = stack->scontext;
2287  prev->masked_srole = stack->srole;
2288  prev->masked = stack->prior;
2289  prev->state = GUC_SET_LOCAL;
2290  }
2291  else
2292  {
2293  /* else just forget this stack level */
2294  discard_stack_value(gconf, &stack->prior);
2295  }
2296  break;
2297 
2298  case GUC_SET_LOCAL:
2299  /* prior state at this level no longer wanted */
2300  discard_stack_value(gconf, &stack->prior);
2301  /* copy down the masked state */
2303  prev->masked_srole = stack->masked_srole;
2304  if (prev->state == GUC_SET_LOCAL)
2305  discard_stack_value(gconf, &prev->masked);
2306  prev->masked = stack->masked;
2307  prev->state = GUC_SET_LOCAL;
2308  break;
2309  }
2310  }
2311 
2312  changed = false;
2313 
2314  if (restorePrior || restoreMasked)
2315  {
2316  /* Perform appropriate restoration of the stacked value */
2317  config_var_value newvalue;
2318  GucSource newsource;
2319  GucContext newscontext;
2320  Oid newsrole;
2321 
2322  if (restoreMasked)
2323  {
2324  newvalue = stack->masked;
2325  newsource = PGC_S_SESSION;
2326  newscontext = stack->masked_scontext;
2327  newsrole = stack->masked_srole;
2328  }
2329  else
2330  {
2331  newvalue = stack->prior;
2332  newsource = stack->source;
2333  newscontext = stack->scontext;
2334  newsrole = stack->srole;
2335  }
2336 
2337  switch (gconf->vartype)
2338  {
2339  case PGC_BOOL:
2340  {
2341  struct config_bool *conf = (struct config_bool *) gconf;
2342  bool newval = newvalue.val.boolval;
2343  void *newextra = newvalue.extra;
2344 
2345  if (*conf->variable != newval ||
2346  conf->gen.extra != newextra)
2347  {
2348  if (conf->assign_hook)
2349  conf->assign_hook(newval, newextra);
2350  *conf->variable = newval;
2351  set_extra_field(&conf->gen, &conf->gen.extra,
2352  newextra);
2353  changed = true;
2354  }
2355  break;
2356  }
2357  case PGC_INT:
2358  {
2359  struct config_int *conf = (struct config_int *) gconf;
2360  int newval = newvalue.val.intval;
2361  void *newextra = newvalue.extra;
2362 
2363  if (*conf->variable != newval ||
2364  conf->gen.extra != newextra)
2365  {
2366  if (conf->assign_hook)
2367  conf->assign_hook(newval, newextra);
2368  *conf->variable = newval;
2369  set_extra_field(&conf->gen, &conf->gen.extra,
2370  newextra);
2371  changed = true;
2372  }
2373  break;
2374  }
2375  case PGC_REAL:
2376  {
2377  struct config_real *conf = (struct config_real *) gconf;
2378  double newval = newvalue.val.realval;
2379  void *newextra = newvalue.extra;
2380 
2381  if (*conf->variable != newval ||
2382  conf->gen.extra != newextra)
2383  {
2384  if (conf->assign_hook)
2385  conf->assign_hook(newval, newextra);
2386  *conf->variable = newval;
2387  set_extra_field(&conf->gen, &conf->gen.extra,
2388  newextra);
2389  changed = true;
2390  }
2391  break;
2392  }
2393  case PGC_STRING:
2394  {
2395  struct config_string *conf = (struct config_string *) gconf;
2396  char *newval = newvalue.val.stringval;
2397  void *newextra = newvalue.extra;
2398 
2399  if (*conf->variable != newval ||
2400  conf->gen.extra != newextra)
2401  {
2402  if (conf->assign_hook)
2403  conf->assign_hook(newval, newextra);
2404  set_string_field(conf, conf->variable, newval);
2405  set_extra_field(&conf->gen, &conf->gen.extra,
2406  newextra);
2407  changed = true;
2408  }
2409 
2410  /*
2411  * Release stacked values if not used anymore. We
2412  * could use discard_stack_value() here, but since
2413  * we have type-specific code anyway, might as
2414  * well inline it.
2415  */
2416  set_string_field(conf, &stack->prior.val.stringval, NULL);
2417  set_string_field(conf, &stack->masked.val.stringval, NULL);
2418  break;
2419  }
2420  case PGC_ENUM:
2421  {
2422  struct config_enum *conf = (struct config_enum *) gconf;
2423  int newval = newvalue.val.enumval;
2424  void *newextra = newvalue.extra;
2425 
2426  if (*conf->variable != newval ||
2427  conf->gen.extra != newextra)
2428  {
2429  if (conf->assign_hook)
2430  conf->assign_hook(newval, newextra);
2431  *conf->variable = newval;
2432  set_extra_field(&conf->gen, &conf->gen.extra,
2433  newextra);
2434  changed = true;
2435  }
2436  break;
2437  }
2438  }
2439 
2440  /*
2441  * Release stacked extra values if not used anymore.
2442  */
2443  set_extra_field(gconf, &(stack->prior.extra), NULL);
2444  set_extra_field(gconf, &(stack->masked.extra), NULL);
2445 
2446  /* And restore source information */
2447  set_guc_source(gconf, newsource);
2448  gconf->scontext = newscontext;
2449  gconf->srole = newsrole;
2450  }
2451 
2452  /*
2453  * Pop the GUC's state stack; if it's now empty, remove the GUC
2454  * from guc_stack_list.
2455  */
2456  gconf->stack = prev;
2457  if (prev == NULL)
2458  slist_delete_current(&iter);
2459  pfree(stack);
2460 
2461  /* Report new value if we changed it */
2462  if (changed && (gconf->flags & GUC_REPORT) &&
2463  !(gconf->status & GUC_NEEDS_REPORT))
2464  {
2465  gconf->status |= GUC_NEEDS_REPORT;
2467  }
2468  } /* end of stack-popping loop */
2469  }
2470 
2471  /* Update nesting level */
2472  GUCNestLevel = nestLevel - 1;
2473 }
static slist_head guc_report_list
Definition: guc.c:221
static void set_string_field(struct config_string *conf, char **field, char *newval)
Definition: guc.c:724
static int GUCNestLevel
Definition: guc.c:226
static void discard_stack_value(struct config_generic *gconf, config_var_value *val)
Definition: guc.c:839
static slist_head guc_stack_list
Definition: guc.c:219
static void set_guc_source(struct config_generic *gconf, GucSource newsource)
Definition: guc.c:2059
static void set_extra_field(struct config_generic *gconf, void **field, void *newval)
Definition: guc.c:785
GucSource
Definition: guc.h:108
@ PGC_S_SESSION
Definition: guc.h:122
GucContext
Definition: guc.h:68
#define GUC_REPORT
Definition: guc.h:214
@ GUC_SET_LOCAL
Definition: guc_tables.h:113
@ GUC_SET
Definition: guc_tables.h:111
@ GUC_SAVE
Definition: guc_tables.h:110
@ GUC_LOCAL
Definition: guc_tables.h:112
#define GUC_NEEDS_REPORT
Definition: guc_tables.h:192
@ PGC_BOOL
Definition: guc_tables.h:25
@ PGC_ENUM
Definition: guc_tables.h:29
@ PGC_REAL
Definition: guc_tables.h:27
@ PGC_INT
Definition: guc_tables.h:26
static void slist_delete_current(slist_mutable_iter *iter)
Definition: ilist.h:1021
#define slist_foreach_modify(iter, lhead)
Definition: ilist.h:1085
static void slist_push_head(slist_head *head, slist_node *node)
Definition: ilist.h:943
#define slist_container(type, membername, ptr)
Definition: ilist.h:1043
void pfree(void *pointer)
Definition: mcxt.c:1306
unsigned int Oid
Definition: postgres_ext.h:31
struct config_generic gen
Definition: guc_tables.h:199
bool * variable
Definition: guc_tables.h:201
GucBoolAssignHook assign_hook
Definition: guc_tables.h:204
int * variable
Definition: guc_tables.h:261
GucEnumAssignHook assign_hook
Definition: guc_tables.h:265
struct config_generic gen
Definition: guc_tables.h:259
GucContext scontext
Definition: guc_tables.h:166
slist_node stack_link
Definition: guc_tables.h:174
GucStack * stack
Definition: guc_tables.h:170
slist_node report_link
Definition: guc_tables.h:176
GucIntAssignHook assign_hook
Definition: guc_tables.h:220
int * variable
Definition: guc_tables.h:215
struct config_generic gen
Definition: guc_tables.h:213
GucRealAssignHook assign_hook
Definition: guc_tables.h:236
double * variable
Definition: guc_tables.h:231
struct config_generic gen
Definition: guc_tables.h:229
GucStringAssignHook assign_hook
Definition: guc_tables.h:250
union config_var_val val
Definition: guc_tables.h:47
struct guc_stack * prev
Definition: guc_tables.h:118
Oid masked_srole
Definition: guc_tables.h:126
int nest_level
Definition: guc_tables.h:119
config_var_value masked
Definition: guc_tables.h:128
config_var_value prior
Definition: guc_tables.h:127
GucContext scontext
Definition: guc_tables.h:123
GucStackState state
Definition: guc_tables.h:120
GucSource source
Definition: guc_tables.h:121
GucContext masked_scontext
Definition: guc_tables.h:124
slist_node * cur
Definition: ilist.h:274
double realval
Definition: guc_tables.h:36
char * stringval
Definition: guc_tables.h:37

References Assert(), config_bool::assign_hook, config_int::assign_hook, config_real::assign_hook, config_string::assign_hook, config_enum::assign_hook, config_var_val::boolval, slist_mutable_iter::cur, discard_stack_value(), config_var_val::enumval, config_var_value::extra, config_generic::extra, config_generic::flags, config_bool::gen, config_int::gen, config_real::gen, config_string::gen, config_enum::gen, GUC_LOCAL, GUC_NEEDS_REPORT, GUC_REPORT, guc_report_list, GUC_SAVE, GUC_SET, GUC_SET_LOCAL, guc_stack_list, GUCNestLevel, config_var_val::intval, guc_stack::masked, guc_stack::masked_scontext, guc_stack::masked_srole, guc_stack::nest_level, newval, pfree(), PGC_BOOL, PGC_ENUM, PGC_INT, PGC_REAL, PGC_S_SESSION, PGC_STRING, guc_stack::prev, guc_stack::prior, config_var_val::realval, config_generic::report_link, guc_stack::scontext, config_generic::scontext, set_extra_field(), set_guc_source(), set_string_field(), slist_container, slist_delete_current(), slist_foreach_modify, slist_push_head(), guc_stack::source, guc_stack::srole, config_generic::srole, config_generic::stack, config_generic::stack_link, guc_stack::state, config_generic::status, config_var_val::stringval, config_var_value::val, config_bool::variable, config_int::variable, config_real::variable, config_string::variable, config_enum::variable, and config_generic::vartype.

Referenced by AbortSubTransaction(), AbortTransaction(), brin_summarize_range(), bt_index_check_internal(), cluster_rel(), CommitSubTransaction(), CommitTransaction(), ComputeIndexAttrs(), DefineIndex(), do_analyze_rel(), ExecCreateTableAs(), ExecRefreshMatView(), execute_extension_script(), fmgr_security_definer(), index_build(), index_concurrently_build(), PrepareTransaction(), ProcedureCreate(), reindex_index(), ReindexRelationConcurrently(), reset_transmission_modes(), restoreLocalGucs(), RI_Initial_Check(), RI_PartitionRemove_Check(), vacuum_rel(), and validate_index().

◆ AtStart_GUC()

void AtStart_GUC ( void  )

Definition at line 2163 of file guc.c.

2164 {
2165  /*
2166  * The nest level should be 0 between transactions; if it isn't, somebody
2167  * didn't call AtEOXact_GUC, or called it with the wrong nestLevel. We
2168  * throw a warning but make no other effort to clean up.
2169  */
2170  if (GUCNestLevel != 0)
2171  elog(WARNING, "GUC nest level = %d at transaction start",
2172  GUCNestLevel);
2173  GUCNestLevel = 1;
2174 }
#define WARNING
Definition: elog.h:32

References elog(), GUCNestLevel, and WARNING.

Referenced by StartTransaction().

◆ BeginReportingGUCOptions()

void BeginReportingGUCOptions ( void  )

Definition at line 2481 of file guc.c.

2482 {
2484  GUCHashEntry *hentry;
2485 
2486  /*
2487  * Don't do anything unless talking to an interactive frontend.
2488  */
2490  return;
2491 
2492  reporting_enabled = true;
2493 
2494  /*
2495  * Hack for in_hot_standby: set the GUC value true if appropriate. This
2496  * is kind of an ugly place to do it, but there's few better options.
2497  *
2498  * (This could be out of date by the time we actually send it, in which
2499  * case the next ReportChangedGUCOptions call will send a duplicate
2500  * report.)
2501  */
2502  if (RecoveryInProgress())
2503  SetConfigOption("in_hot_standby", "true",
2505 
2506  /* Transmit initial values of interesting variables */
2508  while ((hentry = (GUCHashEntry *) hash_seq_search(&status)) != NULL)
2509  {
2510  struct config_generic *conf = hentry->gucvar;
2511 
2512  if (conf->flags & GUC_REPORT)
2513  ReportGUCOption(conf);
2514  }
2515 }
@ DestRemote
Definition: dest.h:91
void * hash_seq_search(HASH_SEQ_STATUS *status)
Definition: dynahash.c:1431
void hash_seq_init(HASH_SEQ_STATUS *status, HTAB *hashp)
Definition: dynahash.c:1421
static void ReportGUCOption(struct config_generic *record)
Definition: guc.c:2569
void SetConfigOption(const char *name, const char *value, GucContext context, GucSource source)
Definition: guc.c:4158
static bool reporting_enabled
Definition: guc.c:224
@ PGC_S_OVERRIDE
Definition: guc.h:119
static void static void status(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:225
CommandDest whereToSendOutput
Definition: postgres.c:85
bool RecoveryInProgress(void)
Definition: xlog.c:5912

References DestRemote, config_generic::flags, guc_hashtab, GUC_REPORT, GUCHashEntry::gucvar, hash_seq_init(), hash_seq_search(), PGC_INTERNAL, PGC_S_OVERRIDE, RecoveryInProgress(), ReportGUCOption(), reporting_enabled, SetConfigOption(), status(), and whereToSendOutput.

Referenced by PostgresMain().

◆ build_guc_variables()

void build_guc_variables ( void  )

Definition at line 896 of file guc.c.

897 {
898  int size_vars;
899  int num_vars = 0;
900  HASHCTL hash_ctl;
901  GUCHashEntry *hentry;
902  bool found;
903  int i;
904 
905  /*
906  * Create the memory context that will hold all GUC-related data.
907  */
908  Assert(GUCMemoryContext == NULL);
910  "GUCMemoryContext",
912 
913  /*
914  * Count all the built-in variables, and set their vartypes correctly.
915  */
916  for (i = 0; ConfigureNamesBool[i].gen.name; i++)
917  {
918  struct config_bool *conf = &ConfigureNamesBool[i];
919 
920  /* Rather than requiring vartype to be filled in by hand, do this: */
921  conf->gen.vartype = PGC_BOOL;
922  num_vars++;
923  }
924 
925  for (i = 0; ConfigureNamesInt[i].gen.name; i++)
926  {
927  struct config_int *conf = &ConfigureNamesInt[i];
928 
929  conf->gen.vartype = PGC_INT;
930  num_vars++;
931  }
932 
933  for (i = 0; ConfigureNamesReal[i].gen.name; i++)
934  {
935  struct config_real *conf = &ConfigureNamesReal[i];
936 
937  conf->gen.vartype = PGC_REAL;
938  num_vars++;
939  }
940 
941  for (i = 0; ConfigureNamesString[i].gen.name; i++)
942  {
943  struct config_string *conf = &ConfigureNamesString[i];
944 
945  conf->gen.vartype = PGC_STRING;
946  num_vars++;
947  }
948 
949  for (i = 0; ConfigureNamesEnum[i].gen.name; i++)
950  {
951  struct config_enum *conf = &ConfigureNamesEnum[i];
952 
953  conf->gen.vartype = PGC_ENUM;
954  num_vars++;
955  }
956 
957  /*
958  * Create hash table with 20% slack
959  */
960  size_vars = num_vars + num_vars / 4;
961 
962  hash_ctl.keysize = sizeof(char *);
963  hash_ctl.entrysize = sizeof(GUCHashEntry);
964  hash_ctl.hash = guc_name_hash;
965  hash_ctl.match = guc_name_match;
966  hash_ctl.hcxt = GUCMemoryContext;
967  guc_hashtab = hash_create("GUC hash table",
968  size_vars,
969  &hash_ctl,
971 
972  for (i = 0; ConfigureNamesBool[i].gen.name; i++)
973  {
974  struct config_generic *gucvar = &ConfigureNamesBool[i].gen;
975 
976  hentry = (GUCHashEntry *) hash_search(guc_hashtab,
977  &gucvar->name,
978  HASH_ENTER,
979  &found);
980  Assert(!found);
981  hentry->gucvar = gucvar;
982  }
983 
984  for (i = 0; ConfigureNamesInt[i].gen.name; i++)
985  {
986  struct config_generic *gucvar = &ConfigureNamesInt[i].gen;
987 
988  hentry = (GUCHashEntry *) hash_search(guc_hashtab,
989  &gucvar->name,
990  HASH_ENTER,
991  &found);
992  Assert(!found);
993  hentry->gucvar = gucvar;
994  }
995 
996  for (i = 0; ConfigureNamesReal[i].gen.name; i++)
997  {
998  struct config_generic *gucvar = &ConfigureNamesReal[i].gen;
999 
1000  hentry = (GUCHashEntry *) hash_search(guc_hashtab,
1001  &gucvar->name,
1002  HASH_ENTER,
1003  &found);
1004  Assert(!found);
1005  hentry->gucvar = gucvar;
1006  }
1007 
1008  for (i = 0; ConfigureNamesString[i].gen.name; i++)
1009  {
1010  struct config_generic *gucvar = &ConfigureNamesString[i].gen;
1011 
1012  hentry = (GUCHashEntry *) hash_search(guc_hashtab,
1013  &gucvar->name,
1014  HASH_ENTER,
1015  &found);
1016  Assert(!found);
1017  hentry->gucvar = gucvar;
1018  }
1019 
1020  for (i = 0; ConfigureNamesEnum[i].gen.name; i++)
1021  {
1022  struct config_generic *gucvar = &ConfigureNamesEnum[i].gen;
1023 
1024  hentry = (GUCHashEntry *) hash_search(guc_hashtab,
1025  &gucvar->name,
1026  HASH_ENTER,
1027  &found);
1028  Assert(!found);
1029  hentry->gucvar = gucvar;
1030  }
1031 
1032  Assert(num_vars == hash_get_num_entries(guc_hashtab));
1033 }
HTAB * hash_create(const char *tabname, long nelem, const HASHCTL *info, int flags)
Definition: dynahash.c:350
long hash_get_num_entries(HTAB *hashp)
Definition: dynahash.c:1377
static int guc_name_match(const void *key1, const void *key2, Size keysize)
Definition: guc.c:1319
static uint32 guc_name_hash(const void *key, Size keysize)
Definition: guc.c:1295
static MemoryContext GUCMemoryContext
Definition: guc.c:194
struct config_string ConfigureNamesString[]
Definition: guc_tables.c:3714
struct config_int ConfigureNamesInt[]
Definition: guc_tables.c:1961
struct config_bool ConfigureNamesBool[]
Definition: guc_tables.c:780
struct config_real ConfigureNamesReal[]
Definition: guc_tables.c:3433
struct config_enum ConfigureNamesEnum[]
Definition: guc_tables.c:4478
@ HASH_ENTER
Definition: hsearch.h:114
#define HASH_CONTEXT
Definition: hsearch.h:102
#define HASH_ELEM
Definition: hsearch.h:95
#define HASH_COMPARE
Definition: hsearch.h:99
#define HASH_FUNCTION
Definition: hsearch.h:98
int i
Definition: isn.c:73
MemoryContext TopMemoryContext
Definition: mcxt.c:130
#define AllocSetContextCreate
Definition: memutils.h:129
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:153
Size keysize
Definition: hsearch.h:75
HashValueFunc hash
Definition: hsearch.h:78
Size entrysize
Definition: hsearch.h:76
HashCompareFunc match
Definition: hsearch.h:80
MemoryContext hcxt
Definition: hsearch.h:86

References ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate, Assert(), ConfigureNamesBool, ConfigureNamesEnum, ConfigureNamesInt, ConfigureNamesReal, ConfigureNamesString, HASHCTL::entrysize, config_bool::gen, config_int::gen, config_real::gen, config_string::gen, config_enum::gen, guc_hashtab, guc_name_hash(), guc_name_match(), GUCMemoryContext, GUCHashEntry::gucvar, HASHCTL::hash, HASH_COMPARE, HASH_CONTEXT, hash_create(), HASH_ELEM, HASH_ENTER, HASH_FUNCTION, hash_get_num_entries(), hash_search(), HASHCTL::hcxt, i, HASHCTL::keysize, HASHCTL::match, config_generic::name, PGC_BOOL, PGC_ENUM, PGC_INT, PGC_REAL, PGC_STRING, TopMemoryContext, and config_generic::vartype.

Referenced by GucInfoMain(), and InitializeGUCOptions().

◆ call_bool_check_hook()

static bool call_bool_check_hook ( struct config_bool conf,
bool newval,
void **  extra,
GucSource  source,
int  elevel 
)
static

Definition at line 6575 of file guc.c.

6577 {
6578  /* Quick success if no hook */
6579  if (!conf->check_hook)
6580  return true;
6581 
6582  /* Reset variables that might be set by hook */
6583  GUC_check_errcode_value = ERRCODE_INVALID_PARAMETER_VALUE;
6584  GUC_check_errmsg_string = NULL;
6586  GUC_check_errhint_string = NULL;
6587 
6588  if (!conf->check_hook(newval, extra, source))
6589  {
6590  ereport(elevel,
6594  errmsg("invalid value for parameter \"%s\": %d",
6595  conf->gen.name, (int) *newval),
6599  errhint("%s", GUC_check_errhint_string) : 0));
6600  /* Flush any strings created in ErrorContext */
6601  FlushErrorState();
6602  return false;
6603  }
6604 
6605  return true;
6606 }
int errmsg_internal(const char *fmt,...)
Definition: elog.c:993
int errdetail_internal(const char *fmt,...)
Definition: elog.c:1066
void FlushErrorState(void)
Definition: elog.c:1651
int errhint(const char *fmt,...)
Definition: elog.c:1153
char * GUC_check_errhint_string
Definition: guc.c:76
char * GUC_check_errmsg_string
Definition: guc.c:74
static int GUC_check_errcode_value
Definition: guc.c:69
char * GUC_check_errdetail_string
Definition: guc.c:75
static rewind_source * source
Definition: pg_rewind.c:81
GucBoolCheckHook check_hook
Definition: guc_tables.h:203

References config_bool::check_hook, ereport, errcode(), errdetail_internal(), errhint(), errmsg(), errmsg_internal(), config_generic::extra, FlushErrorState(), config_bool::gen, GUC_check_errcode_value, GUC_check_errdetail_string, GUC_check_errhint_string, GUC_check_errmsg_string, config_generic::name, newval, and source.

Referenced by InitializeOneGUCOption(), parse_and_validate_value(), and set_config_option_ext().

◆ call_enum_check_hook()

static bool call_enum_check_hook ( struct config_enum conf,
int *  newval,
void **  extra,
GucSource  source,
int  elevel 
)
static

Definition at line 6727 of file guc.c.

6729 {
6730  /* Quick success if no hook */
6731  if (!conf->check_hook)
6732  return true;
6733 
6734  /* Reset variables that might be set by hook */
6735  GUC_check_errcode_value = ERRCODE_INVALID_PARAMETER_VALUE;
6736  GUC_check_errmsg_string = NULL;
6738  GUC_check_errhint_string = NULL;
6739 
6740  if (!conf->check_hook(newval, extra, source))
6741  {
6742  ereport(elevel,
6746  errmsg("invalid value for parameter \"%s\": \"%s\"",
6747  conf->gen.name,
6752  errhint("%s", GUC_check_errhint_string) : 0));
6753  /* Flush any strings created in ErrorContext */
6754  FlushErrorState();
6755  return false;
6756  }
6757 
6758  return true;
6759 }
const char * config_enum_lookup_by_value(struct config_enum *record, int val)
Definition: guc.c:2958
GucEnumCheckHook check_hook
Definition: guc_tables.h:264

References config_enum::check_hook, config_enum_lookup_by_value(), ereport, errcode(), errdetail_internal(), errhint(), errmsg(), errmsg_internal(), config_generic::extra, FlushErrorState(), config_enum::gen, GUC_check_errcode_value, GUC_check_errdetail_string, GUC_check_errhint_string, GUC_check_errmsg_string, config_generic::name, newval, and source.

Referenced by InitializeOneGUCOption(), parse_and_validate_value(), and set_config_option_ext().

◆ call_int_check_hook()

static bool call_int_check_hook ( struct config_int conf,
int *  newval,
void **  extra,
GucSource  source,
int  elevel 
)
static

Definition at line 6609 of file guc.c.

6611 {
6612  /* Quick success if no hook */
6613  if (!conf->check_hook)
6614  return true;
6615 
6616  /* Reset variables that might be set by hook */
6617  GUC_check_errcode_value = ERRCODE_INVALID_PARAMETER_VALUE;
6618  GUC_check_errmsg_string = NULL;
6620  GUC_check_errhint_string = NULL;
6621 
6622  if (!conf->check_hook(newval, extra, source))
6623  {
6624  ereport(elevel,
6628  errmsg("invalid value for parameter \"%s\": %d",
6629  conf->gen.name, *newval),
6633  errhint("%s", GUC_check_errhint_string) : 0));
6634  /* Flush any strings created in ErrorContext */
6635  FlushErrorState();
6636  return false;
6637  }
6638 
6639  return true;
6640 }
GucIntCheckHook check_hook
Definition: guc_tables.h:219

References config_int::check_hook, ereport, errcode(), errdetail_internal(), errhint(), errmsg(), errmsg_internal(), config_generic::extra, FlushErrorState(), config_int::gen, GUC_check_errcode_value, GUC_check_errdetail_string, GUC_check_errhint_string, GUC_check_errmsg_string, config_generic::name, newval, and source.

Referenced by InitializeOneGUCOption(), parse_and_validate_value(), and set_config_option_ext().

◆ call_real_check_hook()

static bool call_real_check_hook ( struct config_real conf,
double *  newval,
void **  extra,
GucSource  source,
int  elevel 
)
static

Definition at line 6643 of file guc.c.

6645 {
6646  /* Quick success if no hook */
6647  if (!conf->check_hook)
6648  return true;
6649 
6650  /* Reset variables that might be set by hook */
6651  GUC_check_errcode_value = ERRCODE_INVALID_PARAMETER_VALUE;
6652  GUC_check_errmsg_string = NULL;
6654  GUC_check_errhint_string = NULL;
6655 
6656  if (!conf->check_hook(newval, extra, source))
6657  {
6658  ereport(elevel,
6662  errmsg("invalid value for parameter \"%s\": %g",
6663  conf->gen.name, *newval),
6667  errhint("%s", GUC_check_errhint_string) : 0));
6668  /* Flush any strings created in ErrorContext */
6669  FlushErrorState();
6670  return false;
6671  }
6672 
6673  return true;
6674 }
GucRealCheckHook check_hook
Definition: guc_tables.h:235

References config_real::check_hook, ereport, errcode(), errdetail_internal(), errhint(), errmsg(), errmsg_internal(), config_generic::extra, FlushErrorState(), config_real::gen, GUC_check_errcode_value, GUC_check_errdetail_string, GUC_check_errhint_string, GUC_check_errmsg_string, config_generic::name, newval, and source.

Referenced by InitializeOneGUCOption(), parse_and_validate_value(), and set_config_option_ext().

◆ call_string_check_hook()

static bool call_string_check_hook ( struct config_string conf,
char **  newval,
void **  extra,
GucSource  source,
int  elevel 
)
static

Definition at line 6677 of file guc.c.

6679 {
6680  volatile bool result = true;
6681 
6682  /* Quick success if no hook */
6683  if (!conf->check_hook)
6684  return true;
6685 
6686  /*
6687  * If elevel is ERROR, or if the check_hook itself throws an elog
6688  * (undesirable, but not always avoidable), make sure we don't leak the
6689  * already-malloc'd newval string.
6690  */
6691  PG_TRY();
6692  {
6693  /* Reset variables that might be set by hook */
6694  GUC_check_errcode_value = ERRCODE_INVALID_PARAMETER_VALUE;
6695  GUC_check_errmsg_string = NULL;
6697  GUC_check_errhint_string = NULL;
6698 
6699  if (!conf->check_hook(newval, extra, source))
6700  {
6701  ereport(elevel,
6705  errmsg("invalid value for parameter \"%s\": \"%s\"",
6706  conf->gen.name, *newval ? *newval : ""),
6710  errhint("%s", GUC_check_errhint_string) : 0));
6711  /* Flush any strings created in ErrorContext */
6712  FlushErrorState();
6713  result = false;
6714  }
6715  }
6716  PG_CATCH();
6717  {
6718  guc_free(*newval);
6719  PG_RE_THROW();
6720  }
6721  PG_END_TRY();
6722 
6723  return result;
6724 }
GucStringCheckHook check_hook
Definition: guc_tables.h:249

References config_string::check_hook, ereport, errcode(), errdetail_internal(), errhint(), errmsg(), errmsg_internal(), config_generic::extra, FlushErrorState(), config_string::gen, GUC_check_errcode_value, GUC_check_errdetail_string, GUC_check_errhint_string, GUC_check_errmsg_string, guc_free(), config_generic::name, newval, PG_CATCH, PG_END_TRY, PG_RE_THROW, PG_TRY, and source.

Referenced by InitializeOneGUCOption(), parse_and_validate_value(), and set_config_option_ext().

◆ can_skip_gucvar()

static bool can_skip_gucvar ( struct config_generic gconf)
static

Definition at line 5616 of file guc.c.

5617 {
5618  /*
5619  * We can skip GUCs that are guaranteed to have the same values in leaders
5620  * and workers. (Note it is critical that the leader and worker have the
5621  * same idea of which GUCs fall into this category. It's okay to consider
5622  * context and name for this purpose, since those are unchanging
5623  * properties of a GUC.)
5624  *
5625  * PGC_POSTMASTER variables always have the same value in every child of a
5626  * particular postmaster, so the worker will certainly have the right
5627  * value already. Likewise, PGC_INTERNAL variables are set by special
5628  * mechanisms (if indeed they aren't compile-time constants). So we may
5629  * always skip these.
5630  *
5631  * Role must be handled specially because its current value can be an
5632  * invalid value (for instance, if someone dropped the role since we set
5633  * it). So if we tried to serialize it normally, we might get a failure.
5634  * We skip it here, and use another mechanism to ensure the worker has the
5635  * right value.
5636  *
5637  * For all other GUCs, we skip if the GUC has its compiled-in default
5638  * value (i.e., source == PGC_S_DEFAULT). On the leader side, this means
5639  * we don't send GUCs that have their default values, which typically
5640  * saves lots of work. On the worker side, this means we don't need to
5641  * reset the GUC to default because it already has that value. See
5642  * comments in RestoreGUCState for more info.
5643  */
5644  return gconf->context == PGC_POSTMASTER ||
5645  gconf->context == PGC_INTERNAL || gconf->source == PGC_S_DEFAULT ||
5646  strcmp(gconf->name, "role") == 0;
5647 }
@ PGC_S_DEFAULT
Definition: guc.h:109
@ PGC_POSTMASTER
Definition: guc.h:70
GucSource source
Definition: guc_tables.h:164

References config_generic::context, config_generic::name, PGC_INTERNAL, PGC_POSTMASTER, PGC_S_DEFAULT, and config_generic::source.

Referenced by estimate_variable_size(), RestoreGUCState(), and serialize_variable().

◆ check_GUC_name_for_parameter_acl()

bool check_GUC_name_for_parameter_acl ( const char *  name)

Definition at line 1375 of file guc.c.

1376 {
1377  /* OK if the GUC exists. */
1378  if (find_option(name, false, true, DEBUG1) != NULL)
1379  return true;
1380  /* Otherwise, it'd better be a valid custom GUC name. */
1382  return true;
1383  return false;
1384 }
#define DEBUG1
Definition: elog.h:26
static bool valid_custom_variable_name(const char *name)
Definition: guc.c:1069

References DEBUG1, find_option(), name, and valid_custom_variable_name().

Referenced by ParameterAclCreate().

◆ config_enum_get_options()

char* config_enum_get_options ( struct config_enum record,
const char *  prefix,
const char *  suffix,
const char *  separator 
)

Definition at line 3007 of file guc.c.

3009 {
3010  const struct config_enum_entry *entry;
3011  StringInfoData retstr;
3012  int seplen;
3013 
3014  initStringInfo(&retstr);
3015  appendStringInfoString(&retstr, prefix);
3016 
3017  seplen = strlen(separator);
3018  for (entry = record->options; entry && entry->name; entry++)
3019  {
3020  if (!entry->hidden)
3021  {
3022  appendStringInfoString(&retstr, entry->name);
3023  appendBinaryStringInfo(&retstr, separator, seplen);
3024  }
3025  }
3026 
3027  /*
3028  * All the entries may have been hidden, leaving the string empty if no
3029  * prefix was given. This indicates a broken GUC setup, since there is no
3030  * use for an enum without any values, so we just check to make sure we
3031  * don't write to invalid memory instead of actually trying to do
3032  * something smart with it.
3033  */
3034  if (retstr.len >= seplen)
3035  {
3036  /* Replace final separator */
3037  retstr.data[retstr.len - seplen] = '\0';
3038  retstr.len -= seplen;
3039  }
3040 
3041  appendStringInfoString(&retstr, suffix);
3042 
3043  return retstr.data;
3044 }
void appendBinaryStringInfo(StringInfo str, const char *data, int datalen)
Definition: stringinfo.c:227
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:176
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
Definition: guc.h:168
const char * name
Definition: guc.h:169
bool hidden
Definition: guc.h:171
const struct config_enum_entry * options
Definition: guc_tables.h:263

References appendBinaryStringInfo(), appendStringInfoString(), StringInfoData::data, config_enum_entry::hidden, initStringInfo(), StringInfoData::len, config_enum_entry::name, and config_enum::options.

Referenced by GetConfigOptionValues(), and parse_and_validate_value().

◆ config_enum_lookup_by_name()

bool config_enum_lookup_by_name ( struct config_enum record,
const char *  value,
int *  retval 
)

Definition at line 2981 of file guc.c.

2983 {
2984  const struct config_enum_entry *entry;
2985 
2986  for (entry = record->options; entry && entry->name; entry++)
2987  {
2988  if (pg_strcasecmp(value, entry->name) == 0)
2989  {
2990  *retval = entry->val;
2991  return true;
2992  }
2993  }
2994 
2995  *retval = 0;
2996  return false;
2997 }
int pg_strcasecmp(const char *s1, const char *s2)
Definition: pgstrcasecmp.c:36
int val
Definition: guc.h:170

References config_enum_entry::name, config_enum::options, pg_strcasecmp(), config_enum_entry::val, and value.

Referenced by parse_and_validate_value().

◆ config_enum_lookup_by_value()

const char* config_enum_lookup_by_value ( struct config_enum record,
int  val 
)

Definition at line 2958 of file guc.c.

2959 {
2960  const struct config_enum_entry *entry;
2961 
2962  for (entry = record->options; entry && entry->name; entry++)
2963  {
2964  if (entry->val == val)
2965  return entry->name;
2966  }
2967 
2968  elog(ERROR, "could not find enum option %d for %s",
2969  val, record->gen.name);
2970  return NULL; /* silence compiler */
2971 }
long val
Definition: informix.c:664

References elog(), ERROR, config_enum::gen, config_enum_entry::name, config_generic::name, config_enum::options, config_enum_entry::val, and val.

Referenced by call_enum_check_hook(), estimate_variable_size(), GetConfigOption(), GetConfigOptionResetString(), GetConfigOptionValues(), serialize_variable(), and ShowGUCOption().

◆ convert_GUC_name_for_parameter_acl()

char* convert_GUC_name_for_parameter_acl ( const char *  name)

Definition at line 1339 of file guc.c.

1340 {
1341  char *result;
1342 
1343  /* Apply old-GUC-name mapping. */
1344  for (int i = 0; map_old_guc_names[i] != NULL; i += 2)
1345  {
1347  {
1348  name = map_old_guc_names[i + 1];
1349  break;
1350  }
1351  }
1352 
1353  /* Apply case-folding that matches guc_name_compare(). */
1354  result = pstrdup(name);
1355  for (char *ptr = result; *ptr != '\0'; ptr++)
1356  {
1357  char ch = *ptr;
1358 
1359  if (ch >= 'A' && ch <= 'Z')
1360  {
1361  ch += 'a' - 'A';
1362  *ptr = ch;
1363  }
1364  }
1365 
1366  return result;
1367 }
static const char *const map_old_guc_names[]
Definition: guc.c:186
int guc_name_compare(const char *namea, const char *nameb)
Definition: guc.c:1265
char * pstrdup(const char *in)
Definition: mcxt.c:1483

References guc_name_compare(), i, map_old_guc_names, name, and pstrdup().

Referenced by ParameterAclCreate(), ParameterAclLookup(), and pg_parameter_aclmask().

◆ convert_int_from_base_unit()

static void convert_int_from_base_unit ( int64  base_value,
int  base_unit,
int64 *  value,
const char **  unit 
)
static

Definition at line 2664 of file guc.c.

2666 {
2667  const unit_conversion *table;
2668  int i;
2669 
2670  *unit = NULL;
2671 
2672  if (base_unit & GUC_UNIT_MEMORY)
2674  else
2676 
2677  for (i = 0; *table[i].unit; i++)
2678  {
2679  if (base_unit == table[i].base_unit)
2680  {
2681  /*
2682  * Accept the first conversion that divides the value evenly. We
2683  * assume that the conversions for each base unit are ordered from
2684  * greatest unit to the smallest!
2685  */
2686  if (table[i].multiplier <= 1.0 ||
2687  base_value % (int64) table[i].multiplier == 0)
2688  {
2689  *value = (int64) rint(base_value / table[i].multiplier);
2690  *unit = table[i].unit;
2691  break;
2692  }
2693  }
2694  }
2695 
2696  Assert(*unit != NULL);
2697 }
static const unit_conversion memory_unit_conversion_table[]
Definition: guc.c:117
static const unit_conversion time_unit_conversion_table[]
Definition: guc.c:154
#define GUC_UNIT_MEMORY
Definition: guc.h:230
char unit[MAX_UNIT_LEN+1]
Definition: guc.c:101

References Assert(), GUC_UNIT_MEMORY, i, memory_unit_conversion_table, time_unit_conversion_table, unit_conversion::unit, and value.

Referenced by ShowGUCOption().

◆ convert_real_from_base_unit()

static void convert_real_from_base_unit ( double  base_value,
int  base_unit,
double *  value,
const char **  unit 
)
static

Definition at line 2706 of file guc.c.

2708 {
2709  const unit_conversion *table;
2710  int i;
2711 
2712  *unit = NULL;
2713 
2714  if (base_unit & GUC_UNIT_MEMORY)
2716  else
2718 
2719  for (i = 0; *table[i].unit; i++)
2720  {
2721  if (base_unit == table[i].base_unit)
2722  {
2723  /*
2724  * Accept the first conversion that divides the value evenly; or
2725  * if there is none, use the smallest (last) target unit.
2726  *
2727  * What we actually care about here is whether snprintf with "%g"
2728  * will print the value as an integer, so the obvious test of
2729  * "*value == rint(*value)" is too strict; roundoff error might
2730  * make us choose an unreasonably small unit. As a compromise,
2731  * accept a divisor that is within 1e-8 of producing an integer.
2732  */
2733  *value = base_value / table[i].multiplier;
2734  *unit = table[i].unit;
2735  if (*value > 0 &&
2736  fabs((rint(*value) / *value) - 1.0) <= 1e-8)
2737  break;
2738  }
2739  }
2740 
2741  Assert(*unit != NULL);
2742 }
e
Definition: preproc-init.c:82
double multiplier
Definition: guc.c:104

References Assert(), GUC_UNIT_MEMORY, i, memory_unit_conversion_table, unit_conversion::multiplier, time_unit_conversion_table, unit_conversion::unit, and value.

Referenced by ShowGUCOption().

◆ convert_to_base_unit()

static bool convert_to_base_unit ( double  value,
const char *  unit,
int  base_unit,
double *  base_value 
)
static

Definition at line 2606 of file guc.c.

2608 {
2609  char unitstr[MAX_UNIT_LEN + 1];
2610  int unitlen;
2611  const unit_conversion *table;
2612  int i;
2613 
2614  /* extract unit string to compare to table entries */
2615  unitlen = 0;
2616  while (*unit != '\0' && !isspace((unsigned char) *unit) &&
2617  unitlen < MAX_UNIT_LEN)
2618  unitstr[unitlen++] = *(unit++);
2619  unitstr[unitlen] = '\0';
2620  /* allow whitespace after unit */
2621  while (isspace((unsigned char) *unit))
2622  unit++;
2623  if (*unit != '\0')
2624  return false; /* unit too long, or garbage after it */
2625 
2626  /* now search the appropriate table */
2627  if (base_unit & GUC_UNIT_MEMORY)
2629  else
2631 
2632  for (i = 0; *table[i].unit; i++)
2633  {
2634  if (base_unit == table[i].base_unit &&
2635  strcmp(unitstr, table[i].unit) == 0)
2636  {
2637  double cvalue = value * table[i].multiplier;
2638 
2639  /*
2640  * If the user gave a fractional value such as "30.1GB", round it
2641  * off to the nearest multiple of the next smaller unit, if there
2642  * is one.
2643  */
2644  if (*table[i + 1].unit &&
2645  base_unit == table[i + 1].base_unit)
2646  cvalue = rint(cvalue / table[i + 1].multiplier) *
2647  table[i + 1].multiplier;
2648 
2649  *base_value = cvalue;
2650  return true;
2651  }
2652  }
2653  return false;
2654 }
#define MAX_UNIT_LEN
Definition: guc.c:97

References GUC_UNIT_MEMORY, i, MAX_UNIT_LEN, memory_unit_conversion_table, unit_conversion::multiplier, time_unit_conversion_table, unit_conversion::unit, and value.

Referenced by parse_int(), and parse_real().

◆ define_custom_variable()

static void define_custom_variable ( struct config_generic variable)
static

Definition at line 4739 of file guc.c.

4740 {
4741  const char *name = variable->name;
4742  GUCHashEntry *hentry;
4743  struct config_string *pHolder;
4744 
4745  /* Check mapping between initial and default value */
4746  Assert(check_GUC_init(variable));
4747 
4748  /*
4749  * See if there's a placeholder by the same name.
4750  */
4751  hentry = (GUCHashEntry *) hash_search(guc_hashtab,
4752  &name,
4753  HASH_FIND,
4754  NULL);
4755  if (hentry == NULL)
4756  {
4757  /*
4758  * No placeholder to replace, so we can just add it ... but first,
4759  * make sure it's initialized to its default value.
4760  */
4763  return;
4764  }
4765 
4766  /*
4767  * This better be a placeholder
4768  */
4769  if ((hentry->gucvar->flags & GUC_CUSTOM_PLACEHOLDER) == 0)
4770  ereport(ERROR,
4771  (errcode(ERRCODE_INTERNAL_ERROR),
4772  errmsg("attempt to redefine parameter \"%s\"", name)));
4773 
4774  Assert(hentry->gucvar->vartype == PGC_STRING);
4775  pHolder = (struct config_string *) hentry->gucvar;
4776 
4777  /*
4778  * First, set the variable to its default value. We must do this even
4779  * though we intend to immediately apply a new value, since it's possible
4780  * that the new value is invalid.
4781  */
4783 
4784  /*
4785  * Replace the placeholder in the hash table. We aren't changing the name
4786  * (at least up to case-folding), so the hash value is unchanged.
4787  */
4788  hentry->gucname = name;
4789  hentry->gucvar = variable;
4790 
4791  /*
4792  * Remove the placeholder from any lists it's in, too.
4793  */
4794  RemoveGUCFromLists(&pHolder->gen);
4795 
4796  /*
4797  * Assign the string value(s) stored in the placeholder to the real
4798  * variable. Essentially, we need to duplicate all the active and stacked
4799  * values, but with appropriate validation and datatype adjustment.
4800  *
4801  * If an assignment fails, we report a WARNING and keep going. We don't
4802  * want to throw ERROR for bad values, because it'd bollix the add-on
4803  * module that's presumably halfway through getting loaded. In such cases
4804  * the default or previous state will become active instead.
4805  */
4806 
4807  /* First, apply the reset value if any */
4808  if (pHolder->reset_val)
4809  (void) set_config_option_ext(name, pHolder->reset_val,
4810  pHolder->gen.reset_scontext,
4811  pHolder->gen.reset_source,
4812  pHolder->gen.reset_srole,
4813  GUC_ACTION_SET, true, WARNING, false);
4814  /* That should not have resulted in stacking anything */
4815  Assert(variable->stack == NULL);
4816 
4817  /* Now, apply current and stacked values, in the order they were stacked */
4818  reapply_stacked_values(variable, pHolder, pHolder->gen.stack,
4819  *(pHolder->variable),
4820  pHolder->gen.scontext, pHolder->gen.source,
4821  pHolder->gen.srole);
4822 
4823  /* Also copy over any saved source-location information */
4824  if (pHolder->gen.sourcefile)
4826  pHolder->gen.sourceline);
4827 
4828  /*
4829  * Free up as much as we conveniently can of the placeholder structure.
4830  * (This neglects any stack items, so it's possible for some memory to be
4831  * leaked. Since this can only happen once per session per variable, it
4832  * doesn't seem worth spending much code on.)
4833  */
4834  set_string_field(pHolder, pHolder->variable, NULL);
4835  set_string_field(pHolder, &pHolder->reset_val, NULL);
4836 
4837  guc_free(pHolder);
4838 }
int set_config_option_ext(const char *name, const char *value, GucContext context, GucSource source, Oid srole, GucAction action, bool changeVal, int elevel, bool is_reload)
Definition: guc.c:3306
static void set_config_sourcefile(const char *name, char *sourcefile, int sourceline)
Definition: guc.c:4125
static void reapply_stacked_values(struct config_generic *variable, struct config_string *pHolder, GucStack *stack, const char *curvalue, GucContext curscontext, GucSource cursource, Oid cursrole)
Definition: guc.c:4848
static void InitializeOneGUCOption(struct config_generic *gconf)
Definition: guc.c:1591
static void RemoveGUCFromLists(struct config_generic *gconf)
Definition: guc.c:1708
@ GUC_ACTION_SET
Definition: guc.h:197
@ HASH_FIND
Definition: hsearch.h:113
const char * gucname
Definition: guc.c:203
char * sourcefile
Definition: guc_tables.h:180
GucContext reset_scontext
Definition: guc_tables.h:167
GucSource reset_source
Definition: guc_tables.h:165
char * reset_val
Definition: guc_tables.h:253
char * name
Definition: type.h:178

References add_guc_variable(), Assert(), ereport, errcode(), errmsg(), ERROR, config_generic::flags, config_string::gen, GUC_ACTION_SET, GUC_CUSTOM_PLACEHOLDER, guc_free(), guc_hashtab, GUCHashEntry::gucname, GUCHashEntry::gucvar, HASH_FIND, hash_search(), InitializeOneGUCOption(), name, variable::name, PGC_STRING, reapply_stacked_values(), RemoveGUCFromLists(), config_generic::reset_scontext, config_generic::reset_source, config_generic::reset_srole, config_string::reset_val, config_generic::scontext, set_config_option_ext(), set_config_sourcefile(), set_string_field(), config_generic::source, config_generic::sourcefile, config_generic::sourceline, config_generic::srole, config_generic::stack, config_string::variable, config_generic::vartype, and WARNING.

Referenced by DefineCustomBoolVariable(), DefineCustomEnumVariable(), DefineCustomIntVariable(), DefineCustomRealVariable(), and DefineCustomStringVariable().

◆ DefineCustomBoolVariable()

void DefineCustomBoolVariable ( const char *  name,
const char *  short_desc,
const char *  long_desc,
bool valueAddr,
bool  bootValue,
GucContext  context,
int  flags,
GucBoolCheckHook  check_hook,
GucBoolAssignHook  assign_hook,
GucShowHook  show_hook 
)

Definition at line 4940 of file guc.c.

4950 {
4951  struct config_bool *var;
4952 
4953  var = (struct config_bool *)
4954  init_custom_variable(name, short_desc, long_desc, context, flags,
4955  PGC_BOOL, sizeof(struct config_bool));
4956  var->variable = valueAddr;
4957  var->boot_val = bootValue;
4958  var->reset_val = bootValue;
4959  var->check_hook = check_hook;
4960  var->assign_hook = assign_hook;
4961  var->show_hook = show_hook;
4962  define_custom_variable(&var->gen);
4963 }
static struct config_generic * init_custom_variable(const char *name, const char *short_desc, const char *long_desc, GucContext context, int flags, enum config_type type, size_t sz)
Definition: guc.c:4679
static void define_custom_variable(struct config_generic *variable)
Definition: guc.c:4739
bool reset_val
Definition: guc_tables.h:207
bool boot_val
Definition: guc_tables.h:202
GucShowHook show_hook
Definition: guc_tables.h:205

References config_bool::assign_hook, config_bool::boot_val, config_bool::check_hook, define_custom_variable(), config_bool::gen, init_custom_variable(), name, PGC_BOOL, config_bool::reset_val, config_bool::show_hook, and config_bool::variable.

Referenced by _PG_init().

◆ DefineCustomEnumVariable()

void DefineCustomEnumVariable ( const char *  name,
const char *  short_desc,
const char *  long_desc,
int *  valueAddr,
int  bootValue,
const struct config_enum_entry options,
GucContext  context,
int  flags,
GucEnumCheckHook  check_hook,
GucEnumAssignHook  assign_hook,
GucShowHook  show_hook 
)

Definition at line 5051 of file guc.c.

5062 {
5063  struct config_enum *var;
5064 
5065  var = (struct config_enum *)
5066  init_custom_variable(name, short_desc, long_desc, context, flags,
5067  PGC_ENUM, sizeof(struct config_enum));
5068  var->variable = valueAddr;
5069  var->boot_val = bootValue;
5070  var->reset_val = bootValue;
5071  var->options = options;
5072  var->check_hook = check_hook;
5073  var->assign_hook = assign_hook;
5074  var->show_hook = show_hook;
5075  define_custom_variable(&var->gen);
5076 }
static char ** options
GucShowHook show_hook
Definition: guc_tables.h:266

References config_enum::assign_hook, config_enum::boot_val, config_enum::check_hook, define_custom_variable(), config_enum::gen, init_custom_variable(), name, options, config_enum::options, PGC_ENUM, config_enum::reset_val, config_enum::show_hook, and config_enum::variable.

Referenced by _PG_init().

◆ DefineCustomIntVariable()

void DefineCustomIntVariable ( const char *  name,
const char *  short_desc,
const char *  long_desc,
int *  valueAddr,
int  bootValue,
int  minValue,
int  maxValue,
GucContext  context,
int  flags,
GucIntCheckHook  check_hook,
GucIntAssignHook  assign_hook,
GucShowHook  show_hook 
)

Definition at line 4966 of file guc.c.

4978 {
4979  struct config_int *var;
4980 
4981  var = (struct config_int *)
4982  init_custom_variable(name, short_desc, long_desc, context, flags,
4983  PGC_INT, sizeof(struct config_int));
4984  var->variable = valueAddr;
4985  var->boot_val = bootValue;
4986  var->reset_val = bootValue;
4987  var->min = minValue;
4988  var->max = maxValue;
4989  var->check_hook = check_hook;
4990  var->assign_hook = assign_hook;
4991  var->show_hook = show_hook;
4992  define_custom_variable(&var->gen);
4993 }
int reset_val
Definition: guc_tables.h:223
int boot_val
Definition: guc_tables.h:216
GucShowHook show_hook
Definition: guc_tables.h:221

References config_int::assign_hook, config_int::boot_val, config_int::check_hook, define_custom_variable(), config_int::gen, init_custom_variable(), config_int::max, config_int::min, name, PGC_INT, config_int::reset_val, config_int::show_hook, and config_int::variable.

Referenced by _PG_init().

◆ DefineCustomRealVariable()

void DefineCustomRealVariable ( const char *  name,
const char *  short_desc,
const char *  long_desc,
double *  valueAddr,
double  bootValue,
double  minValue,
double  maxValue,
GucContext  context,
int  flags,
GucRealCheckHook  check_hook,
GucRealAssignHook  assign_hook,
GucShowHook  show_hook 
)

Definition at line 4996 of file guc.c.

5008 {
5009  struct config_real *var;
5010 
5011  var = (struct config_real *)
5012  init_custom_variable(name, short_desc, long_desc, context, flags,
5013  PGC_REAL, sizeof(struct config_real));
5014  var->variable = valueAddr;
5015  var->boot_val = bootValue;
5016  var->reset_val = bootValue;
5017  var->min = minValue;
5018  var->max = maxValue;
5019  var->check_hook = check_hook;
5020  var->assign_hook = assign_hook;
5021  var->show_hook = show_hook;
5022  define_custom_variable(&var->gen);
5023 }
double boot_val
Definition: guc_tables.h:232
double reset_val
Definition: guc_tables.h:239
double min
Definition: guc_tables.h:233
double max
Definition: guc_tables.h:234
GucShowHook show_hook
Definition: guc_tables.h:237

References config_real::assign_hook, config_real::boot_val, config_real::check_hook, define_custom_variable(), config_real::gen, init_custom_variable(), config_real::max, config_real::min, name, PGC_REAL, config_real::reset_val, config_real::show_hook, and config_real::variable.

Referenced by _PG_init().

◆ DefineCustomStringVariable()

void DefineCustomStringVariable ( const char *  name,
const char *  short_desc,
const char *  long_desc,
char **  valueAddr,
const char *  bootValue,
GucContext  context,
int  flags,
GucStringCheckHook  check_hook,
GucStringAssignHook  assign_hook,
GucShowHook  show_hook 
)

Definition at line 5026 of file guc.c.

5036 {
5037  struct config_string *var;
5038 
5039  var = (struct config_string *)
5040  init_custom_variable(name, short_desc, long_desc, context, flags,
5041  PGC_STRING, sizeof(struct config_string));
5042  var->variable = valueAddr;
5043  var->boot_val = bootValue;
5044  var->check_hook = check_hook;
5045  var->assign_hook = assign_hook;
5046  var->show_hook = show_hook;
5047  define_custom_variable(&var->gen);
5048 }
GucShowHook show_hook
Definition: guc_tables.h:251
const char * boot_val
Definition: guc_tables.h:248

References config_string::assign_hook, config_string::boot_val, config_string::check_hook, define_custom_variable(), config_string::gen, init_custom_variable(), name, PGC_STRING, config_string::show_hook, and config_string::variable.

Referenced by _PG_init().

◆ discard_stack_value()

static void discard_stack_value ( struct config_generic gconf,
config_var_value val 
)
static

Definition at line 839 of file guc.c.

840 {
841  switch (gconf->vartype)
842  {
843  case PGC_BOOL:
844  case PGC_INT:
845  case PGC_REAL:
846  case PGC_ENUM:
847  /* no need to do anything */
848  break;
849  case PGC_STRING:
850  set_string_field((struct config_string *) gconf,
851  &(val->val.stringval),
852  NULL);
853  break;
854  }
855  set_extra_field(gconf, &(val->extra), NULL);
856 }

References PGC_BOOL, PGC_ENUM, PGC_INT, PGC_REAL, PGC_STRING, set_extra_field(), set_string_field(), val, and config_generic::vartype.

Referenced by AtEOXact_GUC(), and push_old_value().

◆ do_serialize()

static void do_serialize ( char **  destptr,
Size maxbytes,
const char *  fmt,
  ... 
)
static

Definition at line 5787 of file guc.c.

5788 {
5789  va_list vargs;
5790  int n;
5791 
5792  if (*maxbytes <= 0)
5793  elog(ERROR, "not enough space to serialize GUC state");
5794 
5795  va_start(vargs, fmt);
5796  n = vsnprintf(*destptr, *maxbytes, fmt, vargs);
5797  va_end(vargs);
5798 
5799  if (n < 0)
5800  {
5801  /* Shouldn't happen. Better show errno description. */
5802  elog(ERROR, "vsnprintf failed: %m with format string \"%s\"", fmt);
5803  }
5804  if (n >= *maxbytes)
5805  {
5806  /* This shouldn't happen either, really. */
5807  elog(ERROR, "not enough space to serialize GUC state");
5808  }
5809 
5810  /* Shift the destptr ahead of the null terminator */
5811  *destptr += n + 1;
5812  *maxbytes -= n + 1;
5813 }
static void const char * fmt
va_end(args)
va_start(args, fmt)
#define vsnprintf
Definition: port.h:237

References elog(), ERROR, fmt, va_end(), va_start(), and vsnprintf.

Referenced by serialize_variable().

◆ do_serialize_binary()

static void do_serialize_binary ( char **  destptr,
Size maxbytes,
void *  val,
Size  valsize 
)
static

Definition at line 5817 of file guc.c.

5818 {
5819  if (valsize > *maxbytes)
5820  elog(ERROR, "not enough space to serialize GUC state");
5821 
5822  memcpy(*destptr, val, valsize);
5823  *destptr += valsize;
5824  *maxbytes -= valsize;
5825 }

References elog(), ERROR, and val.

Referenced by serialize_variable().

◆ estimate_variable_size()

static Size estimate_variable_size ( struct config_generic gconf)
static

Definition at line 5656 of file guc.c.

5657 {
5658  Size size;
5659  Size valsize = 0;
5660 
5661  /* Skippable GUCs consume zero space. */
5662  if (can_skip_gucvar(gconf))
5663  return 0;
5664 
5665  /* Name, plus trailing zero byte. */
5666  size = strlen(gconf->name) + 1;
5667 
5668  /* Get the maximum display length of the GUC value. */
5669  switch (gconf->vartype)
5670  {
5671  case PGC_BOOL:
5672  {
5673  valsize = 5; /* max(strlen('true'), strlen('false')) */
5674  }
5675  break;
5676 
5677  case PGC_INT:
5678  {
5679  struct config_int *conf = (struct config_int *) gconf;
5680 
5681  /*
5682  * Instead of getting the exact display length, use max
5683  * length. Also reduce the max length for typical ranges of
5684  * small values. Maximum value is 2147483647, i.e. 10 chars.
5685  * Include one byte for sign.
5686  */
5687  if (abs(*conf->variable) < 1000)
5688  valsize = 3 + 1;
5689  else
5690  valsize = 10 + 1;
5691  }
5692  break;
5693 
5694  case PGC_REAL:
5695  {
5696  /*
5697  * We are going to print it with %e with REALTYPE_PRECISION
5698  * fractional digits. Account for sign, leading digit,
5699  * decimal point, and exponent with up to 3 digits. E.g.
5700  * -3.99329042340000021e+110
5701  */
5702  valsize = 1 + 1 + 1 + REALTYPE_PRECISION + 5;
5703  }
5704  break;
5705 
5706  case PGC_STRING:
5707  {
5708  struct config_string *conf = (struct config_string *) gconf;
5709 
5710  /*
5711  * If the value is NULL, we transmit it as an empty string.
5712  * Although this is not physically the same value, GUC
5713  * generally treats a NULL the same as empty string.
5714  */
5715  if (*conf->variable)
5716  valsize = strlen(*conf->variable);
5717  else
5718  valsize = 0;
5719  }
5720  break;
5721 
5722  case PGC_ENUM:
5723  {
5724  struct config_enum *conf = (struct config_enum *) gconf;
5725 
5726  valsize = strlen(config_enum_lookup_by_value(conf, *conf->variable));
5727  }
5728  break;
5729  }
5730 
5731  /* Allow space for terminating zero-byte for value */
5732  size = add_size(size, valsize + 1);
5733 
5734  if (gconf->sourcefile)
5735  size = add_size(size, strlen(gconf->sourcefile));
5736 
5737  /* Allow space for terminating zero-byte for sourcefile */
5738  size = add_size(size, 1);
5739 
5740  /* Include line whenever file is nonempty. */
5741  if (gconf->sourcefile && gconf->sourcefile[0])
5742  size = add_size(size, sizeof(gconf->sourceline));
5743 
5744  size = add_size(size, sizeof(gconf->source));
5745  size = add_size(size, sizeof(gconf->scontext));
5746  size = add_size(size, sizeof(gconf->srole));
5747 
5748  return size;
5749 }
size_t Size
Definition: c.h:541
static bool can_skip_gucvar(struct config_generic *gconf)
Definition: guc.c:5616
#define REALTYPE_PRECISION
Definition: guc.c:67
Size add_size(Size s1, Size s2)
Definition: shmem.c:502

References add_size(), can_skip_gucvar(), config_enum_lookup_by_value(), config_generic::name, PGC_BOOL, PGC_ENUM, PGC_INT, PGC_REAL, PGC_STRING, REALTYPE_PRECISION, config_generic::scontext, config_generic::source, config_generic::sourcefile, config_generic::sourceline, config_generic::srole, config_int::variable, config_string::variable, config_enum::variable, and config_generic::vartype.

Referenced by EstimateGUCStateSpace().

◆ EstimateGUCStateSpace()

Size EstimateGUCStateSpace ( void  )

Definition at line 5756 of file guc.c.

5757 {
5758  Size size;
5759  dlist_iter iter;
5760 
5761  /* Add space reqd for saving the data size of the guc state */
5762  size = sizeof(Size);
5763 
5764  /*
5765  * Add up the space needed for each GUC variable.
5766  *
5767  * We need only process non-default GUCs.
5768  */
5770  {
5771  struct config_generic *gconf = dlist_container(struct config_generic,
5772  nondef_link, iter.cur);
5773 
5774  size = add_size(size, estimate_variable_size(gconf));
5775  }
5776 
5777  return size;
5778 }
static dlist_head guc_nondef_list
Definition: guc.c:217
static Size estimate_variable_size(struct config_generic *gconf)
Definition: guc.c:5656
#define dlist_foreach(iter, lhead)
Definition: ilist.h:573
#define dlist_container(type, membername, ptr)
Definition: ilist.h:543
dlist_node nondef_link
Definition: guc_tables.h:172
dlist_node * cur
Definition: ilist.h:179

References add_size(), dlist_iter::cur, dlist_container, dlist_foreach, estimate_variable_size(), guc_nondef_list, and config_generic::nondef_link.

Referenced by InitializeParallelDSM().

◆ extra_field_used()

static bool extra_field_used ( struct config_generic gconf,
void *  extra 
)
static

Definition at line 740 of file guc.c.

741 {
742  GucStack *stack;
743 
744  if (extra == gconf->extra)
745  return true;
746  switch (gconf->vartype)
747  {
748  case PGC_BOOL:
749  if (extra == ((struct config_bool *) gconf)->reset_extra)
750  return true;
751  break;
752  case PGC_INT:
753  if (extra == ((struct config_int *) gconf)->reset_extra)
754  return true;
755  break;
756  case PGC_REAL:
757  if (extra == ((struct config_real *) gconf)->reset_extra)
758  return true;
759  break;
760  case PGC_STRING:
761  if (extra == ((struct config_string *) gconf)->reset_extra)
762  return true;
763  break;
764  case PGC_ENUM:
765  if (extra == ((struct config_enum *) gconf)->reset_extra)
766  return true;
767  break;
768  }
769  for (stack = gconf->stack; stack; stack = stack->prev)
770  {
771  if (extra == stack->prior.extra ||
772  extra == stack->masked.extra)
773  return true;
774  }
775 
776  return false;
777 }

References config_var_value::extra, config_generic::extra, guc_stack::masked, PGC_BOOL, PGC_ENUM, PGC_INT, PGC_REAL, PGC_STRING, guc_stack::prev, guc_stack::prior, config_generic::stack, and config_generic::vartype.

Referenced by set_config_option_ext(), and set_extra_field().

◆ find_option()

struct config_generic* find_option ( const char *  name,
bool  create_placeholders,
bool  skip_errors,
int  elevel 
)

Definition at line 1163 of file guc.c.

1165 {
1166  GUCHashEntry *hentry;
1167  int i;
1168 
1169  Assert(name);
1170 
1171  /* Look it up using the hash table. */
1172  hentry = (GUCHashEntry *) hash_search(guc_hashtab,
1173  &name,
1174  HASH_FIND,
1175  NULL);
1176  if (hentry)
1177  return hentry->gucvar;
1178 
1179  /*
1180  * See if the name is an obsolete name for a variable. We assume that the
1181  * set of supported old names is short enough that a brute-force search is
1182  * the best way.
1183  */
1184  for (i = 0; map_old_guc_names[i] != NULL; i += 2)
1185  {
1187  return find_option(map_old_guc_names[i + 1], false,
1188  skip_errors, elevel);
1189  }
1190 
1191  if (create_placeholders)
1192  {
1193  /*
1194  * Check if the name is valid, and if so, add a placeholder. If it
1195  * doesn't contain a separator, don't assume that it was meant to be a
1196  * placeholder.
1197  */
1198  const char *sep = strchr(name, GUC_QUALIFIER_SEPARATOR);
1199 
1200  if (sep != NULL)
1201  {
1202  size_t classLen = sep - name;
1203  ListCell *lc;
1204 
1205  /* The name must be syntactically acceptable ... */
1207  {
1208  if (!skip_errors)
1209  ereport(elevel,
1210  (errcode(ERRCODE_INVALID_NAME),
1211  errmsg("invalid configuration parameter name \"%s\"",
1212  name),
1213  errdetail("Custom parameter names must be two or more simple identifiers separated by dots.")));
1214  return NULL;
1215  }
1216  /* ... and it must not match any previously-reserved prefix */
1217  foreach(lc, reserved_class_prefix)
1218  {
1219  const char *rcprefix = lfirst(lc);
1220 
1221  if (strlen(rcprefix) == classLen &&
1222  strncmp(name, rcprefix, classLen) == 0)
1223  {
1224  if (!skip_errors)
1225  ereport(elevel,
1226  (errcode(ERRCODE_INVALID_NAME),
1227  errmsg("invalid configuration parameter name \"%s\"",
1228  name),
1229  errdetail("\"%s\" is a reserved prefix.",
1230  rcprefix)));
1231  return NULL;
1232  }
1233  }
1234  /* OK, create it */
1235  return add_placeholder_variable(name, elevel);
1236  }
1237  }
1238 
1239  /* Unknown name */
1240  if (!skip_errors)
1241  ereport(elevel,
1242  (errcode(ERRCODE_UNDEFINED_OBJECT),
1243  errmsg("unrecognized configuration parameter \"%s\"",
1244  name)));
1245  return NULL;
1246 }
int errdetail(const char *fmt,...)
Definition: elog.c:1039
static List * reserved_class_prefix
Definition: guc.c:71
static struct config_generic * add_placeholder_variable(const char *name, int elevel)
Definition: guc.c:1105
#define GUC_QUALIFIER_SEPARATOR
Definition: guc.h:202
#define lfirst(lc)
Definition: pg_list.h:170

References add_placeholder_variable(), Assert(), ereport, errcode(), errdetail(), errmsg(), guc_hashtab, guc_name_compare(), GUC_QUALIFIER_SEPARATOR, GUCHashEntry::gucvar, HASH_FIND, hash_search(), i, lfirst, map_old_guc_names, name, reserved_class_prefix, and valid_custom_variable_name().

Referenced by AlterSystemSetConfigFile(), check_GUC_name_for_parameter_acl(), flatten_set_variable_args(), GetConfigOption(), GetConfigOptionByName(), GetConfigOptionFlags(), GetConfigOptionResetString(), GUCArrayAdd(), GUCArrayDelete(), InitializeWalConsistencyChecking(), pg_settings_get_flags(), ProcessConfigFileInternal(), SelectConfigFiles(), set_config_option_ext(), set_config_sourcefile(), and validate_option_array_item().

◆ get_config_unit_name()

const char* get_config_unit_name ( int  flags)

Definition at line 2749 of file guc.c.

2750 {
2751  switch (flags & (GUC_UNIT_MEMORY | GUC_UNIT_TIME))
2752  {
2753  case 0:
2754  return NULL; /* GUC has no units */
2755  case GUC_UNIT_BYTE:
2756  return "B";
2757  case GUC_UNIT_KB:
2758  return "kB";
2759  case GUC_UNIT_MB:
2760  return "MB";
2761  case GUC_UNIT_BLOCKS:
2762  {
2763  static char bbuf[8];
2764 
2765  /* initialize if first time through */
2766  if (bbuf[0] == '\0')
2767  snprintf(bbuf, sizeof(bbuf), "%dkB", BLCKSZ / 1024);
2768  return bbuf;
2769  }
2770  case GUC_UNIT_XBLOCKS:
2771  {
2772  static char xbuf[8];
2773 
2774  /* initialize if first time through */
2775  if (xbuf[0] == '\0')
2776  snprintf(xbuf, sizeof(xbuf), "%dkB", XLOG_BLCKSZ / 1024);
2777  return xbuf;
2778  }
2779  case GUC_UNIT_MS:
2780  return "ms";
2781  case GUC_UNIT_S:
2782  return "s";
2783  case GUC_UNIT_MIN:
2784  return "min";
2785  default:
2786  elog(ERROR, "unrecognized GUC units value: %d",
2787  flags & (GUC_UNIT_MEMORY | GUC_UNIT_TIME));
2788  return NULL;
2789  }
2790 }
#define GUC_UNIT_MB
Definition: guc.h:228
#define GUC_UNIT_TIME
Definition: guc.h:235
#define GUC_UNIT_MS
Definition: guc.h:232
#define GUC_UNIT_BLOCKS
Definition: guc.h:226
#define GUC_UNIT_XBLOCKS
Definition: guc.h:227
#define GUC_UNIT_BYTE
Definition: guc.h:229
#define GUC_UNIT_S
Definition: guc.h:233
#define GUC_UNIT_KB
Definition: guc.h:225
#define GUC_UNIT_MIN
Definition: guc.h:234

References elog(), ERROR, config_generic::flags, GUC_UNIT_BLOCKS, GUC_UNIT_BYTE, GUC_UNIT_KB, GUC_UNIT_MB, GUC_UNIT_MEMORY, GUC_UNIT_MIN, GUC_UNIT_MS, GUC_UNIT_S, GUC_UNIT_TIME, GUC_UNIT_XBLOCKS, and snprintf.

Referenced by GetConfigOptionValues(), and parse_and_validate_value().

◆ get_explain_guc_options()

struct config_generic** get_explain_guc_options ( int *  num)

Definition at line 5139 of file guc.c.

5140 {
5141  struct config_generic **result;
5142  dlist_iter iter;
5143 
5144  *num = 0;
5145 
5146  /*
5147  * While only a fraction of all the GUC variables are marked GUC_EXPLAIN,
5148  * it doesn't seem worth dynamically resizing this array.
5149  */
5150  result = palloc(sizeof(struct config_generic *) * hash_get_num_entries(guc_hashtab));
5151 
5152  /* We need only consider GUCs with source not PGC_S_DEFAULT */
5154  {
5155  struct config_generic *conf = dlist_container(struct config_generic,
5156  nondef_link, iter.cur);
5157  bool modified;
5158 
5159  /* return only parameters marked for inclusion in explain */
5160  if (!(conf->flags & GUC_EXPLAIN))
5161  continue;
5162 
5163  /* return only options visible to the current user */
5164  if ((conf->flags & GUC_NO_SHOW_ALL) ||
5165  ((conf->flags & GUC_SUPERUSER_ONLY) &&
5166  !has_privs_of_role(GetUserId(), ROLE_PG_READ_ALL_SETTINGS)))
5167  continue;
5168 
5169  /* return only options that are different from their boot values */
5170  modified = false;
5171 
5172  switch (conf->vartype)
5173  {
5174  case PGC_BOOL:
5175  {
5176  struct config_bool *lconf = (struct config_bool *) conf;
5177 
5178  modified = (lconf->boot_val != *(lconf->variable));
5179  }
5180  break;
5181 
5182  case PGC_INT:
5183  {
5184  struct config_int *lconf = (struct config_int *) conf;
5185 
5186  modified = (lconf->boot_val != *(lconf->variable));
5187  }
5188  break;
5189 
5190  case PGC_REAL:
5191  {
5192  struct config_real *lconf = (struct config_real *) conf;
5193 
5194  modified = (lconf->boot_val != *(lconf->variable));
5195  }
5196  break;
5197 
5198  case PGC_STRING:
5199  {
5200  struct config_string *lconf = (struct config_string *) conf;
5201 
5202  modified = (strcmp(lconf->boot_val, *(lconf->variable)) != 0);
5203  }
5204  break;
5205 
5206  case PGC_ENUM:
5207  {
5208  struct config_enum *lconf = (struct config_enum *) conf;
5209 
5210  modified = (lconf->boot_val != *(lconf->variable));
5211  }
5212  break;
5213 
5214  default:
5215  elog(ERROR, "unexpected GUC type: %d", conf->vartype);
5216  }
5217 
5218  if (!modified)
5219  continue;
5220 
5221  /* OK, report it */
5222  result[*num] = conf;
5223  *num = *num + 1;
5224  }
5225 
5226  return result;
5227 }
bool has_privs_of_role(Oid member, Oid role)
Definition: acl.c:4949
#define GUC_EXPLAIN
Definition: guc.h:213
#define GUC_SUPERUSER_ONLY
Definition: guc.h:218
void * palloc(Size size)
Definition: mcxt.c:1199

References config_bool::boot_val, config_int::boot_val, config_real::boot_val, config_string::boot_val, config_enum::boot_val, dlist_iter::cur, dlist_container, dlist_foreach, elog(), ERROR, config_generic::flags, GetUserId(), GUC_EXPLAIN, guc_hashtab, GUC_NO_SHOW_ALL, guc_nondef_list, GUC_SUPERUSER_ONLY, has_privs_of_role(), hash_get_num_entries(), config_generic::nondef_link, palloc(), PGC_BOOL, PGC_ENUM, PGC_INT, PGC_REAL, PGC_STRING, config_bool::variable, config_int::variable, config_real::variable, config_string::variable, config_enum::variable, and config_generic::vartype.

Referenced by ExplainPrintSettings().

◆ get_guc_variables()

struct config_generic** get_guc_variables ( int *  num_vars)

Definition at line 865 of file guc.c.

866 {
867  struct config_generic **result;
869  GUCHashEntry *hentry;
870  int i;
871 
872  *num_vars = hash_get_num_entries(guc_hashtab);
873  result = palloc(sizeof(struct config_generic *) * *num_vars);
874 
875  /* Extract pointers from the hash table */
876  i = 0;
878  while ((hentry = (GUCHashEntry *) hash_seq_search(&status)) != NULL)
879  result[i++] = hentry->gucvar;
880  Assert(i == *num_vars);
881 
882  /* Sort by name */
883  qsort(result, *num_vars,
884  sizeof(struct config_generic *), guc_var_compare);
885 
886  return result;
887 }
static int guc_var_compare(const void *a, const void *b)
Definition: guc.c:1253
#define qsort(a, b, c, d)
Definition: port.h:445

References Assert(), guc_hashtab, guc_var_compare(), GUCHashEntry::gucvar, hash_get_num_entries(), hash_seq_init(), hash_seq_search(), i, palloc(), qsort, and status().

Referenced by GucInfoMain(), show_all_settings(), and ShowAllGUCConfig().

◆ GetConfigOption()

const char* GetConfigOption ( const char *  name,
bool  missing_ok,
bool  restrict_privileged 
)

Definition at line 4182 of file guc.c.

4183 {
4184  struct config_generic *record;
4185  static char buffer[256];
4186 
4187  record = find_option(name, false, missing_ok, ERROR);
4188  if (record == NULL)
4189  return NULL;
4190  if (restrict_privileged &&
4191  (record->flags & GUC_SUPERUSER_ONLY) &&
4192  !has_privs_of_role(GetUserId(), ROLE_PG_READ_ALL_SETTINGS))
4193  ereport(ERROR,
4194  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
4195  errmsg("must be superuser or have privileges of pg_read_all_settings to examine \"%s\"",
4196  name)));
4197 
4198  switch (record->vartype)
4199  {
4200  case PGC_BOOL:
4201  return *((struct config_bool *) record)->variable ? "on" : "off";
4202 
4203  case PGC_INT:
4204  snprintf(buffer, sizeof(buffer), "%d",
4205  *((struct config_int *) record)->variable);
4206  return buffer;
4207 
4208  case PGC_REAL:
4209  snprintf(buffer, sizeof(buffer), "%g",
4210  *((struct config_real *) record)->variable);
4211  return buffer;
4212 
4213  case PGC_STRING:
4214  return *((struct config_string *) record)->variable;
4215 
4216  case PGC_ENUM:
4217  return config_enum_lookup_by_value((struct config_enum *) record,
4218  *((struct config_enum *) record)->variable);
4219  }
4220  return NULL;
4221 }

References config_enum_lookup_by_value(), ereport, errcode(), errmsg(), ERROR, find_option(), config_generic::flags, GetUserId(), GUC_SUPERUSER_ONLY, has_privs_of_role(), name, PGC_BOOL, PGC_ENUM, PGC_INT, PGC_REAL, PGC_STRING, snprintf, and config_generic::vartype.

Referenced by applyRemoteGucs(), be_tls_init(), PostmasterMain(), and ProcessConfigFileInternal().

◆ GetConfigOptionByName()

char* GetConfigOptionByName ( const char *  name,
const char **  varname,
bool  missing_ok 
)

Definition at line 5235 of file guc.c.

5236 {
5237  struct config_generic *record;
5238 
5239  record = find_option(name, false, missing_ok, ERROR);
5240  if (record == NULL)
5241  {
5242  if (varname)
5243  *varname = NULL;
5244  return NULL;
5245  }
5246 
5247  if ((record->flags & GUC_SUPERUSER_ONLY) &&
5248  !has_privs_of_role(GetUserId(), ROLE_PG_READ_ALL_SETTINGS))
5249  ereport(ERROR,
5250  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
5251  errmsg("must be superuser or have privileges of pg_read_all_settings to examine \"%s\"",
5252  name)));
5253 
5254  if (varname)
5255  *varname = record->name;
5256 
5257  return ShowGUCOption(record, true);
5258 }
char * ShowGUCOption(struct config_generic *record, bool use_units)
Definition: guc.c:5268

References ereport, errcode(), errmsg(), ERROR, find_option(), config_generic::flags, GetUserId(), GUC_SUPERUSER_ONLY, has_privs_of_role(), name, config_generic::name, and ShowGUCOption().

Referenced by ExplainPrintSettings(), ExtractSetVariableArgs(), GetPGVariableResultDesc(), set_config_by_name(), show_config_by_name(), show_config_by_name_missing_ok(), and ShowGUCConfigOption().

◆ GetConfigOptionFlags()

int GetConfigOptionFlags ( const char *  name,
bool  missing_ok 
)

Definition at line 4277 of file guc.c.

4278 {
4279  struct config_generic *record;
4280 
4281  record = find_option(name, false, missing_ok, ERROR);
4282  if (record == NULL)
4283  return 0;
4284  return record->flags;
4285 }

References ERROR, find_option(), config_generic::flags, and name.

Referenced by pg_get_functiondef(), and PostmasterMain().

◆ GetConfigOptionResetString()

const char* GetConfigOptionResetString ( const char *  name)

Definition at line 4231 of file guc.c.

4232 {
4233  struct config_generic *record;
4234  static char buffer[256];
4235 
4236  record = find_option(name, false, false, ERROR);
4237  Assert(record != NULL);
4238  if ((record->flags & GUC_SUPERUSER_ONLY) &&
4239  !has_privs_of_role(GetUserId(), ROLE_PG_READ_ALL_SETTINGS))
4240  ereport(ERROR,
4241  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
4242  errmsg("must be superuser or have privileges of pg_read_all_settings to examine \"%s\"",
4243  name)));
4244 
4245  switch (record->vartype)
4246  {
4247  case PGC_BOOL:
4248  return ((struct config_bool *) record)->reset_val ? "on" : "off";
4249 
4250  case PGC_INT:
4251  snprintf(buffer, sizeof(buffer), "%d",
4252  ((struct config_int *) record)->reset_val);
4253  return buffer;
4254 
4255  case PGC_REAL:
4256  snprintf(buffer, sizeof(buffer), "%g",
4257  ((struct config_real *) record)->reset_val);
4258  return buffer;
4259 
4260  case PGC_STRING:
4261  return ((struct config_string *) record)->reset_val;
4262 
4263  case PGC_ENUM:
4264  return config_enum_lookup_by_value((struct config_enum *) record,
4265  ((struct config_enum *) record)->reset_val);
4266  }
4267  return NULL;
4268 }

References Assert(), config_enum_lookup_by_value(), ereport, errcode(), errmsg(), ERROR, find_option(), config_generic::flags, GetUserId(), GUC_SUPERUSER_ONLY, has_privs_of_role(), name, PGC_BOOL, PGC_ENUM, PGC_INT, PGC_REAL, PGC_STRING, snprintf, and config_generic::vartype.

Referenced by check_datestyle().

◆ GUC_check_errcode()

◆ guc_free()

void guc_free ( void *  ptr)

Definition at line 682 of file guc.c.

683 {
684  /*
685  * Historically, GUC-related code has relied heavily on the ability to do
686  * free(NULL), so we allow that here even though pfree() doesn't.
687  */
688  if (ptr != NULL)
689  {
690  /* This is to help catch old code that malloc's GUC data. */
692  pfree(ptr);
693  }
694 }
MemoryContext GetMemoryChunkContext(void *pointer)
Definition: mcxt.c:589

References Assert(), GetMemoryChunkContext(), GUCMemoryContext, and pfree().

Referenced by add_placeholder_variable(), AlterSystemSetConfigFile(), call_string_check_hook(), check_client_encoding(), check_datestyle(), check_default_text_search_config(), define_custom_variable(), parse_and_validate_value(), ReportGUCOption(), RestoreGUCState(), SelectConfigFiles(), set_config_option_ext(), set_config_sourcefile(), set_extra_field(), and set_string_field().

◆ guc_malloc()

◆ guc_name_compare()

int guc_name_compare ( const char *  namea,
const char *  nameb 
)

Definition at line 1265 of file guc.c.

1266 {
1267  /*
1268  * The temptation to use strcasecmp() here must be resisted, because the
1269  * hash mapping has to remain stable across setlocale() calls. So, build
1270  * our own with a simple ASCII-only downcasing.
1271  */
1272  while (*namea && *nameb)
1273  {
1274  char cha = *namea++;
1275  char chb = *nameb++;
1276 
1277  if (cha >= 'A' && cha <= 'Z')
1278  cha += 'a' - 'A';
1279  if (chb >= 'A' && chb <= 'Z')
1280  chb += 'a' - 'A';
1281  if (cha != chb)
1282  return cha - chb;
1283  }
1284  if (*namea)
1285  return 1; /* a is longer */
1286  if (*nameb)
1287  return -1; /* b is longer */
1288  return 0;
1289 }

Referenced by convert_GUC_name_for_parameter_acl(), find_option(), GetPGVariable(), GetPGVariableResultDesc(), guc_name_match(), guc_var_compare(), and replace_auto_config_value().

◆ guc_name_hash()

static uint32 guc_name_hash ( const void *  key,
Size  keysize 
)
static

Definition at line 1295 of file guc.c.

1296 {
1297  uint32 result = 0;
1298  const char *name = *(const char *const *) key;
1299 
1300  while (*name)
1301  {
1302  char ch = *name++;
1303 
1304  /* Case-fold in the same way as guc_name_compare */
1305  if (ch >= 'A' && ch <= 'Z')
1306  ch += 'a' - 'A';
1307 
1308  /* Merge into hash ... not very bright, but it needn't be */
1309  result = pg_rotate_left32(result, 5);
1310  result ^= (uint32) ch;
1311  }
1312  return result;
1313 }
unsigned int uint32
Definition: c.h:442
static uint32 pg_rotate_left32(uint32 word, int n)
Definition: pg_bitutils.h:277

References sort-test::key, name, and pg_rotate_left32().

Referenced by build_guc_variables().

◆ guc_name_match()

static int guc_name_match ( const void *  key1,
const void *  key2,
Size  keysize 
)
static

Definition at line 1319 of file guc.c.

1320 {
1321  const char *name1 = *(const char *const *) key1;
1322  const char *name2 = *(const char *const *) key2;
1323 
1324  return guc_name_compare(name1, name2);
1325 }

References guc_name_compare().

Referenced by build_guc_variables().

◆ guc_realloc()

void* guc_realloc ( int  elevel,
void *  old,
size_t  size 
)

Definition at line 645 of file guc.c.

646 {
647  void *data;
648 
649  if (old != NULL)
650  {
651  /* This is to help catch old code that malloc's GUC data. */
653  data = repalloc_extended(old, size,
655  }
656  else
657  {
658  /* Like realloc(3), but not like repalloc(), we allow old == NULL. */
661  }
662  if (unlikely(data == NULL))
663  ereport(elevel,
664  (errcode(ERRCODE_OUT_OF_MEMORY),
665  errmsg("out of memory")));
666  return data;
667 }
void * repalloc_extended(void *pointer, Size size, int flags)
Definition: mcxt.c:1360

References Assert(), data, ereport, errcode(), errmsg(), GetMemoryChunkContext(), GUCMemoryContext, MCXT_ALLOC_NO_OOM, MemoryContextAllocExtended(), repalloc_extended(), and unlikely.

◆ guc_restore_error_context_callback()

static void guc_restore_error_context_callback ( void *  arg)
static

Definition at line 5979 of file guc.c.

5980 {
5981  char **error_context_name_and_value = (char **) arg;
5982 
5983  if (error_context_name_and_value)
5984  errcontext("while setting parameter \"%s\" to \"%s\"",
5985  error_context_name_and_value[0],
5986  error_context_name_and_value[1]);
5987 }
#define errcontext
Definition: elog.h:192
void * arg

References arg, and errcontext.

Referenced by RestoreGUCState().

◆ guc_strdup()

char* guc_strdup ( int  elevel,
const char *  src 
)

Definition at line 670 of file guc.c.

671 {
672  char *data;
673  size_t len = strlen(src) + 1;
674 
675  data = guc_malloc(elevel, len);
676  if (likely(data != NULL))
677  memcpy(data, src, len);
678  return data;
679 }
#define likely(x)
Definition: c.h:294
const void size_t len

References data, guc_malloc(), len, and likely.

Referenced by add_placeholder_variable(), check_application_name(), check_client_encoding(), check_cluster_name(), check_datestyle(), check_default_text_search_config(), init_custom_variable(), InitializeOneGUCOption(), parse_and_validate_value(), ReportGUCOption(), set_config_option_ext(), and set_config_sourcefile().

◆ guc_var_compare()

static int guc_var_compare ( const void *  a,
const void *  b 
)
static

Definition at line 1253 of file guc.c.

1254 {
1255  const struct config_generic *confa = *(struct config_generic *const *) a;
1256  const struct config_generic *confb = *(struct config_generic *const *) b;
1257 
1258  return guc_name_compare(confa->name, confb->name);
1259 }
int b
Definition: isn.c:70
int a
Definition: isn.c:69

References a, b, guc_name_compare(), and config_generic::name.

Referenced by get_guc_variables().

◆ GUCArrayAdd()

ArrayType* GUCArrayAdd ( ArrayType array,
const char *  name,
const char *  value 
)

Definition at line 6265 of file guc.c.

6266 {
6267  struct config_generic *record;
6268  Datum datum;
6269  char *newval;
6270  ArrayType *a;
6271 
6272  Assert(name);
6273  Assert(value);
6274 
6275  /* test if the option is valid and we're allowed to set it */
6276  (void) validate_option_array_item(name, value, false);
6277 
6278  /* normalize name (converts obsolete GUC names to modern spellings) */
6279  record = find_option(name, false, true, WARNING);
6280  if (record)
6281  name = record->name;
6282 
6283  /* build new item for array */
6284  newval = psprintf("%s=%s", name, value);
6285  datum = CStringGetTextDatum(newval);
6286 
6287  if (array)
6288  {
6289  int index;
6290  bool isnull;
6291  int i;
6292 
6293  Assert(ARR_ELEMTYPE(array) == TEXTOID);
6294  Assert(ARR_NDIM(array) == 1);
6295  Assert(ARR_LBOUND(array)[0] == 1);
6296 
6297  index = ARR_DIMS(array)[0] + 1; /* add after end */
6298 
6299  for (i = 1; i <= ARR_DIMS(array)[0]; i++)
6300  {
6301  Datum d;
6302  char *current;
6303 
6304  d = array_ref(array, 1, &i,
6305  -1 /* varlenarray */ ,
6306  -1 /* TEXT's typlen */ ,
6307  false /* TEXT's typbyval */ ,
6308  TYPALIGN_INT /* TEXT's typalign */ ,
6309  &isnull);
6310  if (isnull)
6311  continue;
6312  current = TextDatumGetCString(d);
6313 
6314  /* check for match up through and including '=' */
6315  if (strncmp(current, newval, strlen(name) + 1) == 0)
6316  {
6317  index = i;
6318  break;
6319  }
6320  }
6321 
6322  a = array_set(array, 1, &index,
6323  datum,
6324  false,
6325  -1 /* varlena array */ ,
6326  -1 /* TEXT's typlen */ ,
6327  false /* TEXT's typbyval */ ,
6328  TYPALIGN_INT /* TEXT's typalign */ );
6329  }
6330  else
6331  a = construct_array_builtin(&datum, 1, TEXTOID);
6332 
6333  return a;
6334 }
#define ARR_NDIM(a)
Definition: array.h:283
#define ARR_ELEMTYPE(a)
Definition: array.h:285
#define ARR_DIMS(a)
Definition: array.h:287
#define ARR_LBOUND(a)
Definition: array.h:289
ArrayType * construct_array_builtin(Datum *elems, int nelems, Oid elmtype)
Definition: arrayfuncs.c:3338
ArrayType * array_set(ArrayType *array, int nSubscripts, int *indx, Datum dataValue, bool isNull, int arraytyplen, int elmlen, bool elmbyval, char elmalign)
Definition: arrayfuncs.c:3120
Datum array_ref(ArrayType *array, int nSubscripts, int *indx, int arraytyplen, int elmlen, bool elmbyval, char elmalign, bool *isNull)
Definition: arrayfuncs.c:3103
#define CStringGetTextDatum(s)
Definition: builtins.h:85
#define TextDatumGetCString(d)
Definition: builtins.h:86
static bool validate_option_array_item(const char *name, const char *value, bool skipIfNoPermissions)
Definition: guc.c:6485
uintptr_t Datum
Definition: postgres.h:412
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46
Definition: type.h:95

References a, ARR_DIMS, ARR_ELEMTYPE, ARR_LBOUND, ARR_NDIM, array_ref(), array_set(), Assert(), construct_array_builtin(), CStringGetTextDatum, find_option(), i, name, config_generic::name, newval, psprintf(), TextDatumGetCString, validate_option_array_item(), value, and WARNING.

Referenced by AlterSetting(), and update_proconfig_value().

◆ GUCArrayDelete()

ArrayType* GUCArrayDelete ( ArrayType array,
const char *  name 
)

Definition at line 6343 of file guc.c.

6344 {
6345  struct config_generic *record;
6346  ArrayType *newarray;
6347  int i;
6348  int index;
6349 
6350  Assert(name);
6351 
6352  /* test if the option is valid and we're allowed to set it */
6353  (void) validate_option_array_item(name, NULL, false);
6354 
6355  /* normalize name (converts obsolete GUC names to modern spellings) */
6356  record = find_option(name, false, true, WARNING);
6357  if (record)
6358  name = record->name;
6359 
6360  /* if array is currently null, then surely nothing to delete */
6361  if (!array)
6362  return NULL;
6363 
6364  newarray = NULL;
6365  index = 1;
6366 
6367  for (i = 1; i <= ARR_DIMS(array)[0]; i++)
6368  {
6369  Datum d;
6370  char *val;
6371  bool isnull;
6372 
6373  d = array_ref(array, 1, &i,
6374  -1 /* varlenarray */ ,
6375  -1 /* TEXT's typlen */ ,
6376  false /* TEXT's typbyval */ ,
6377  TYPALIGN_INT /* TEXT's typalign */ ,
6378  &isnull);
6379  if (isnull)
6380  continue;
6381  val = TextDatumGetCString(d);
6382 
6383  /* ignore entry if it's what we want to delete */
6384  if (strncmp(val, name, strlen(name)) == 0
6385  && val[strlen(name)] == '=')
6386  continue;
6387 
6388  /* else add it to the output array */
6389  if (newarray)
6390  newarray = array_set(newarray, 1, &index,
6391  d,
6392  false,
6393  -1 /* varlenarray */ ,
6394  -1 /* TEXT's typlen */ ,
6395  false /* TEXT's typbyval */ ,
6396  TYPALIGN_INT /* TEXT's typalign */ );
6397  else
6398  newarray = construct_array_builtin(&d, 1, TEXTOID);
6399 
6400  index++;
6401  }
6402 
6403  return newarray;
6404 }

References ARR_DIMS, array_ref(), array_set(), Assert(), construct_array_builtin(), find_option(), i, name, config_generic::name, TextDatumGetCString, val, validate_option_array_item(), and WARNING.

Referenced by AlterSetting(), and update_proconfig_value().

◆ GUCArrayReset()

ArrayType* GUCArrayReset ( ArrayType array)

Definition at line 6413 of file guc.c.

6414 {
6415  ArrayType *newarray;
6416  int i;
6417  int index;
6418 
6419  /* if array is currently null, nothing to do */
6420  if (!array)
6421  return NULL;
6422 
6423  /* if we're superuser, we can delete everything, so just do it */
6424  if (superuser())
6425  return NULL;
6426 
6427  newarray = NULL;
6428  index = 1;
6429 
6430  for (i = 1; i <= ARR_DIMS(array)[0]; i++)
6431  {
6432  Datum d;
6433  char *val;
6434  char *eqsgn;
6435  bool isnull;
6436 
6437  d = array_ref(array, 1, &i,
6438  -1 /* varlenarray */ ,
6439  -1 /* TEXT's typlen */ ,
6440  false /* TEXT's typbyval */ ,
6441  TYPALIGN_INT /* TEXT's typalign */ ,
6442  &isnull);
6443  if (isnull)
6444  continue;
6445  val = TextDatumGetCString(d);
6446 
6447  eqsgn = strchr(val, '=');
6448  *eqsgn = '\0';
6449 
6450  /* skip if we have permission to delete it */
6451  if (validate_option_array_item(val, NULL, true))
6452  continue;
6453 
6454  /* else add it to the output array */
6455  if (newarray)
6456  newarray = array_set(newarray, 1, &index,
6457  d,
6458  false,
6459  -1 /* varlenarray */ ,
6460  -1 /* TEXT's typlen */ ,
6461  false /* TEXT's typbyval */ ,
6462  TYPALIGN_INT /* TEXT's typalign */ );
6463  else
6464  newarray = construct_array_builtin(&d, 1, TEXTOID);
6465 
6466  index++;
6467  pfree(val);
6468  }
6469 
6470  return newarray;
6471 }

References ARR_DIMS, array_ref(), array_set(), construct_array_builtin(), i, pfree(), superuser(), TextDatumGetCString, val, and validate_option_array_item().

Referenced by AlterSetting().

◆ init_custom_variable()

static struct config_generic* init_custom_variable ( const char *  name,
const char *  short_desc,
const char *  long_desc,
GucContext  context,
int  flags,
enum config_type  type,
size_t  sz 
)
static

Definition at line 4679 of file guc.c.

4686 {
4687  struct config_generic *gen;
4688 
4689  /*
4690  * Only allow custom PGC_POSTMASTER variables to be created during shared
4691  * library preload; any later than that, we can't ensure that the value
4692  * doesn't change after startup. This is a fatal elog if it happens; just
4693  * erroring out isn't safe because we don't know what the calling loadable
4694  * module might already have hooked into.
4695  */
4696  if (context == PGC_POSTMASTER &&
4698  elog(FATAL, "cannot create PGC_POSTMASTER variables after startup");
4699 
4700  /*
4701  * We can't support custom GUC_LIST_QUOTE variables, because the wrong
4702  * things would happen if such a variable were set or pg_dump'd when the
4703  * defining extension isn't loaded. Again, treat this as fatal because
4704  * the loadable module may be partly initialized already.
4705  */
4706  if (flags & GUC_LIST_QUOTE)
4707  elog(FATAL, "extensions cannot define GUC_LIST_QUOTE variables");
4708 
4709  /*
4710  * Before pljava commit 398f3b876ed402bdaec8bc804f29e2be95c75139
4711  * (2015-12-15), two of that module's PGC_USERSET variables facilitated
4712  * trivial escalation to superuser privileges. Restrict the variables to
4713  * protect sites that have yet to upgrade pljava.
4714  */
4715  if (context == PGC_USERSET &&
4716  (strcmp(name, "pljava.classpath") == 0 ||
4717  strcmp(name, "pljava.vmoptions") == 0))
4718  context = PGC_SUSET;
4719 
4720  gen = (struct config_generic *) guc_malloc(ERROR, sz);
4721  memset(gen, 0, sz);
4722 
4723  gen->name = guc_strdup(ERROR, name);
4724  gen->context = context;
4725  gen->group = CUSTOM_OPTIONS;
4726  gen->short_desc = short_desc;
4727  gen->long_desc = long_desc;
4728  gen->flags = flags;
4729  gen->vartype = type;
4730 
4731  return gen;
4732 }
#define FATAL
Definition: elog.h:37
#define GUC_LIST_QUOTE
Definition: guc.h:209
@ PGC_SUSET
Definition: guc.h:74
bool process_shared_preload_libraries_in_progress
Definition: miscinit.c:1765
const char * long_desc
Definition: guc_tables.h:159

References config_generic::context, CUSTOM_OPTIONS, elog(), ERROR, FATAL, config_generic::flags, config_generic::group, GUC_LIST_QUOTE, guc_malloc(), guc_strdup(), config_generic::long_desc, name, config_generic::name, PGC_POSTMASTER, PGC_SUSET, PGC_USERSET, process_shared_preload_libraries_in_progress, config_generic::short_desc, generate_unaccent_rules::type, and config_generic::vartype.

Referenced by DefineCustomBoolVariable(), DefineCustomEnumVariable(), DefineCustomIntVariable(), DefineCustomRealVariable(), and DefineCustomStringVariable().

◆ InitializeGUCOptions()

void InitializeGUCOptions ( void  )

Definition at line 1477 of file guc.c.

1478 {
1480  GUCHashEntry *hentry;
1481 
1482  /*
1483  * Before log_line_prefix could possibly receive a nonempty setting, make
1484  * sure that timezone processing is minimally alive (see elog.c).
1485  */
1487 
1488  /*
1489  * Create GUCMemoryContext and build hash table of all GUC variables.
1490  */
1492 
1493  /*
1494  * Load all variables with their compiled-in defaults, and initialize
1495  * status fields as needed.
1496  */
1498  while ((hentry = (GUCHashEntry *) hash_seq_search(&status)) != NULL)
1499  {
1500  /* Check mapping between initial and default value */
1501  Assert(check_GUC_init(hentry->gucvar));
1502 
1503  InitializeOneGUCOption(hentry->gucvar);
1504  }
1505 
1506  reporting_enabled = false;
1507 
1508  /*
1509  * Prevent any attempt to override the transaction modes from
1510  * non-interactive sources.
1511  */
1512  SetConfigOption("transaction_isolation", "read committed",
1514  SetConfigOption("transaction_read_only", "no",
1516  SetConfigOption("transaction_deferrable", "no",
1518 
1519  /*
1520  * For historical reasons, some GUC parameters can receive defaults from
1521  * environment variables. Process those settings.
1522  */
1524 }
void build_guc_variables(void)
Definition: guc.c:896
static void InitializeGUCOptionsFromEnvironment(void)
Definition: guc.c:1536
void pg_timezone_initialize(void)
Definition: pgtz.c:361

References Assert(), build_guc_variables(), guc_hashtab, GUCHashEntry::gucvar, hash_seq_init(), hash_seq_search(), InitializeGUCOptionsFromEnvironment(), InitializeOneGUCOption(), pg_timezone_initialize(), PGC_POSTMASTER, PGC_S_OVERRIDE, reporting_enabled, SetConfigOption(), and status().

Referenced by BootstrapModeMain(), PostgresSingleUserMain(), and PostmasterMain().

◆ InitializeGUCOptionsFromEnvironment()

static void InitializeGUCOptionsFromEnvironment ( void  )
static

Definition at line 1536 of file guc.c.

1537 {
1538  char *env;
1539  long stack_rlimit;
1540 
1541  env = getenv("PGPORT");
1542  if (env != NULL)
1544 
1545  env = getenv("PGDATESTYLE");
1546  if (env != NULL)
1547  SetConfigOption("datestyle", env, PGC_POSTMASTER, PGC_S_ENV_VAR);
1548 
1549  env = getenv("PGCLIENTENCODING");
1550  if (env != NULL)
1551  SetConfigOption("client_encoding", env, PGC_POSTMASTER, PGC_S_ENV_VAR);
1552 
1553  /*
1554  * rlimit isn't exactly an "environment variable", but it behaves about
1555  * the same. If we can identify the platform stack depth rlimit, increase
1556  * default stack depth setting up to whatever is safe (but at most 2MB).
1557  * Report the value's source as PGC_S_DYNAMIC_DEFAULT if it's 2MB, or as
1558  * PGC_S_ENV_VAR if it's reflecting the rlimit limit.
1559  */
1560  stack_rlimit = get_stack_depth_rlimit();
1561  if (stack_rlimit > 0)
1562  {
1563  long new_limit = (stack_rlimit - STACK_DEPTH_SLOP) / 1024L;
1564 
1565  if (new_limit > 100)
1566  {
1567  GucSource source;
1568  char limbuf[16];
1569 
1570  if (new_limit < 2048)
1572  else
1573  {
1574  new_limit = 2048;
1576  }
1577  snprintf(limbuf, sizeof(limbuf), "%ld", new_limit);
1578  SetConfigOption("max_stack_depth", limbuf,
1580  }
1581  }
1582 }
@ PGC_S_DYNAMIC_DEFAULT
Definition: guc.h:110
@ PGC_S_ENV_VAR
Definition: guc.h:111
long get_stack_depth_rlimit(void)
Definition: postgres.c:4817
#define STACK_DEPTH_SLOP
Definition: tcopprot.h:26

References get_stack_depth_rlimit(), PGC_POSTMASTER, PGC_S_DYNAMIC_DEFAULT, PGC_S_ENV_VAR, SetConfigOption(), snprintf, source, and STACK_DEPTH_SLOP.

Referenced by InitializeGUCOptions(), and ProcessConfigFileInternal().

◆ InitializeOneGUCOption()

static void InitializeOneGUCOption ( struct config_generic gconf)
static

Definition at line 1591 of file guc.c.

1592 {
1593  gconf->status = 0;
1594  gconf->source = PGC_S_DEFAULT;
1595  gconf->reset_source = PGC_S_DEFAULT;
1596  gconf->scontext = PGC_INTERNAL;
1597  gconf->reset_scontext = PGC_INTERNAL;
1598  gconf->srole = BOOTSTRAP_SUPERUSERID;
1599  gconf->reset_srole = BOOTSTRAP_SUPERUSERID;
1600  gconf->stack = NULL;
1601  gconf->extra = NULL;
1602  gconf->last_reported = NULL;
1603  gconf->sourcefile = NULL;
1604  gconf->sourceline = 0;
1605 
1606  switch (gconf->vartype)
1607  {
1608  case PGC_BOOL:
1609  {
1610  struct config_bool *conf = (struct config_bool *) gconf;
1611  bool newval = conf->boot_val;
1612  void *extra = NULL;
1613 
1614  if (!call_bool_check_hook(conf, &newval, &extra,
1615  PGC_S_DEFAULT, LOG))
1616  elog(FATAL, "failed to initialize %s to %d",
1617  conf->gen.name, (int) newval);
1618  if (conf->assign_hook)
1619  conf->assign_hook(newval, extra);
1620  *conf->variable = conf->reset_val = newval;
1621  conf->gen.extra = conf->reset_extra = extra;
1622  break;
1623  }
1624  case PGC_INT:
1625  {
1626  struct config_int *conf = (struct config_int *) gconf;
1627  int newval = conf->boot_val;
1628  void *extra = NULL;
1629 
1630  Assert(newval >= conf->min);
1631  Assert(newval <= conf->max);
1632  if (!call_int_check_hook(conf, &newval, &extra,
1633  PGC_S_DEFAULT, LOG))
1634  elog(FATAL, "failed to initialize %s to %d",
1635  conf->gen.name, newval);
1636  if (conf->assign_hook)
1637  conf->assign_hook(newval, extra);
1638  *conf->variable = conf->reset_val = newval;
1639  conf->gen.extra = conf->reset_extra = extra;
1640  break;
1641  }
1642  case PGC_REAL:
1643  {
1644  struct config_real *conf = (struct config_real *) gconf;
1645  double newval = conf->boot_val;
1646  void *extra = NULL;
1647 
1648  Assert(newval >= conf->min);
1649  Assert(newval <= conf->max);
1650  if (!call_real_check_hook(conf, &newval, &extra,
1651  PGC_S_DEFAULT, LOG))
1652  elog(FATAL, "failed to initialize %s to %g",
1653  conf->gen.name, newval);
1654  if (conf->assign_hook)
1655  conf->assign_hook(newval, extra);
1656  *conf->variable = conf->reset_val = newval;
1657  conf->gen.extra = conf->reset_extra = extra;
1658  break;
1659  }
1660  case PGC_STRING:
1661  {
1662  struct config_string *conf = (struct config_string *) gconf;
1663  char *newval;
1664  void *extra = NULL;
1665 
1666  /* non-NULL boot_val must always get strdup'd */
1667  if (conf->boot_val != NULL)
1668  newval = guc_strdup(FATAL, conf->boot_val);
1669  else
1670  newval = NULL;
1671 
1672  if (!call_string_check_hook(conf, &newval, &extra,
1673  PGC_S_DEFAULT, LOG))
1674  elog(FATAL, "failed to initialize %s to \"%s\"",
1675  conf->gen.name, newval ? newval : "");
1676  if (conf->assign_hook)
1677  conf->assign_hook(newval, extra);
1678  *conf->variable = conf->reset_val = newval;
1679  conf->gen.extra = conf->reset_extra = extra;
1680  break;
1681  }
1682  case PGC_ENUM:
1683  {
1684  struct config_enum *conf = (struct config_enum *) gconf;
1685  int newval = conf->boot_val;
1686  void *extra = NULL;
1687 
1688  if (!call_enum_check_hook(conf, &newval, &extra,
1689  PGC_S_DEFAULT, LOG))
1690  elog(FATAL, "failed to initialize %s to %d",
1691  conf->gen.name, newval);
1692  if (conf->assign_hook)
1693  conf->assign_hook(newval, extra);
1694  *conf->variable = conf->reset_val = newval;
1695  conf->gen.extra = conf->reset_extra = extra;
1696  break;
1697  }
1698  }
1699 }
static bool call_string_check_hook(struct config_string *conf, char **newval, void **extra, GucSource source, int elevel)
Definition: guc.c:6677
static void static bool call_bool_check_hook(struct config_bool *conf, bool *newval, void **extra, GucSource source, int elevel)
Definition: guc.c:6575
static bool call_int_check_hook(struct config_int *conf, int *newval, void **extra, GucSource source, int elevel)
Definition: guc.c:6609
static bool call_real_check_hook(struct config_real *conf, double *newval, void **extra, GucSource source, int elevel)
Definition: guc.c:6643
static bool call_enum_check_hook(struct config_enum *conf, int *newval, void **extra, GucSource source, int elevel)
Definition: guc.c:6727
void * reset_extra
Definition: guc_tables.h:208
void * reset_extra
Definition: guc_tables.h:269
char * last_reported
Definition: guc_tables.h:178
void * reset_extra
Definition: guc_tables.h:224
void * reset_extra
Definition: guc_tables.h:240
void * reset_extra
Definition: guc_tables.h:254

References Assert(), config_bool::assign_hook, config_int::assign_hook, config_real::assign_hook, config_string::assign_hook, config_enum::assign_hook, config_bool::boot_val, config_int::boot_val, config_real::boot_val, config_string::boot_val, config_enum::boot_val, call_bool_check_hook(), call_enum_check_hook(), call_int_check_hook(), call_real_check_hook(), call_string_check_hook(), elog(), config_generic::extra, FATAL, config_bool::gen, config_int::gen, config_real::gen, config_string::gen, config_enum::gen, guc_strdup(), config_generic::last_reported, LOG, config_int::max, config_real::max, config_int::min, config_real::min, config_generic::name, newval, PGC_BOOL, PGC_ENUM, PGC_INT, PGC_INTERNAL, PGC_REAL, PGC_S_DEFAULT, PGC_STRING, config_bool::reset_extra, config_int::reset_extra, config_real::reset_extra, config_string::reset_extra, config_enum::reset_extra, config_generic::reset_scontext, config_generic::reset_source, config_generic::reset_srole, config_bool::reset_val, config_int::reset_val, config_real::reset_val, config_string::reset_val, config_enum::reset_val, config_generic::scontext, config_generic::source, config_generic::sourcefile, config_generic::sourceline, config_generic::srole, config_generic::stack, config_generic::status, config_bool::variable, config_int::variable, config_real::variable, config_string::variable, config_enum::variable, and config_generic::vartype.

Referenced by define_custom_variable(), InitializeGUCOptions(), and RestoreGUCState().

◆ MarkGUCPrefixReserved()

void MarkGUCPrefixReserved ( const char *  className)

Definition at line 5087 of file guc.c.

5088 {
5089  int classLen = strlen(className);
5091  GUCHashEntry *hentry;
5092  MemoryContext oldcontext;
5093 
5094  /*
5095  * Check for existing placeholders. We must actually remove invalid
5096  * placeholders, else future parallel worker startups will fail. (We
5097  * don't bother trying to free associated memory, since this shouldn't
5098  * happen often.)
5099  */
5101  while ((hentry = (GUCHashEntry *) hash_seq_search(&status)) != NULL)
5102  {
5103  struct config_generic *var = hentry->gucvar;
5104 
5105  if ((var->flags & GUC_CUSTOM_PLACEHOLDER) != 0 &&
5106  strncmp(className, var->name, classLen) == 0 &&
5107  var->name[classLen] == GUC_QUALIFIER_SEPARATOR)
5108  {
5109  ereport(WARNING,
5110  (errcode(ERRCODE_INVALID_NAME),
5111  errmsg("invalid configuration parameter name \"%s\", removing it",
5112  var->name),
5113  errdetail("\"%s\" is now a reserved prefix.",
5114  className)));
5115  /* Remove it from the hash table */
5117  &var->name,
5118  HASH_REMOVE,
5119  NULL);
5120  /* Remove it from any lists it's in, too */
5121  RemoveGUCFromLists(var);
5122  }
5123  }
5124 
5125  /* And remember the name so we can prevent future mistakes. */
5128  MemoryContextSwitchTo(oldcontext);
5129 }
@ HASH_REMOVE
Definition: hsearch.h:115
List * lappend(List *list, void *datum)
Definition: list.c:338
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:135

References ereport, errcode(), errdetail(), errmsg(), config_generic::flags, GUC_CUSTOM_PLACEHOLDER, guc_hashtab, GUC_QUALIFIER_SEPARATOR, GUCMemoryContext, GUCHashEntry::gucvar, HASH_REMOVE, hash_search(), hash_seq_init(), hash_seq_search(), lappend(), MemoryContextSwitchTo(), config_generic::name, pstrdup(), RemoveGUCFromLists(), reserved_class_prefix, status(), and WARNING.

Referenced by _PG_init().

◆ NewGUCNestLevel()

◆ parse_and_validate_value()

static bool parse_and_validate_value ( struct config_generic record,
const char *  name,
const char *  value,
GucSource  source,
int  elevel,
union config_var_val newval,
void **  newextra 
)
static

Definition at line 3065 of file guc.c.

3069 {
3070  switch (record->vartype)
3071  {
3072  case PGC_BOOL:
3073  {
3074  struct config_bool *conf = (struct config_bool *) record;
3075 
3076  if (!parse_bool(value, &newval->boolval))
3077  {
3078  ereport(elevel,
3079  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
3080  errmsg("parameter \"%s\" requires a Boolean value",
3081  name)));
3082  return false;
3083  }
3084 
3085  if (!call_bool_check_hook(conf, &newval->boolval, newextra,
3086  source, elevel))
3087  return false;
3088  }
3089  break;
3090  case PGC_INT:
3091  {
3092  struct config_int *conf = (struct config_int *) record;
3093  const char *hintmsg;
3094 
3095  if (!parse_int(value, &newval->intval,
3096  conf->gen.flags, &hintmsg))
3097  {
3098  ereport(elevel,
3099  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
3100  errmsg("invalid value for parameter \"%s\": \"%s\"",
3101  name, value),
3102  hintmsg ? errhint("%s", _(hintmsg)) : 0));
3103  return false;
3104  }
3105 
3106  if (newval->intval < conf->min || newval->intval > conf->max)
3107  {
3108  const char *unit = get_config_unit_name(conf->gen.flags);
3109 
3110  ereport(elevel,
3111  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
3112  errmsg("%d%s%s is outside the valid range for parameter \"%s\" (%d .. %d)",
3113  newval->intval,
3114  unit ? " " : "",
3115  unit ? unit : "",
3116  name,
3117  conf->min, conf->max)));
3118  return false;
3119  }
3120 
3121  if (!call_int_check_hook(conf, &newval->intval, newextra,
3122  source, elevel))
3123  return false;
3124  }
3125  break;
3126  case PGC_REAL:
3127  {
3128  struct config_real *conf = (struct config_real *) record;
3129  const char *hintmsg;
3130 
3131  if (!parse_real(value, &newval->realval,
3132  conf->gen.flags, &hintmsg))
3133  {
3134  ereport(elevel,
3135  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
3136  errmsg("invalid value for parameter \"%s\": \"%s\"",
3137  name, value),
3138  hintmsg ? errhint("%s", _(hintmsg)) : 0));
3139  return false;
3140  }
3141 
3142  if (newval->realval < conf->min || newval->realval > conf->max)
3143  {
3144  const char *unit = get_config_unit_name(conf->gen.flags);
3145 
3146  ereport(elevel,
3147  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
3148  errmsg("%g%s%s is outside the valid range for parameter \"%s\" (%g .. %g)",
3149  newval->realval,
3150  unit ? " " : "",
3151  unit ? unit : "",
3152  name,
3153  conf->min, conf->max)));
3154  return false;
3155  }
3156 
3157  if (!call_real_check_hook(conf, &newval->realval, newextra,
3158  source, elevel))
3159  return false;
3160  }
3161  break;
3162  case PGC_STRING:
3163  {
3164  struct config_string *conf = (struct config_string *) record;
3165 
3166  /*
3167  * The value passed by the caller could be transient, so we
3168  * always strdup it.
3169  */
3170  newval->stringval = guc_strdup(elevel, value);
3171  if (newval->stringval == NULL)
3172  return false;
3173 
3174  /*
3175  * The only built-in "parsing" check we have is to apply
3176  * truncation if GUC_IS_NAME.
3177  */
3178  if (conf->gen.flags & GUC_IS_NAME)
3179  truncate_identifier(newval->stringval,
3180  strlen(newval->stringval),
3181  true);
3182 
3183  if (!call_string_check_hook(conf, &newval->stringval, newextra,
3184  source, elevel))
3185  {
3186  guc_free(newval->stringval);
3187  newval->stringval = NULL;
3188  return false;
3189  }
3190  }
3191  break;
3192  case PGC_ENUM:
3193  {
3194  struct config_enum *conf = (struct config_enum *) record;
3195 
3196  if (!config_enum_lookup_by_name(conf, value, &newval->enumval))
3197  {
3198  char *hintmsg;
3199 
3200  hintmsg = config_enum_get_options(conf,
3201  "Available values: ",
3202  ".", ", ");
3203 
3204  ereport(elevel,
3205  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
3206  errmsg("invalid value for parameter \"%s\": \"%s\"",
3207  name, value),
3208  hintmsg ? errhint("%s", _(hintmsg)) : 0));
3209 
3210  if (hintmsg)
3211  pfree(hintmsg);
3212  return false;
3213  }
3214 
3215  if (!call_enum_check_hook(conf, &newval->enumval, newextra,
3216  source, elevel))
3217  return false;
3218  }
3219  break;
3220  }
3221 
3222  return true;
3223 }
bool parse_bool(const char *value, bool *result)
Definition: bool.c:30
#define _(x)
Definition: elog.c:90
bool parse_int(const char *value, int *result, int flags, const char **hintmsg)
Definition: guc.c:2806
bool config_enum_lookup_by_name(struct config_enum *record, const char *value, int *retval)
Definition: guc.c:2981
bool parse_real(const char *value, double *result, int flags, const char **hintmsg)
Definition: guc.c:2896
const char * get_config_unit_name(int flags)
Definition: guc.c:2749
char * config_enum_get_options(struct config_enum *record, const char *prefix, const char *suffix, const char *separator)
Definition: guc.c:3007
#define GUC_IS_NAME
Definition: guc.h:219
void truncate_identifier(char *ident, int len, bool warn)
Definition: scansup.c:93

References _, call_bool_check_hook(), call_enum_check_hook(), call_int_check_hook(), call_real_check_hook(), call_string_check_hook(), config_enum_get_options(), config_enum_lookup_by_name(), ereport, errcode(), errhint(), errmsg(), config_generic::flags, config_int::gen, config_real::gen, config_string::gen, get_config_unit_name(), guc_free(), GUC_IS_NAME, guc_strdup(), config_int::max, config_real::max, config_int::min, config_real::min, name, newval, parse_bool(), parse_int(), parse_real(), pfree(), PGC_BOOL, PGC_ENUM, PGC_INT, PGC_REAL, PGC_STRING, source, truncate_identifier(), value, and config_generic::vartype.

Referenced by AlterSystemSetConfigFile(), and set_config_option_ext().

◆ parse_int()

bool parse_int ( const char *  value,
int *  result,
int  flags,
const char **  hintmsg 
)

Definition at line 2806 of file guc.c.

2807 {
2808  /*
2809  * We assume here that double is wide enough to represent any integer
2810  * value with adequate precision.
2811  */
2812  double val;
2813  char *endptr;
2814 
2815  /* To suppress compiler warnings, always set output params */
2816  if (result)
2817  *result = 0;
2818  if (hintmsg)
2819  *hintmsg = NULL;
2820 
2821  /*
2822  * Try to parse as an integer (allowing octal or hex input). If the
2823  * conversion stops at a decimal point or 'e', or overflows, re-parse as
2824  * float. This should work fine as long as we have no unit names starting
2825  * with 'e'. If we ever do, the test could be extended to check for a
2826  * sign or digit after 'e', but for now that's unnecessary.
2827  */
2828  errno = 0;
2829  val = strtol(value, &endptr, 0);
2830  if (*endptr == '.' || *endptr == 'e' || *endptr == 'E' ||
2831  errno == ERANGE)
2832  {
2833  errno = 0;
2834  val = strtod(value, &endptr);
2835  }
2836 
2837  if (endptr == value || errno == ERANGE)
2838  return false; /* no HINT for these cases */
2839 
2840  /* reject NaN (infinities will fail range check below) */
2841  if (isnan(val))
2842  return false; /* treat same as syntax error; no HINT */
2843 
2844  /* allow whitespace between number and unit */
2845  while (isspace((unsigned char) *endptr))
2846  endptr++;
2847 
2848  /* Handle possible unit */
2849  if (*endptr != '\0')
2850  {
2851  if ((flags & GUC_UNIT) == 0)
2852  return false; /* this setting does not accept a unit */
2853 
2855  endptr, (flags & GUC_UNIT),
2856  &val))
2857  {
2858  /* invalid unit, or garbage after the unit; set hint and fail. */
2859  if (hintmsg)
2860  {
2861  if (flags & GUC_UNIT_MEMORY)
2862  *hintmsg = memory_units_hint;
2863  else
2864  *hintmsg = time_units_hint;
2865  }
2866  return false;
2867  }
2868  }
2869 
2870  /* Round to int, then check for overflow */
2871  val = rint(val);
2872 
2873  if (val > INT_MAX || val < INT_MIN)
2874  {
2875  if (hintmsg)
2876  *hintmsg = gettext_noop("Value exceeds integer range.");
2877  return false;
2878  }
2879 
2880  if (result)
2881  *result = (int) val;
2882  return true;
2883 }
#define gettext_noop(x)
Definition: c.h:1135
static const char * memory_units_hint
Definition: guc.c:115
static bool convert_to_base_unit(double value, const char *unit, int base_unit, double *base_value)
Definition: guc.c:2606
static const char * time_units_hint
Definition: guc.c:152
#define GUC_UNIT
Definition: guc.h:237

References convert_to_base_unit(), config_generic::flags, gettext_noop, GUC_UNIT, GUC_UNIT_MEMORY, memory_units_hint, time_units_hint, val, and value.

Referenced by apply_server_options(), apply_table_options(), get_batch_size_option(), parse_and_validate_value(), parse_one_reloption(), postgres_fdw_validator(), and postgresAcquireSampleRowsFunc().

◆ parse_real()

bool parse_real ( const char *  value,
double *  result,
int  flags,
const char **  hintmsg 
)

Definition at line 2896 of file guc.c.

2897 {
2898  double val;
2899  char *endptr;
2900 
2901  /* To suppress compiler warnings, always set output params */
2902  if (result)
2903  *result = 0;
2904  if (hintmsg)
2905  *hintmsg = NULL;
2906 
2907  errno = 0;
2908  val = strtod(value, &endptr);
2909 
2910  if (endptr == value || errno == ERANGE)
2911  return false; /* no HINT for these cases */
2912 
2913  /* reject NaN (infinities will fail range checks later) */
2914  if (isnan(val))
2915  return false; /* treat same as syntax error; no HINT */
2916 
2917  /* allow whitespace between number and unit */
2918  while (isspace((unsigned char) *endptr))
2919  endptr++;
2920 
2921  /* Handle possible unit */
2922  if (*endptr != '\0')
2923  {
2924  if ((flags & GUC_UNIT) == 0)
2925  return false; /* this setting does not accept a unit */
2926 
2928  endptr, (flags & GUC_UNIT),
2929  &val))
2930  {
2931  /* invalid unit, or garbage after the unit; set hint and fail. */
2932  if (hintmsg)
2933  {
2934  if (flags & GUC_UNIT_MEMORY)
2935  *hintmsg = memory_units_hint;
2936  else
2937  *hintmsg = time_units_hint;
2938  }
2939  return false;
2940  }
2941  }
2942 
2943  if (result)
2944  *result = val;
2945  return true;
2946 }

References convert_to_base_unit(), config_generic::flags, GUC_UNIT, GUC_UNIT_MEMORY, memory_units_hint, time_units_hint, val, and value.

Referenced by apply_server_options(), parse_and_validate_value(), parse_one_reloption(), and postgres_fdw_validator().

◆ ParseLongOption()

void ParseLongOption ( const char *  string,
char **  name,
char **  value 
)

Definition at line 6170 of file guc.c.

6171 {
6172  size_t equal_pos;
6173  char *cp;
6174 
6175  Assert(string);
6176  Assert(name);
6177  Assert(value);
6178 
6179  equal_pos = strcspn(string, "=");
6180 
6181  if (string[equal_pos] == '=')
6182  {
6183  *name = palloc(equal_pos + 1);
6184  strlcpy(*name, string, equal_pos + 1);
6185 
6186  *value = pstrdup(&string[equal_pos + 1]);
6187  }
6188  else
6189  {
6190  /* no equal sign in string */
6191  *name = pstrdup(string);
6192  *value = NULL;
6193  }
6194 
6195  for (cp = *name; *cp; cp++)
6196  if (*cp == '-')
6197  *cp = '_';
6198 }
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45

References Assert(), name, palloc(), pstrdup(), strlcpy(), and value.

Referenced by BootstrapModeMain(), PostmasterMain(), process_postgres_switches(), and ProcessGUCArray().

◆ pg_timezone_abbrev_initialize()

static void pg_timezone_abbrev_initialize ( void  )
static

Definition at line 1940 of file guc.c.

1941 {
1942  SetConfigOption("timezone_abbreviations", "Default",
1944 }

References PGC_POSTMASTER, PGC_S_DYNAMIC_DEFAULT, and SetConfigOption().

Referenced by ProcessConfigFileInternal(), and SelectConfigFiles().

◆ ProcessConfigFileInternal()

ConfigVariable* ProcessConfigFileInternal ( GucContext  context,
bool  applySettings,
int  elevel 
)

Definition at line 275 of file guc.c.

276 {
277  bool error = false;
278  bool applying = false;
279  const char *ConfFileWithError;
280  ConfigVariable *item,
281  *head,
282  *tail;
284  GUCHashEntry *hentry;
285 
286  /* Parse the main config file into a list of option names and values */
287  ConfFileWithError = ConfigFileName;
288  head = tail = NULL;
289 
290  if (!ParseConfigFile(ConfigFileName, true,
291  NULL, 0, CONF_FILE_START_DEPTH, elevel,
292  &head, &tail))
293  {
294  /* Syntax error(s) detected in the file, so bail out */
295  error = true;
296  goto bail_out;
297  }
298 
299  /*
300  * Parse the PG_AUTOCONF_FILENAME file, if present, after the main file to
301  * replace any parameters set by ALTER SYSTEM command. Because this file
302  * is in the data directory, we can't read it until the DataDir has been
303  * set.
304  */
305  if (DataDir)
306  {
308  NULL, 0, CONF_FILE_START_DEPTH, elevel,
309  &head, &tail))
310  {
311  /* Syntax error(s) detected in the file, so bail out */
312  error = true;
313  ConfFileWithError = PG_AUTOCONF_FILENAME;
314  goto bail_out;
315  }
316  }
317  else
318  {
319  /*
320  * If DataDir is not set, the PG_AUTOCONF_FILENAME file cannot be
321  * read. In this case, we don't want to accept any settings but
322  * data_directory from postgresql.conf, because they might be
323  * overwritten with settings in the PG_AUTOCONF_FILENAME file which
324  * will be read later. OTOH, since data_directory isn't allowed in the
325  * PG_AUTOCONF_FILENAME file, it will never be overwritten later.
326  */
327  ConfigVariable *newlist = NULL;
328 
329  /*
330  * Prune all items except the last "data_directory" from the list.
331  */
332  for (item = head; item; item = item->next)
333  {
334  if (!item->ignore &&
335  strcmp(item->name, "data_directory") == 0)
336  newlist = item;
337  }
338 
339  if (newlist)
340  newlist->next = NULL;
341  head = tail = newlist;
342 
343  /*
344  * Quick exit if data_directory is not present in file.
345  *
346  * We need not do any further processing, in particular we don't set
347  * PgReloadTime; that will be set soon by subsequent full loading of
348  * the config file.
349  */
350  if (head == NULL)
351  goto bail_out;
352  }
353 
354  /*
355  * Mark all extant GUC variables as not present in the config file. We
356  * need this so that we can tell below which ones have been removed from
357  * the file since we last processed it.
358  */
360  while ((hentry = (GUCHashEntry *) hash_seq_search(&status)) != NULL)
361  {
362  struct config_generic *gconf = hentry->gucvar;
363 
364  gconf->status &= ~GUC_IS_IN_FILE;
365  }
366 
367  /*
368  * Check if all the supplied option names are valid, as an additional
369  * quasi-syntactic check on the validity of the config file. It is
370  * important that the postmaster and all backends agree on the results of
371  * this phase, else we will have strange inconsistencies about which
372  * processes accept a config file update and which don't. Hence, unknown
373  * custom variable names have to be accepted without complaint. For the
374  * same reason, we don't attempt to validate the options' values here.
375  *
376  * In addition, the GUC_IS_IN_FILE flag is set on each existing GUC
377  * variable mentioned in the file; and we detect duplicate entries in the
378  * file and mark the earlier occurrences as ignorable.
379  */
380  for (item = head; item; item = item->next)
381  {
382  struct config_generic *record;
383 
384  /* Ignore anything already marked as ignorable */
385  if (item->ignore)
386  continue;
387 
388  /*
389  * Try to find the variable; but do not create a custom placeholder if
390  * it's not there already.
391  */
392  record = find_option(item->name, false, true, elevel);
393 
394  if (record)
395  {
396  /* If it's already marked, then this is a duplicate entry */
397  if (record->status & GUC_IS_IN_FILE)
398  {
399  /*
400  * Mark the earlier occurrence(s) as dead/ignorable. We could
401  * avoid the O(N^2) behavior here with some additional state,
402  * but it seems unlikely to be worth the trouble.
403  */
404  ConfigVariable *pitem;
405 
406  for (pitem = head; pitem != item; pitem = pitem->next)
407  {
408  if (!pitem->ignore &&
409  strcmp(pitem->name, item->name) == 0)
410  pitem->ignore = true;
411  }
412  }
413  /* Now mark it as present in file */
414  record->status |= GUC_IS_IN_FILE;
415  }
416  else if (!valid_custom_variable_name(item->name))
417  {
418  /* Invalid non-custom variable, so complain */
419  ereport(elevel,
420  (errcode(ERRCODE_UNDEFINED_OBJECT),
421  errmsg("unrecognized configuration parameter \"%s\" in file \"%s\" line %d",
422  item->name,
423  item->filename, item->sourceline)));
424  item->errmsg = pstrdup("unrecognized configuration parameter");
425  error = true;
426  ConfFileWithError = item->filename;
427  }
428  }
429 
430  /*
431  * If we've detected any errors so far, we don't want to risk applying any
432  * changes.
433  */
434  if (error)
435  goto bail_out;
436 
437  /* Otherwise, set flag that we're beginning to apply changes */
438  applying = true;
439 
440  /*
441  * Check for variables having been removed from the config file, and
442  * revert their reset values (and perhaps also effective values) to the
443  * boot-time defaults. If such a variable can't be changed after startup,
444  * report that and continue.
445  */
447  while ((hentry = (GUCHashEntry *) hash_seq_search(&status)) != NULL)
448  {
449  struct config_generic *gconf = hentry->gucvar;
450  GucStack *stack;
451 
452  if (gconf->reset_source != PGC_S_FILE ||
453  (gconf->status & GUC_IS_IN_FILE))
454  continue;
455  if (gconf->context < PGC_SIGHUP)
456  {
457  /* The removal can't be effective without a restart */
458  gconf->status |= GUC_PENDING_RESTART;
459  ereport(elevel,
460  (errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
461  errmsg("parameter \"%s\" cannot be changed without restarting the server",
462  gconf->name)));
463  record_config_file_error(psprintf("parameter \"%s\" cannot be changed without restarting the server",
464  gconf->name),
465  NULL, 0,
466  &head, &tail);
467  error = true;
468  continue;
469  }
470 
471  /* No more to do if we're just doing show_all_file_settings() */
472  if (!applySettings)
473  continue;
474 
475  /*
476  * Reset any "file" sources to "default", else set_config_option will
477  * not override those settings.
478  */
479  if (gconf->reset_source == PGC_S_FILE)
480  gconf->reset_source = PGC_S_DEFAULT;
481  if (gconf->source == PGC_S_FILE)
483  for (stack = gconf->stack; stack; stack = stack->prev)
484  {
485  if (stack->source == PGC_S_FILE)
487  }
488 
489  /* Now we can re-apply the wired-in default (i.e., the boot_val) */
490  if (set_config_option(gconf->name, NULL,
492  GUC_ACTION_SET, true, 0, false) > 0)
493  {
494  /* Log the change if appropriate */
495  if (context == PGC_SIGHUP)
496  ereport(elevel,
497  (errmsg("parameter \"%s\" removed from configuration file, reset to default",
498  gconf->name)));
499  }
500  }
501 
502  /*
503  * Restore any variables determined by environment variables or
504  * dynamically-computed defaults. This is a no-op except in the case
505  * where one of these had been in the config file and is now removed.
506  *
507  * In particular, we *must not* do this during the postmaster's initial
508  * loading of the file, since the timezone functions in particular should
509  * be run only after initialization is complete.
510  *
511  * XXX this is an unmaintainable crock, because we have to know how to set
512  * (or at least what to call to set) every non-PGC_INTERNAL variable that
513  * could potentially have PGC_S_DYNAMIC_DEFAULT or PGC_S_ENV_VAR source.
514  */
515  if (context == PGC_SIGHUP && applySettings)
516  {
519  /* this selects SQL_ASCII in processes not connected to a database */
520  SetConfigOption("client_encoding", GetDatabaseEncodingName(),
522  }
523 
524  /*
525  * Now apply the values from the config file.
526  */
527  for (item = head; item; item = item->next)
528  {
529  char *pre_value = NULL;
530  int scres;
531 
532  /* Ignore anything marked as ignorable */
533  if (item->ignore)
534  continue;
535 
536  /* In SIGHUP cases in the postmaster, we want to report changes */
537  if (context == PGC_SIGHUP && applySettings && !IsUnderPostmaster)
538  {
539  const char *preval = GetConfigOption(item->name, true, false);
540 
541  /* If option doesn't exist yet or is NULL, treat as empty string */
542  if (!preval)
543  preval = "";
544  /* must dup, else might have dangling pointer below */
545  pre_value = pstrdup(preval);
546  }
547 
548  scres = set_config_option(item->name, item->value,
550  GUC_ACTION_SET, applySettings, 0, false);
551  if (scres > 0)
552  {
553  /* variable was updated, so log the change if appropriate */
554  if (pre_value)
555  {
556  const char *post_value = GetConfigOption(item->name, true, false);
557 
558  if (!post_value)
559  post_value = "";
560  if (strcmp(pre_value, post_value) != 0)
561  ereport(elevel,
562  (errmsg("parameter \"%s\" changed to \"%s\"",
563  item->name, item->value)));
564  }
565  item->applied = true;
566  }
567  else if (scres == 0)
568  {
569  error = true;
570  item->errmsg = pstrdup("setting could not be applied");
571  ConfFileWithError = item->filename;
572  }
573  else
574  {
575  /* no error, but variable's active value was not changed */
576  item->applied = true;
577  }
578 
579  /*
580  * We should update source location unless there was an error, since
581  * even if the active value didn't change, the reset value might have.
582  * (In the postmaster, there won't be a difference, but it does matter
583  * in backends.)
584  */
585  if (scres != 0 && applySettings)
586  set_config_sourcefile(item->name, item->filename,
587  item->sourceline);
588 
589  if (pre_value)
590  pfree(pre_value);
591  }
592 
593  /* Remember when we last successfully loaded the config file. */
594  if (applySettings)
596 
597 bail_out:
598  if (error && applySettings)
599  {
600  /* During postmaster startup, any error is fatal */
601  if (context == PGC_POSTMASTER)
602  ereport(ERROR,
603  (errcode(ERRCODE_CONFIG_FILE_ERROR),
604  errmsg("configuration file \"%s\" contains errors",
605  ConfFileWithError)));
606  else if (applying)
607  ereport(elevel,
608  (errcode(ERRCODE_CONFIG_FILE_ERROR),
609  errmsg("configuration file \"%s\" contains errors; unaffected changes were applied",
610  ConfFileWithError)));
611  else
612  ereport(elevel,
613  (errcode(ERRCODE_CONFIG_FILE_ERROR),
614  errmsg("configuration file \"%s\" contains errors; no changes were applied",
615  ConfFileWithError)));
616  }
617 
618  /* Successful or otherwise, return the collected data list */
619  return head;
620 }
TimestampTz PgReloadTime
Definition: timestamp.c:56
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1573
bool IsUnderPostmaster
Definition: globals.c:113
char * DataDir
Definition: globals.c:66
static void pg_timezone_abbrev_initialize(void)
Definition: guc.c:1940
const char * GetConfigOption(const char *name, bool missing_ok, bool restrict_privileged)
Definition: guc.c:4182
int set_config_option(const char *name, const char *value, GucContext context, GucSource source, GucAction action, bool changeVal, int elevel, bool is_reload)
Definition: guc.c:3266
bool ParseConfigFile(const char *config_file, bool strict, const char *calling_file, int calling_lineno, int depth, int elevel, ConfigVariable **head_p, ConfigVariable **tail_p)
@ PGC_SIGHUP
Definition: guc.h:71
@ PGC_BACKEND
Definition: guc.h:73
void record_config_file_error(const char *errmsg, const char *config_file, int lineno, ConfigVariable **head_p, ConfigVariable **tail_p)
char * ConfigFileName
Definition: guc_tables.c:503
#define GUC_IS_IN_FILE
Definition: guc_tables.h:186
#define GUC_PENDING_RESTART
Definition: guc_tables.h:191
const char * GetDatabaseEncodingName(void)
Definition: mbutils.c:1216
static void error(void)
Definition: sql-dyntest.c:147
char * name
Definition: guc.h:137
bool ignore
Definition: guc.h:142
struct ConfigVariable * next
Definition: guc.h:144
bool applied
Definition: guc.h:143
char * filename
Definition: guc.h:140
int sourceline
Definition: guc.h:141
char * value
Definition: guc.h:138
char * errmsg
Definition: guc.h:139

References ConfigVariable::applied, CONF_FILE_START_DEPTH, ConfigFileName, config_generic::context, DataDir, ereport, errcode(), errmsg(), ConfigVariable::errmsg, ERROR, error(), ConfigVariable::filename, find_option(), GetConfigOption(), GetCurrentTimestamp(), GetDatabaseEncodingName(), GUC_ACTION_SET, guc_hashtab, GUC_IS_IN_FILE, GUC_PENDING_RESTART, GUCHashEntry::gucvar, hash_seq_init(), hash_seq_search(), ConfigVariable::ignore, InitializeGUCOptionsFromEnvironment(), IsUnderPostmaster, ConfigVariable::name, config_generic::name, ConfigVariable::next, ParseConfigFile(), pfree(), PG_AUTOCONF_FILENAME, pg_timezone_abbrev_initialize(), PGC_BACKEND, PGC_POSTMASTER, PGC_S_DEFAULT, PGC_S_DYNAMIC_DEFAULT, PGC_S_FILE, PGC_SIGHUP, PgReloadTime, guc_stack::prev, psprintf(), pstrdup(), record_config_file_error(), config_generic::reset_source, set_config_option(), set_config_sourcefile(), set_guc_source(), SetConfigOption(), guc_stack::source, config_generic::source, ConfigVariable::sourceline, config_generic::stack, config_generic::status, status(), valid_custom_variable_name(), and ConfigVariable::value.

Referenced by show_all_file_settings().

◆ ProcessGUCArray()

void ProcessGUCArray ( ArrayType array,
GucContext  context,
GucSource  source,
GucAction  action 
)

Definition at line 6208 of file guc.c.

6210 {
6211  int i;
6212 
6213  Assert(array != NULL);
6214  Assert(ARR_ELEMTYPE(array) == TEXTOID);
6215  Assert(ARR_NDIM(array) == 1);
6216  Assert(ARR_LBOUND(array)[0] == 1);
6217 
6218  for (i = 1; i <= ARR_DIMS(array)[0]; i++)
6219  {
6220  Datum d;
6221  bool isnull;
6222  char *s;
6223  char *name;
6224  char *value;
6225 
6226  d = array_ref(array, 1, &i,
6227  -1 /* varlenarray */ ,
6228  -1 /* TEXT's typlen */ ,
6229  false /* TEXT's typbyval */ ,
6230  TYPALIGN_INT /* TEXT's typalign */ ,
6231  &isnull);
6232 
6233  if (isnull)
6234  continue;
6235 
6236  s = TextDatumGetCString(d);
6237 
6238  ParseLongOption(s, &name, &value);
6239  if (!value)
6240  {
6241  ereport(WARNING,
6242  (errcode(ERRCODE_SYNTAX_ERROR),
6243  errmsg("could not parse setting for parameter \"%s\"",
6244  name)));
6245  pfree(name);
6246  continue;
6247  }
6248 
6249  (void) set_config_option(name, value,
6250  context, source,
6251  action, true, 0, false);
6252 
6253  pfree(name);
6254  pfree(value);
6255  pfree(s);
6256  }
6257 }
void ParseLongOption(const char *string, char **name, char **value)
Definition: guc.c:6170

References generate_unaccent_rules::action, ARR_DIMS, ARR_ELEMTYPE, ARR_LBOUND, ARR_NDIM, array_ref(), Assert(), ereport, errcode(), errmsg(), i, name, ParseLongOption(), pfree(), set_config_option(), source, TextDatumGetCString, value, and WARNING.

Referenced by ApplySetting(), fmgr_security_definer(), and ProcedureCreate().

◆ push_old_value()

static void push_old_value ( struct config_generic gconf,
GucAction  action 
)
static

Definition at line 2082 of file guc.c.

2083 {
2084  GucStack *stack;
2085 
2086  /* If we're not inside a nest level, do nothing */
2087  if (GUCNestLevel == 0)
2088  return;
2089 
2090  /* Do we already have a stack entry of the current nest level? */
2091  stack = gconf->stack;
2092  if (stack && stack->nest_level >= GUCNestLevel)
2093  {
2094  /* Yes, so adjust its state if necessary */
2095  Assert(stack->nest_level == GUCNestLevel);
2096  switch (action)
2097  {
2098  case GUC_ACTION_SET:
2099  /* SET overrides any prior action at same nest level */
2100  if (stack->state == GUC_SET_LOCAL)
2101  {
2102  /* must discard old masked value */
2103  discard_stack_value(gconf, &stack->masked);
2104  }
2105  stack->state = GUC_SET;
2106  break;
2107  case GUC_ACTION_LOCAL:
2108  if (stack->state == GUC_SET)
2109  {
2110  /* SET followed by SET LOCAL, remember SET's value */
2111  stack->masked_scontext = gconf->scontext;
2112  stack->masked_srole = gconf->srole;
2113  set_stack_value(gconf, &stack->masked);
2114  stack->state = GUC_SET_LOCAL;
2115  }
2116  /* in all other cases, no change to stack entry */
2117  break;
2118  case GUC_ACTION_SAVE:
2119  /* Could only have a prior SAVE of same variable */
2120  Assert(stack->state == GUC_SAVE);
2121  break;
2122  }
2123  return;
2124  }
2125 
2126  /*
2127  * Push a new stack entry
2128  *
2129  * We keep all the stack entries in TopTransactionContext for simplicity.
2130  */
2132  sizeof(GucStack));
2133 
2134  stack->prev = gconf->stack;
2135  stack->nest_level = GUCNestLevel;
2136  switch (action)
2137  {
2138  case GUC_ACTION_SET:
2139  stack->state = GUC_SET;
2140  break;
2141  case GUC_ACTION_LOCAL:
2142  stack->state = GUC_LOCAL;
2143  break;
2144  case GUC_ACTION_SAVE:
2145  stack->state = GUC_SAVE;
2146  break;
2147  }
2148  stack->source = gconf->source;
2149  stack->scontext = gconf->scontext;
2150  stack->srole = gconf->srole;
2151  set_stack_value(gconf, &stack->prior);
2152 
2153  if (gconf->stack == NULL)
2155  gconf->stack = stack;
2156 }
static void set_stack_value(struct config_generic *gconf, config_var_value *val)
Definition: guc.c:805
@ GUC_ACTION_SAVE
Definition: guc.h:199
@ GUC_ACTION_LOCAL
Definition: guc.h:198
MemoryContext TopTransactionContext
Definition: mcxt.c:135