From 0a20ff54f5e66158930d5328f89f087d4e9ab400 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Tue, 13 Sep 2022 11:05:07 -0400 Subject: [PATCH] Split up guc.c for better build speed and ease of maintenance. guc.c has grown to be one of our largest .c files, making it a bottleneck for compilation. It's also acquired a bunch of knowledge that'd be better kept elsewhere, because of our not very good habit of putting variable-specific check hooks here. Hence, split it up along these lines: * guc.c itself retains just the core GUC housekeeping mechanisms. * New file guc_funcs.c contains the SET/SHOW interfaces and some SQL-accessible functions for GUC manipulation. * New file guc_tables.c contains the data arrays that define the built-in GUC variables, along with some already-exported constant tables. * GUC check/assign/show hook functions are moved to the variable's home module, whenever that's clearly identifiable. A few hard- to-classify hooks ended up in commands/variable.c, which was already a home for miscellaneous GUC hook functions. To avoid cluttering a lot more header files with #include "guc.h", I also invented a new header file utils/guc_hooks.h and put all the GUC hook functions' declarations there, regardless of their originating module. That allowed removal of #include "guc.h" from some existing headers. The fallout from that (hopefully all caught here) demonstrates clearly why such inclusions are best minimized: there are a lot of files that, for example, were getting array.h at two or more levels of remove, despite not having any connection at all to GUCs in themselves. There is some very minor code beautification here, such as renaming a couple of inconsistently-named hook functions and improving some comments. But mostly this just moves code from point A to point B and deals with the ensuing needs for #include adjustments and exporting a few functions that previously weren't exported. Patch by me, per a suggestion from Andres Freund; thanks also to Michael Paquier for the idea to invent guc_funcs.c. Discussion: https://postgr.es/m/587607.1662836699@sss.pgh.pa.us --- contrib/amcheck/verify_nbtree.c | 1 + contrib/ltree/_ltree_gist.c | 1 + contrib/ltree/_ltree_op.c | 1 + contrib/ltree/lquery_op.c | 1 + contrib/ltree/ltree_gist.c | 1 + contrib/pg_surgery/heap_surgery.c | 1 + contrib/pg_trgm/trgm_op.c | 1 + src/backend/access/brin/brin.c | 1 + src/backend/access/table/tableamapi.c | 1 + src/backend/access/transam/xlog.c | 176 +- src/backend/access/transam/xlogprefetcher.c | 2 +- src/backend/access/transam/xlogrecovery.c | 317 +- src/backend/backup/basebackup.c | 1 + src/backend/catalog/aclchk.c | 1 + src/backend/catalog/namespace.c | 2 +- src/backend/catalog/pg_parameter_acl.c | 1 + src/backend/commands/cluster.c | 1 + src/backend/commands/indexcmds.c | 1 + src/backend/commands/tablespace.c | 2 +- src/backend/commands/trigger.c | 16 + src/backend/commands/variable.c | 271 +- src/backend/libpq/pqcomm.c | 104 +- src/backend/partitioning/partbounds.c | 1 + src/backend/port/sysv_shmem.c | 19 +- src/backend/port/win32_shmem.c | 16 + src/backend/postmaster/autovacuum.c | 27 + src/backend/replication/repl_gram.y | 1 + src/backend/replication/repl_scanner.l | 1 + src/backend/replication/syncrep.c | 1 + src/backend/replication/syncrep_gram.y | 1 + src/backend/replication/syncrep_scanner.l | 1 + src/backend/storage/buffer/localbuf.c | 20 +- src/backend/storage/ipc/ipci.c | 1 + src/backend/storage/lmgr/predicate.c | 4 +- src/backend/tcop/postgres.c | 53 + src/backend/tsearch/dict.c | 1 + src/backend/utils/adt/pg_locale.c | 1 + src/backend/utils/adt/selfuncs.c | 1 + src/backend/utils/adt/varchar.c | 1 + src/backend/utils/adt/varlena.c | 1 + src/backend/utils/cache/ts_cache.c | 5 +- src/backend/utils/error/elog.c | 189 +- src/backend/utils/init/postinit.c | 50 +- src/backend/utils/misc/Makefile | 2 + src/backend/utils/misc/guc.c | 7066 +------------------ src/backend/utils/misc/guc_funcs.c | 1047 +++ src/backend/utils/misc/guc_tables.c | 4875 +++++++++++++ src/include/access/tableam.h | 4 +- src/include/access/xlog.h | 4 +- src/include/commands/variable.h | 38 - src/include/replication/syncrep.h | 6 - src/include/tcop/tcopprot.h | 3 - src/include/tsearch/ts_cache.h | 4 +- src/include/utils/elog.h | 4 - src/include/utils/guc.h | 50 +- src/include/utils/guc_hooks.h | 158 + src/include/utils/guc_tables.h | 22 +- src/include/utils/pg_locale.h | 11 - src/test/regress/regress.c | 1 + 59 files changed, 7466 insertions(+), 7128 deletions(-) create mode 100644 src/backend/utils/misc/guc_funcs.c create mode 100644 src/backend/utils/misc/guc_tables.c delete mode 100644 src/include/commands/variable.h create mode 100644 src/include/utils/guc_hooks.h diff --git a/contrib/amcheck/verify_nbtree.c b/contrib/amcheck/verify_nbtree.c index 2beeebb163..798adc5bc5 100644 --- a/contrib/amcheck/verify_nbtree.c +++ b/contrib/amcheck/verify_nbtree.c @@ -37,6 +37,7 @@ #include "miscadmin.h" #include "storage/lmgr.h" #include "storage/smgr.h" +#include "utils/guc.h" #include "utils/memutils.h" #include "utils/snapmgr.h" diff --git a/contrib/ltree/_ltree_gist.c b/contrib/ltree/_ltree_gist.c index 2dc59f8a0f..88d4623621 100644 --- a/contrib/ltree/_ltree_gist.c +++ b/contrib/ltree/_ltree_gist.c @@ -13,6 +13,7 @@ #include "crc32.h" #include "ltree.h" #include "port/pg_bitutils.h" +#include "utils/array.h" PG_FUNCTION_INFO_V1(_ltree_compress); PG_FUNCTION_INFO_V1(_ltree_same); diff --git a/contrib/ltree/_ltree_op.c b/contrib/ltree/_ltree_op.c index 9bb6bcaeff..2fdb5ea97b 100644 --- a/contrib/ltree/_ltree_op.c +++ b/contrib/ltree/_ltree_op.c @@ -10,6 +10,7 @@ #include #include "ltree.h" +#include "utils/array.h" PG_FUNCTION_INFO_V1(_ltree_isparent); PG_FUNCTION_INFO_V1(_ltree_r_isparent); diff --git a/contrib/ltree/lquery_op.c b/contrib/ltree/lquery_op.c index ef86046fc4..d580339283 100644 --- a/contrib/ltree/lquery_op.c +++ b/contrib/ltree/lquery_op.c @@ -10,6 +10,7 @@ #include "catalog/pg_collation.h" #include "ltree.h" #include "miscadmin.h" +#include "utils/array.h" #include "utils/formatting.h" PG_FUNCTION_INFO_V1(ltq_regex); diff --git a/contrib/ltree/ltree_gist.c b/contrib/ltree/ltree_gist.c index 36874e9c72..b582867a93 100644 --- a/contrib/ltree/ltree_gist.c +++ b/contrib/ltree/ltree_gist.c @@ -10,6 +10,7 @@ #include "access/stratnum.h" #include "crc32.h" #include "ltree.h" +#include "utils/array.h" #define NEXTVAL(x) ( (lquery*)( (char*)(x) + INTALIGN( VARSIZE(x) ) ) ) #define ISEQ(a,b) ( (a)->numlevel == (b)->numlevel && ltree_compare(a,b)==0 ) diff --git a/contrib/pg_surgery/heap_surgery.c b/contrib/pg_surgery/heap_surgery.c index 3e641aa644..8a2ad9773d 100644 --- a/contrib/pg_surgery/heap_surgery.c +++ b/contrib/pg_surgery/heap_surgery.c @@ -20,6 +20,7 @@ #include "miscadmin.h" #include "storage/bufmgr.h" #include "utils/acl.h" +#include "utils/array.h" #include "utils/rel.h" PG_MODULE_MAGIC; diff --git a/contrib/pg_trgm/trgm_op.c b/contrib/pg_trgm/trgm_op.c index 2aeaa0ecc5..154346398a 100644 --- a/contrib/pg_trgm/trgm_op.c +++ b/contrib/pg_trgm/trgm_op.c @@ -10,6 +10,7 @@ #include "miscadmin.h" #include "trgm.h" #include "tsearch/ts_locale.h" +#include "utils/guc.h" #include "utils/lsyscache.h" #include "utils/memutils.h" #include "utils/pg_crc.h" diff --git a/src/backend/access/brin/brin.c b/src/backend/access/brin/brin.c index dcf2d2c4b5..20b7d65b94 100644 --- a/src/backend/access/brin/brin.c +++ b/src/backend/access/brin/brin.c @@ -36,6 +36,7 @@ #include "utils/acl.h" #include "utils/builtins.h" #include "utils/datum.h" +#include "utils/guc.h" #include "utils/index_selfuncs.h" #include "utils/memutils.h" #include "utils/rel.h" diff --git a/src/backend/access/table/tableamapi.c b/src/backend/access/table/tableamapi.c index 873d961bf4..92d9cf31db 100644 --- a/src/backend/access/table/tableamapi.c +++ b/src/backend/access/table/tableamapi.c @@ -20,6 +20,7 @@ #include "commands/defrem.h" #include "miscadmin.h" #include "utils/fmgroids.h" +#include "utils/guc_hooks.h" #include "utils/memutils.h" #include "utils/syscache.h" diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index 7a710e6490..81d339d57d 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -97,7 +97,8 @@ #include "storage/smgr.h" #include "storage/spin.h" #include "storage/sync.h" -#include "utils/guc.h" +#include "utils/guc_hooks.h" +#include "utils/guc_tables.h" #include "utils/memutils.h" #include "utils/ps_status.h" #include "utils/relmapper.h" @@ -105,6 +106,7 @@ #include "utils/snapmgr.h" #include "utils/timeout.h" #include "utils/timestamp.h" +#include "utils/varlena.h" extern uint32 bootstrap_data_checksum_version; @@ -160,6 +162,12 @@ int CheckPointSegments; static double CheckPointDistanceEstimate = 0; static double PrevCheckPointDistance = 0; +/* + * Track whether there were any deferred checks for custom resource managers + * specified in wal_consistency_checking. + */ +static bool check_wal_consistency_checking_deferred = false; + /* * GUC support */ @@ -4304,6 +4312,172 @@ check_wal_buffers(int *newval, void **extra, GucSource source) return true; } +/* + * GUC check_hook for wal_consistency_checking + */ +bool +check_wal_consistency_checking(char **newval, void **extra, GucSource source) +{ + char *rawstring; + List *elemlist; + ListCell *l; + bool newwalconsistency[RM_MAX_ID + 1]; + + /* Initialize the array */ + MemSet(newwalconsistency, 0, (RM_MAX_ID + 1) * sizeof(bool)); + + /* Need a modifiable copy of string */ + rawstring = pstrdup(*newval); + + /* Parse string into list of identifiers */ + if (!SplitIdentifierString(rawstring, ',', &elemlist)) + { + /* syntax error in list */ + GUC_check_errdetail("List syntax is invalid."); + pfree(rawstring); + list_free(elemlist); + return false; + } + + foreach(l, elemlist) + { + char *tok = (char *) lfirst(l); + int rmid; + + /* Check for 'all'. */ + if (pg_strcasecmp(tok, "all") == 0) + { + for (rmid = 0; rmid <= RM_MAX_ID; rmid++) + if (RmgrIdExists(rmid) && GetRmgr(rmid).rm_mask != NULL) + newwalconsistency[rmid] = true; + } + else + { + /* Check if the token matches any known resource manager. */ + bool found = false; + + for (rmid = 0; rmid <= RM_MAX_ID; rmid++) + { + if (RmgrIdExists(rmid) && GetRmgr(rmid).rm_mask != NULL && + pg_strcasecmp(tok, GetRmgr(rmid).rm_name) == 0) + { + newwalconsistency[rmid] = true; + found = true; + break; + } + } + if (!found) + { + /* + * During startup, it might be a not-yet-loaded custom + * resource manager. Defer checking until + * InitializeWalConsistencyChecking(). + */ + if (!process_shared_preload_libraries_done) + { + check_wal_consistency_checking_deferred = true; + } + else + { + GUC_check_errdetail("Unrecognized key word: \"%s\".", tok); + pfree(rawstring); + list_free(elemlist); + return false; + } + } + } + } + + pfree(rawstring); + list_free(elemlist); + + /* assign new value */ + *extra = guc_malloc(ERROR, (RM_MAX_ID + 1) * sizeof(bool)); + memcpy(*extra, newwalconsistency, (RM_MAX_ID + 1) * sizeof(bool)); + return true; +} + +/* + * GUC assign_hook for wal_consistency_checking + */ +void +assign_wal_consistency_checking(const char *newval, void *extra) +{ + /* + * If some checks were deferred, it's possible that the checks will fail + * later during InitializeWalConsistencyChecking(). But in that case, the + * postmaster will exit anyway, so it's safe to proceed with the + * assignment. + * + * Any built-in resource managers specified are assigned immediately, + * which affects WAL created before shared_preload_libraries are + * processed. Any custom resource managers specified won't be assigned + * until after shared_preload_libraries are processed, but that's OK + * because WAL for a custom resource manager can't be written before the + * module is loaded anyway. + */ + wal_consistency_checking = extra; +} + +/* + * InitializeWalConsistencyChecking: run after loading custom resource managers + * + * If any unknown resource managers were specified in the + * wal_consistency_checking GUC, processing was deferred. Now that + * shared_preload_libraries have been loaded, process wal_consistency_checking + * again. + */ +void +InitializeWalConsistencyChecking(void) +{ + Assert(process_shared_preload_libraries_done); + + if (check_wal_consistency_checking_deferred) + { + struct config_generic *guc; + + guc = find_option("wal_consistency_checking", false, false, ERROR); + + check_wal_consistency_checking_deferred = false; + + set_config_option_ext("wal_consistency_checking", + wal_consistency_checking_string, + guc->scontext, guc->source, guc->srole, + GUC_ACTION_SET, true, ERROR, false); + + /* checking should not be deferred again */ + Assert(!check_wal_consistency_checking_deferred); + } +} + +/* + * GUC show_hook for archive_command + */ +const char * +show_archive_command(void) +{ + if (XLogArchivingActive()) + return XLogArchiveCommand; + else + return "(disabled)"; +} + +/* + * GUC show_hook for in_hot_standby + */ +const char * +show_in_hot_standby(void) +{ + /* + * We display the actual state based on shared memory, so that this GUC + * reports up-to-date state if examined intra-query. The underlying + * variable (in_hot_standby_guc) changes only when we transmit a new value + * to the client. + */ + return RecoveryInProgress() ? "on" : "off"; +} + + /* * Read the control file, set respective GUCs. * diff --git a/src/backend/access/transam/xlogprefetcher.c b/src/backend/access/transam/xlogprefetcher.c index 368aa73ce2..342960263c 100644 --- a/src/backend/access/transam/xlogprefetcher.c +++ b/src/backend/access/transam/xlogprefetcher.c @@ -44,7 +44,7 @@ #include "storage/bufmgr.h" #include "storage/shmem.h" #include "storage/smgr.h" -#include "utils/guc.h" +#include "utils/guc_hooks.h" #include "utils/hsearch.h" /* diff --git a/src/backend/access/transam/xlogrecovery.c b/src/backend/access/transam/xlogrecovery.c index 9a80084a68..e00ff14d49 100644 --- a/src/backend/access/transam/xlogrecovery.c +++ b/src/backend/access/transam/xlogrecovery.c @@ -48,6 +48,7 @@ #include "pgstat.h" #include "postmaster/bgwriter.h" #include "postmaster/startup.h" +#include "replication/slot.h" #include "replication/walreceiver.h" #include "storage/fd.h" #include "storage/ipc.h" @@ -57,7 +58,9 @@ #include "storage/procarray.h" #include "storage/spin.h" #include "utils/builtins.h" -#include "utils/guc.h" +#include "utils/datetime.h" +#include "utils/guc_hooks.h" +#include "utils/pg_lsn.h" #include "utils/ps_status.h" #include "utils/pg_rusage.h" @@ -4616,3 +4619,315 @@ RecoveryRequiresIntParameter(const char *param_name, int currValue, int minValue errhint("You can restart the server after making the necessary configuration changes."))); } } + + +/* + * GUC check_hook for primary_slot_name + */ +bool +check_primary_slot_name(char **newval, void **extra, GucSource source) +{ + if (*newval && strcmp(*newval, "") != 0 && + !ReplicationSlotValidateName(*newval, WARNING)) + return false; + + return true; +} + +/* + * Recovery target settings: Only one of the several recovery_target* settings + * may be set. Setting a second one results in an error. The global variable + * recoveryTarget tracks which kind of recovery target was chosen. Other + * variables store the actual target value (for example a string or a xid). + * The assign functions of the parameters check whether a competing parameter + * was already set. But we want to allow setting the same parameter multiple + * times. We also want to allow unsetting a parameter and setting a different + * one, so we unset recoveryTarget when the parameter is set to an empty + * string. + * + * XXX this code is broken by design. Throwing an error from a GUC assign + * hook breaks fundamental assumptions of guc.c. So long as all the variables + * for which this can happen are PGC_POSTMASTER, the consequences are limited, + * since we'd just abort postmaster startup anyway. Nonetheless it's likely + * that we have odd behaviors such as unexpected GUC ordering dependencies. + */ + +static void +pg_attribute_noreturn() +error_multiple_recovery_targets(void) +{ + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("multiple recovery targets specified"), + errdetail("At most one of recovery_target, recovery_target_lsn, recovery_target_name, recovery_target_time, recovery_target_xid may be set."))); +} + +/* + * GUC check_hook for recovery_target + */ +bool +check_recovery_target(char **newval, void **extra, GucSource source) +{ + if (strcmp(*newval, "immediate") != 0 && strcmp(*newval, "") != 0) + { + GUC_check_errdetail("The only allowed value is \"immediate\"."); + return false; + } + return true; +} + +/* + * GUC assign_hook for recovery_target + */ +void +assign_recovery_target(const char *newval, void *extra) +{ + if (recoveryTarget != RECOVERY_TARGET_UNSET && + recoveryTarget != RECOVERY_TARGET_IMMEDIATE) + error_multiple_recovery_targets(); + + if (newval && strcmp(newval, "") != 0) + recoveryTarget = RECOVERY_TARGET_IMMEDIATE; + else + recoveryTarget = RECOVERY_TARGET_UNSET; +} + +/* + * GUC check_hook for recovery_target_lsn + */ +bool +check_recovery_target_lsn(char **newval, void **extra, GucSource source) +{ + if (strcmp(*newval, "") != 0) + { + XLogRecPtr lsn; + XLogRecPtr *myextra; + bool have_error = false; + + lsn = pg_lsn_in_internal(*newval, &have_error); + if (have_error) + return false; + + myextra = (XLogRecPtr *) guc_malloc(ERROR, sizeof(XLogRecPtr)); + *myextra = lsn; + *extra = (void *) myextra; + } + return true; +} + +/* + * GUC assign_hook for recovery_target_lsn + */ +void +assign_recovery_target_lsn(const char *newval, void *extra) +{ + if (recoveryTarget != RECOVERY_TARGET_UNSET && + recoveryTarget != RECOVERY_TARGET_LSN) + error_multiple_recovery_targets(); + + if (newval && strcmp(newval, "") != 0) + { + recoveryTarget = RECOVERY_TARGET_LSN; + recoveryTargetLSN = *((XLogRecPtr *) extra); + } + else + recoveryTarget = RECOVERY_TARGET_UNSET; +} + +/* + * GUC check_hook for recovery_target_name + */ +bool +check_recovery_target_name(char **newval, void **extra, GucSource source) +{ + /* Use the value of newval directly */ + if (strlen(*newval) >= MAXFNAMELEN) + { + GUC_check_errdetail("%s is too long (maximum %d characters).", + "recovery_target_name", MAXFNAMELEN - 1); + return false; + } + return true; +} + +/* + * GUC assign_hook for recovery_target_name + */ +void +assign_recovery_target_name(const char *newval, void *extra) +{ + if (recoveryTarget != RECOVERY_TARGET_UNSET && + recoveryTarget != RECOVERY_TARGET_NAME) + error_multiple_recovery_targets(); + + if (newval && strcmp(newval, "") != 0) + { + recoveryTarget = RECOVERY_TARGET_NAME; + recoveryTargetName = newval; + } + else + recoveryTarget = RECOVERY_TARGET_UNSET; +} + +/* + * GUC check_hook for recovery_target_time + * + * The interpretation of the recovery_target_time string can depend on the + * time zone setting, so we need to wait until after all GUC processing is + * done before we can do the final parsing of the string. This check function + * only does a parsing pass to catch syntax errors, but we store the string + * and parse it again when we need to use it. + */ +bool +check_recovery_target_time(char **newval, void **extra, GucSource source) +{ + if (strcmp(*newval, "") != 0) + { + /* reject some special values */ + if (strcmp(*newval, "now") == 0 || + strcmp(*newval, "today") == 0 || + strcmp(*newval, "tomorrow") == 0 || + strcmp(*newval, "yesterday") == 0) + { + return false; + } + + /* + * parse timestamp value (see also timestamptz_in()) + */ + { + char *str = *newval; + fsec_t fsec; + struct pg_tm tt, + *tm = &tt; + int tz; + int dtype; + int nf; + int dterr; + char *field[MAXDATEFIELDS]; + int ftype[MAXDATEFIELDS]; + char workbuf[MAXDATELEN + MAXDATEFIELDS]; + TimestampTz timestamp; + + dterr = ParseDateTime(str, workbuf, sizeof(workbuf), + field, ftype, MAXDATEFIELDS, &nf); + if (dterr == 0) + dterr = DecodeDateTime(field, ftype, nf, &dtype, tm, &fsec, &tz); + if (dterr != 0) + return false; + if (dtype != DTK_DATE) + return false; + + if (tm2timestamp(tm, fsec, &tz, ×tamp) != 0) + { + GUC_check_errdetail("timestamp out of range: \"%s\"", str); + return false; + } + } + } + return true; +} + +/* + * GUC assign_hook for recovery_target_time + */ +void +assign_recovery_target_time(const char *newval, void *extra) +{ + if (recoveryTarget != RECOVERY_TARGET_UNSET && + recoveryTarget != RECOVERY_TARGET_TIME) + error_multiple_recovery_targets(); + + if (newval && strcmp(newval, "") != 0) + recoveryTarget = RECOVERY_TARGET_TIME; + else + recoveryTarget = RECOVERY_TARGET_UNSET; +} + +/* + * GUC check_hook for recovery_target_timeline + */ +bool +check_recovery_target_timeline(char **newval, void **extra, GucSource source) +{ + RecoveryTargetTimeLineGoal rttg; + RecoveryTargetTimeLineGoal *myextra; + + if (strcmp(*newval, "current") == 0) + rttg = RECOVERY_TARGET_TIMELINE_CONTROLFILE; + else if (strcmp(*newval, "latest") == 0) + rttg = RECOVERY_TARGET_TIMELINE_LATEST; + else + { + rttg = RECOVERY_TARGET_TIMELINE_NUMERIC; + + errno = 0; + strtoul(*newval, NULL, 0); + if (errno == EINVAL || errno == ERANGE) + { + GUC_check_errdetail("recovery_target_timeline is not a valid number."); + return false; + } + } + + myextra = (RecoveryTargetTimeLineGoal *) guc_malloc(ERROR, sizeof(RecoveryTargetTimeLineGoal)); + *myextra = rttg; + *extra = (void *) myextra; + + return true; +} + +/* + * GUC assign_hook for recovery_target_timeline + */ +void +assign_recovery_target_timeline(const char *newval, void *extra) +{ + recoveryTargetTimeLineGoal = *((RecoveryTargetTimeLineGoal *) extra); + if (recoveryTargetTimeLineGoal == RECOVERY_TARGET_TIMELINE_NUMERIC) + recoveryTargetTLIRequested = (TimeLineID) strtoul(newval, NULL, 0); + else + recoveryTargetTLIRequested = 0; +} + +/* + * GUC check_hook for recovery_target_xid + */ +bool +check_recovery_target_xid(char **newval, void **extra, GucSource source) +{ + if (strcmp(*newval, "") != 0) + { + TransactionId xid; + TransactionId *myextra; + + errno = 0; + xid = (TransactionId) strtou64(*newval, NULL, 0); + if (errno == EINVAL || errno == ERANGE) + return false; + + myextra = (TransactionId *) guc_malloc(ERROR, sizeof(TransactionId)); + *myextra = xid; + *extra = (void *) myextra; + } + return true; +} + +/* + * GUC assign_hook for recovery_target_xid + */ +void +assign_recovery_target_xid(const char *newval, void *extra) +{ + if (recoveryTarget != RECOVERY_TARGET_UNSET && + recoveryTarget != RECOVERY_TARGET_XID) + error_multiple_recovery_targets(); + + if (newval && strcmp(newval, "") != 0) + { + recoveryTarget = RECOVERY_TARGET_XID; + recoveryTargetXid = *((TransactionId *) extra); + } + else + recoveryTarget = RECOVERY_TARGET_UNSET; +} diff --git a/src/backend/backup/basebackup.c b/src/backend/backup/basebackup.c index 3bf3aa6faa..2bb831a3cd 100644 --- a/src/backend/backup/basebackup.c +++ b/src/backend/backup/basebackup.c @@ -40,6 +40,7 @@ #include "storage/ipc.h" #include "storage/reinit.h" #include "utils/builtins.h" +#include "utils/guc.h" #include "utils/ps_status.h" #include "utils/relcache.h" #include "utils/resowner.h" diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c index 17ff617fba..b20974bbeb 100644 --- a/src/backend/catalog/aclchk.c +++ b/src/backend/catalog/aclchk.c @@ -74,6 +74,7 @@ #include "utils/aclchk_internal.h" #include "utils/builtins.h" #include "utils/fmgroids.h" +#include "utils/guc.h" #include "utils/lsyscache.h" #include "utils/rel.h" #include "utils/syscache.h" diff --git a/src/backend/catalog/namespace.c b/src/backend/catalog/namespace.c index fafb9349cc..dbb4b008a0 100644 --- a/src/backend/catalog/namespace.c +++ b/src/backend/catalog/namespace.c @@ -51,7 +51,7 @@ #include "utils/acl.h" #include "utils/builtins.h" #include "utils/catcache.h" -#include "utils/guc.h" +#include "utils/guc_hooks.h" #include "utils/inval.h" #include "utils/lsyscache.h" #include "utils/memutils.h" diff --git a/src/backend/catalog/pg_parameter_acl.c b/src/backend/catalog/pg_parameter_acl.c index 0570e811d1..37f6217df5 100644 --- a/src/backend/catalog/pg_parameter_acl.c +++ b/src/backend/catalog/pg_parameter_acl.c @@ -21,6 +21,7 @@ #include "catalog/pg_namespace.h" #include "catalog/pg_parameter_acl.h" #include "utils/builtins.h" +#include "utils/guc.h" #include "utils/pg_locale.h" #include "utils/rel.h" #include "utils/syscache.h" diff --git a/src/backend/commands/cluster.c b/src/backend/commands/cluster.c index dc35b02910..1976a373ef 100644 --- a/src/backend/commands/cluster.c +++ b/src/backend/commands/cluster.c @@ -49,6 +49,7 @@ #include "storage/predicate.h" #include "utils/acl.h" #include "utils/fmgroids.h" +#include "utils/guc.h" #include "utils/inval.h" #include "utils/lsyscache.h" #include "utils/memutils.h" diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c index 9167bab0c5..cf98d9e600 100644 --- a/src/backend/commands/indexcmds.c +++ b/src/backend/commands/indexcmds.c @@ -57,6 +57,7 @@ #include "utils/acl.h" #include "utils/builtins.h" #include "utils/fmgroids.h" +#include "utils/guc.h" #include "utils/inval.h" #include "utils/lsyscache.h" #include "utils/memutils.h" diff --git a/src/backend/commands/tablespace.c b/src/backend/commands/tablespace.c index f260b484fc..b69ff37dbb 100644 --- a/src/backend/commands/tablespace.c +++ b/src/backend/commands/tablespace.c @@ -79,7 +79,7 @@ #include "utils/acl.h" #include "utils/builtins.h" #include "utils/fmgroids.h" -#include "utils/guc.h" +#include "utils/guc_hooks.h" #include "utils/lsyscache.h" #include "utils/memutils.h" #include "utils/rel.h" diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c index 28c3dcd0f7..5ad18d2de4 100644 --- a/src/backend/commands/trigger.c +++ b/src/backend/commands/trigger.c @@ -55,9 +55,11 @@ #include "utils/builtins.h" #include "utils/bytea.h" #include "utils/fmgroids.h" +#include "utils/guc_hooks.h" #include "utils/inval.h" #include "utils/lsyscache.h" #include "utils/memutils.h" +#include "utils/plancache.h" #include "utils/rel.h" #include "utils/snapmgr.h" #include "utils/syscache.h" @@ -6499,6 +6501,20 @@ done: table->after_trig_events = qs->events; } +/* + * GUC assign_hook for session_replication_role + */ +void +assign_session_replication_role(int newval, void *extra) +{ + /* + * Must flush the plan cache when changing replication role; but don't + * flush unnecessarily. + */ + if (SessionReplicationRole != newval) + ResetPlanCache(); +} + /* * SQL function pg_trigger_depth() */ diff --git a/src/backend/commands/variable.c b/src/backend/commands/variable.c index e5ddcda0b4..c795cb7a29 100644 --- a/src/backend/commands/variable.c +++ b/src/backend/commands/variable.c @@ -22,15 +22,23 @@ #include "access/parallel.h" #include "access/xact.h" #include "access/xlog.h" +#include "access/xlogprefetcher.h" #include "catalog/pg_authid.h" -#include "commands/variable.h" +#include "common/string.h" #include "mb/pg_wchar.h" #include "miscadmin.h" +#include "postmaster/postmaster.h" +#include "postmaster/syslogger.h" +#include "storage/bufmgr.h" #include "utils/acl.h" +#include "utils/backend_status.h" #include "utils/builtins.h" +#include "utils/datetime.h" +#include "utils/guc_hooks.h" #include "utils/snapmgr.h" #include "utils/syscache.h" #include "utils/timestamp.h" +#include "utils/tzparser.h" #include "utils/varlena.h" /* @@ -466,6 +474,56 @@ show_log_timezone(void) } +/* + * TIMEZONE_ABBREVIATIONS + */ + +/* + * GUC check_hook for assign_timezone_abbreviations + */ +bool +check_timezone_abbreviations(char **newval, void **extra, GucSource source) +{ + /* + * The boot_val for timezone_abbreviations is NULL. When we see that we + * just do nothing. If the value isn't overridden from the config file + * then pg_timezone_abbrev_initialize() will eventually replace it with + * "Default". This hack has two purposes: to avoid wasting cycles loading + * values that might soon be overridden from the config file, and to avoid + * trying to read the timezone abbrev files during InitializeGUCOptions(). + * The latter doesn't work in an EXEC_BACKEND subprocess because + * my_exec_path hasn't been set yet and so we can't locate PGSHAREDIR. + */ + if (*newval == NULL) + { + Assert(source == PGC_S_DEFAULT); + return true; + } + + /* OK, load the file and produce a malloc'd TimeZoneAbbrevTable */ + *extra = load_tzoffsets(*newval); + + /* tzparser.c returns NULL on failure, reporting via GUC_check_errmsg */ + if (!*extra) + return false; + + return true; +} + +/* + * GUC assign_hook for assign_timezone_abbreviations + */ +void +assign_timezone_abbreviations(const char *newval, void *extra) +{ + /* Do nothing for the boot_val default of NULL */ + if (!extra) + return; + + InstallTimeZoneAbbrevs((TimeZoneAbbrevTable *) extra); +} + + /* * SET TRANSACTION READ ONLY and SET TRANSACTION READ WRITE * @@ -522,7 +580,7 @@ check_transaction_read_only(bool *newval, void **extra, GucSource source) * As in check_transaction_read_only, allow it if not inside a transaction. */ bool -check_XactIsoLevel(int *newval, void **extra, GucSource source) +check_transaction_isolation(int *newval, void **extra, GucSource source) { int newXactIsoLevel = *newval; @@ -933,3 +991,212 @@ show_role(void) /* Otherwise we can just use the GUC string */ return role_string ? role_string : "none"; } + + +/* + * PATH VARIABLES + * + * check_canonical_path is used for log_directory and some other GUCs where + * all we want to do is canonicalize the represented path name. + */ + +bool +check_canonical_path(char **newval, void **extra, GucSource source) +{ + /* + * Since canonicalize_path never enlarges the string, we can just modify + * newval in-place. But watch out for NULL, which is the default value + * for external_pid_file. + */ + if (*newval) + canonicalize_path(*newval); + return true; +} + + +/* + * MISCELLANEOUS + */ + +/* + * GUC check_hook for application_name + */ +bool +check_application_name(char **newval, void **extra, GucSource source) +{ + char *clean; + + /* Only allow clean ASCII chars in the application name */ + clean = pg_clean_ascii(*newval, MCXT_ALLOC_NO_OOM); + if (!clean) + return false; + + clean = guc_strdup(WARNING, clean); + if (!clean) + return false; + + *newval = clean; + return true; +} + +/* + * GUC assign_hook for application_name + */ +void +assign_application_name(const char *newval, void *extra) +{ + /* Update the pg_stat_activity view */ + pgstat_report_appname(newval); +} + +/* + * GUC check_hook for cluster_name + */ +bool +check_cluster_name(char **newval, void **extra, GucSource source) +{ + char *clean; + + /* Only allow clean ASCII chars in the cluster name */ + clean = pg_clean_ascii(*newval, MCXT_ALLOC_NO_OOM); + if (!clean) + return false; + + clean = guc_strdup(WARNING, clean); + if (!clean) + return false; + + *newval = clean; + return true; +} + +/* + * GUC assign_hook for maintenance_io_concurrency + */ +void +assign_maintenance_io_concurrency(int newval, void *extra) +{ +#ifdef USE_PREFETCH + /* + * Reconfigure recovery prefetching, because a setting it depends on + * changed. + */ + maintenance_io_concurrency = newval; + if (AmStartupProcess()) + XLogPrefetchReconfigure(); +#endif +} + + +/* + * These show hooks just exist because we want to show the values in octal. + */ + +/* + * GUC show_hook for data_directory_mode + */ +const char * +show_data_directory_mode(void) +{ + static char buf[12]; + + snprintf(buf, sizeof(buf), "%04o", data_directory_mode); + return buf; +} + +/* + * GUC show_hook for log_file_mode + */ +const char * +show_log_file_mode(void) +{ + static char buf[12]; + + snprintf(buf, sizeof(buf), "%04o", Log_file_mode); + return buf; +} + +/* + * GUC show_hook for unix_socket_permissions + */ +const char * +show_unix_socket_permissions(void) +{ + static char buf[12]; + + snprintf(buf, sizeof(buf), "%04o", Unix_socket_permissions); + return buf; +} + + +/* + * These check hooks do nothing more than reject non-default settings + * in builds that don't support them. + */ + +bool +check_bonjour(bool *newval, void **extra, GucSource source) +{ +#ifndef USE_BONJOUR + if (*newval) + { + GUC_check_errmsg("Bonjour is not supported by this build"); + return false; + } +#endif + return true; +} + +bool +check_default_with_oids(bool *newval, void **extra, GucSource source) +{ + if (*newval) + { + /* check the GUC's definition for an explanation */ + GUC_check_errcode(ERRCODE_FEATURE_NOT_SUPPORTED); + GUC_check_errmsg("tables declared WITH OIDS are not supported"); + + return false; + } + + return true; +} + +bool +check_effective_io_concurrency(int *newval, void **extra, GucSource source) +{ +#ifndef USE_PREFETCH + if (*newval != 0) + { + GUC_check_errdetail("effective_io_concurrency must be set to 0 on platforms that lack posix_fadvise()."); + return false; + } +#endif /* USE_PREFETCH */ + return true; +} + +bool +check_maintenance_io_concurrency(int *newval, void **extra, GucSource source) +{ +#ifndef USE_PREFETCH + if (*newval != 0) + { + GUC_check_errdetail("maintenance_io_concurrency must be set to 0 on platforms that lack posix_fadvise()."); + return false; + } +#endif /* USE_PREFETCH */ + return true; +} + +bool +check_ssl(bool *newval, void **extra, GucSource source) +{ +#ifndef USE_SSL + if (*newval) + { + GUC_check_errmsg("SSL is not supported by this build"); + return false; + } +#endif + return true; +} diff --git a/src/backend/libpq/pqcomm.c b/src/backend/libpq/pqcomm.c index cba0caced7..ce56ab1d41 100644 --- a/src/backend/libpq/pqcomm.c +++ b/src/backend/libpq/pqcomm.c @@ -78,7 +78,7 @@ #include "miscadmin.h" #include "port/pg_bswap.h" #include "storage/ipc.h" -#include "utils/guc.h" +#include "utils/guc_hooks.h" #include "utils/memutils.h" /* @@ -1914,6 +1914,108 @@ pq_settcpusertimeout(int timeout, Port *port) return STATUS_OK; } +/* + * GUC assign_hook for tcp_keepalives_idle + */ +void +assign_tcp_keepalives_idle(int newval, void *extra) +{ + /* + * The kernel API provides no way to test a value without setting it; and + * once we set it we might fail to unset it. So there seems little point + * in fully implementing the check-then-assign GUC API for these + * variables. Instead we just do the assignment on demand. + * pq_setkeepalivesidle reports any problems via ereport(LOG). + * + * This approach means that the GUC value might have little to do with the + * actual kernel value, so we use a show_hook that retrieves the kernel + * value rather than trusting GUC's copy. + */ + (void) pq_setkeepalivesidle(newval, MyProcPort); +} + +/* + * GUC show_hook for tcp_keepalives_idle + */ +const char * +show_tcp_keepalives_idle(void) +{ + /* See comments in assign_tcp_keepalives_idle */ + static char nbuf[16]; + + snprintf(nbuf, sizeof(nbuf), "%d", pq_getkeepalivesidle(MyProcPort)); + return nbuf; +} + +/* + * GUC assign_hook for tcp_keepalives_interval + */ +void +assign_tcp_keepalives_interval(int newval, void *extra) +{ + /* See comments in assign_tcp_keepalives_idle */ + (void) pq_setkeepalivesinterval(newval, MyProcPort); +} + +/* + * GUC show_hook for tcp_keepalives_interval + */ +const char * +show_tcp_keepalives_interval(void) +{ + /* See comments in assign_tcp_keepalives_idle */ + static char nbuf[16]; + + snprintf(nbuf, sizeof(nbuf), "%d", pq_getkeepalivesinterval(MyProcPort)); + return nbuf; +} + +/* + * GUC assign_hook for tcp_keepalives_count + */ +void +assign_tcp_keepalives_count(int newval, void *extra) +{ + /* See comments in assign_tcp_keepalives_idle */ + (void) pq_setkeepalivescount(newval, MyProcPort); +} + +/* + * GUC show_hook for tcp_keepalives_count + */ +const char * +show_tcp_keepalives_count(void) +{ + /* See comments in assign_tcp_keepalives_idle */ + static char nbuf[16]; + + snprintf(nbuf, sizeof(nbuf), "%d", pq_getkeepalivescount(MyProcPort)); + return nbuf; +} + +/* + * GUC assign_hook for tcp_user_timeout + */ +void +assign_tcp_user_timeout(int newval, void *extra) +{ + /* See comments in assign_tcp_keepalives_idle */ + (void) pq_settcpusertimeout(newval, MyProcPort); +} + +/* + * GUC show_hook for tcp_user_timeout + */ +const char * +show_tcp_user_timeout(void) +{ + /* See comments in assign_tcp_keepalives_idle */ + static char nbuf[16]; + + snprintf(nbuf, sizeof(nbuf), "%d", pq_gettcpusertimeout(MyProcPort)); + return nbuf; +} + /* * Check if the client is still connected. */ diff --git a/src/backend/partitioning/partbounds.c b/src/backend/partitioning/partbounds.c index 091d6e886b..57c9b51814 100644 --- a/src/backend/partitioning/partbounds.c +++ b/src/backend/partitioning/partbounds.c @@ -31,6 +31,7 @@ #include "partitioning/partbounds.h" #include "partitioning/partdesc.h" #include "partitioning/partprune.h" +#include "utils/array.h" #include "utils/builtins.h" #include "utils/datum.h" #include "utils/fmgroids.h" diff --git a/src/backend/port/sysv_shmem.c b/src/backend/port/sysv_shmem.c index e62d4a618e..97ce7b7c49 100644 --- a/src/backend/port/sysv_shmem.c +++ b/src/backend/port/sysv_shmem.c @@ -34,7 +34,7 @@ #include "storage/fd.h" #include "storage/ipc.h" #include "storage/pg_shmem.h" -#include "utils/guc.h" +#include "utils/guc_hooks.h" #include "utils/pidfile.h" @@ -570,6 +570,23 @@ GetHugePageSize(Size *hugepagesize, int *mmap_flags) #endif /* MAP_HUGETLB */ } +/* + * GUC check_hook for huge_page_size + */ +bool +check_huge_page_size(int *newval, void **extra, GucSource source) +{ +#if !(defined(MAP_HUGE_MASK) && defined(MAP_HUGE_SHIFT)) + /* Recent enough Linux only, for now. See GetHugePageSize(). */ + if (*newval != 0) + { + GUC_check_errdetail("huge_page_size must be 0 on this platform."); + return false; + } +#endif + return true; +} + /* * Creates an anonymous mmap()ed shared memory segment. * diff --git a/src/backend/port/win32_shmem.c b/src/backend/port/win32_shmem.c index 6cf69411db..d3c9b0f098 100644 --- a/src/backend/port/win32_shmem.c +++ b/src/backend/port/win32_shmem.c @@ -16,6 +16,8 @@ #include "storage/dsm.h" #include "storage/ipc.h" #include "storage/pg_shmem.h" +#include "utils/guc_hooks.h" + /* * Early in a process's life, Windows asynchronously creates threads for the @@ -619,3 +621,17 @@ GetHugePageSize(Size *hugepagesize, int *mmap_flags) if (mmap_flags) *mmap_flags = 0; } + +/* + * GUC check_hook for huge_page_size + */ +bool +check_huge_page_size(int *newval, void **extra, GucSource source) +{ + if (*newval != 0) + { + GUC_check_errdetail("huge_page_size must be 0 on this platform."); + return false; + } + return true; +} diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index 9dc6bf9477..1e90b72b74 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -99,6 +99,7 @@ #include "tcop/tcopprot.h" #include "utils/fmgroids.h" #include "utils/fmgrprotos.h" +#include "utils/guc_hooks.h" #include "utils/lsyscache.h" #include "utils/memutils.h" #include "utils/ps_status.h" @@ -3374,3 +3375,29 @@ AutoVacuumShmemInit(void) else Assert(found); } + +/* + * GUC check_hook for autovacuum_work_mem + */ +bool +check_autovacuum_work_mem(int *newval, void **extra, GucSource source) +{ + /* + * -1 indicates fallback. + * + * If we haven't yet changed the boot_val default of -1, just let it be. + * Autovacuum will look to maintenance_work_mem instead. + */ + if (*newval == -1) + return true; + + /* + * We clamp manually-set values to at least 1MB. Since + * maintenance_work_mem is always set to at least this value, do the same + * here. + */ + if (*newval < 1024) + *newval = 1024; + + return true; +} diff --git a/src/backend/replication/repl_gram.y b/src/backend/replication/repl_gram.y index 8ff6ab362f..fe1ec2bc81 100644 --- a/src/backend/replication/repl_gram.y +++ b/src/backend/replication/repl_gram.y @@ -17,6 +17,7 @@ #include "access/xlogdefs.h" #include "nodes/makefuncs.h" +#include "nodes/parsenodes.h" #include "nodes/replnodes.h" #include "replication/walsender.h" #include "replication/walsender_private.h" diff --git a/src/backend/replication/repl_scanner.l b/src/backend/replication/repl_scanner.l index 23fcb2a11d..72ef12225e 100644 --- a/src/backend/replication/repl_scanner.l +++ b/src/backend/replication/repl_scanner.l @@ -15,6 +15,7 @@ */ #include "postgres.h" +#include "nodes/parsenodes.h" #include "utils/builtins.h" #include "parser/scansup.h" diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index ce163b99e9..e360d925b0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -84,6 +84,7 @@ #include "storage/proc.h" #include "tcop/tcopprot.h" #include "utils/builtins.h" +#include "utils/guc_hooks.h" #include "utils/ps_status.h" /* User-settable parameters for sync rep */ diff --git a/src/backend/replication/syncrep_gram.y b/src/backend/replication/syncrep_gram.y index c18ddb2e9b..4a8b9f247b 100644 --- a/src/backend/replication/syncrep_gram.y +++ b/src/backend/replication/syncrep_gram.y @@ -14,6 +14,7 @@ */ #include "postgres.h" +#include "nodes/pg_list.h" #include "replication/syncrep.h" /* Result of parsing is returned in one of these two variables */ diff --git a/src/backend/replication/syncrep_scanner.l b/src/backend/replication/syncrep_scanner.l index bdb1a3391c..2f942357f9 100644 --- a/src/backend/replication/syncrep_scanner.l +++ b/src/backend/replication/syncrep_scanner.l @@ -16,6 +16,7 @@ #include "postgres.h" #include "lib/stringinfo.h" +#include "nodes/pg_list.h" /* * NB: include syncrep_gram.h only AFTER including syncrep.h, because syncrep.h diff --git a/src/backend/storage/buffer/localbuf.c b/src/backend/storage/buffer/localbuf.c index 98530078a6..30d67d1c40 100644 --- a/src/backend/storage/buffer/localbuf.c +++ b/src/backend/storage/buffer/localbuf.c @@ -20,7 +20,7 @@ #include "executor/instrument.h" #include "storage/buf_internals.h" #include "storage/bufmgr.h" -#include "utils/guc.h" +#include "utils/guc_hooks.h" #include "utils/memutils.h" #include "utils/resowner_private.h" @@ -483,6 +483,24 @@ InitLocalBuffers(void) NLocBuffer = nbufs; } +/* + * GUC check_hook for temp_buffers + */ +bool +check_temp_buffers(int *newval, void **extra, GucSource source) +{ + /* + * Once local buffers have been initialized, it's too late to change this. + * However, if this is only a test call, allow it. + */ + if (source != PGC_S_TEST && NLocBuffer && NLocBuffer != *newval) + { + GUC_check_errdetail("\"temp_buffers\" cannot be changed after any temporary tables have been accessed in the session."); + return false; + } + return true; +} + /* * GetLocalBufferStorage - allocate memory for a local buffer * diff --git a/src/backend/storage/ipc/ipci.c b/src/backend/storage/ipc/ipci.c index 1a6f527051..b204ecdbc3 100644 --- a/src/backend/storage/ipc/ipci.c +++ b/src/backend/storage/ipc/ipci.c @@ -47,6 +47,7 @@ #include "storage/procsignal.h" #include "storage/sinvaladt.h" #include "storage/spin.h" +#include "utils/guc.h" #include "utils/snapmgr.h" /* GUCs */ diff --git a/src/backend/storage/lmgr/predicate.c b/src/backend/storage/lmgr/predicate.c index 5136da6ea3..562ac5b432 100644 --- a/src/backend/storage/lmgr/predicate.c +++ b/src/backend/storage/lmgr/predicate.c @@ -1685,8 +1685,8 @@ GetSerializableTransactionSnapshot(Snapshot snapshot) /* * Can't use serializable mode while recovery is still active, as it is, * for example, on a hot standby. We could get here despite the check in - * check_XactIsoLevel() if default_transaction_isolation is set to - * serializable, so phrase the hint accordingly. + * check_transaction_isolation() if default_transaction_isolation is set + * to serializable, so phrase the hint accordingly. */ if (RecoveryInProgress()) ereport(ERROR, diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c index c6ca3b5b3d..35eff28bd3 100644 --- a/src/backend/tcop/postgres.c +++ b/src/backend/tcop/postgres.c @@ -67,6 +67,7 @@ #include "tcop/pquery.h" #include "tcop/tcopprot.h" #include "tcop/utility.h" +#include "utils/guc_hooks.h" #include "utils/lsyscache.h" #include "utils/memutils.h" #include "utils/ps_status.h" @@ -3505,6 +3506,58 @@ assign_max_stack_depth(int newval, void *extra) max_stack_depth_bytes = newval_bytes; } +/* + * GUC check_hook for client_connection_check_interval + */ +bool +check_client_connection_check_interval(int *newval, void **extra, GucSource source) +{ + if (!WaitEventSetCanReportClosed() && *newval != 0) + { + GUC_check_errdetail("client_connection_check_interval must be set to 0 on this platform."); + return false; + } + return true; +} + +/* + * GUC check_hook for log_parser_stats, log_planner_stats, log_executor_stats + * + * This function and check_log_stats interact to prevent their variables from + * being set in a disallowed combination. This is a hack that doesn't really + * work right; for example it might fail while applying pg_db_role_setting + * values even though the final state would have been acceptable. However, + * since these variables are legacy settings with little production usage, + * we tolerate that. + */ +bool +check_stage_log_stats(bool *newval, void **extra, GucSource source) +{ + if (*newval && log_statement_stats) + { + GUC_check_errdetail("Cannot enable parameter when \"log_statement_stats\" is true."); + return false; + } + return true; +} + +/* + * GUC check_hook for log_statement_stats + */ +bool +check_log_stats(bool *newval, void **extra, GucSource source) +{ + if (*newval && + (log_parser_stats || log_planner_stats || log_executor_stats)) + { + GUC_check_errdetail("Cannot enable \"log_statement_stats\" when " + "\"log_parser_stats\", \"log_planner_stats\", " + "or \"log_executor_stats\" is true."); + return false; + } + return true; +} + /* * set_debug_options --- apply "-d N" command line option diff --git a/src/backend/tsearch/dict.c b/src/backend/tsearch/dict.c index c6ea9f9269..f2c468f846 100644 --- a/src/backend/tsearch/dict.c +++ b/src/backend/tsearch/dict.c @@ -16,6 +16,7 @@ #include "catalog/pg_type.h" #include "tsearch/ts_cache.h" #include "tsearch/ts_utils.h" +#include "utils/array.h" #include "utils/builtins.h" diff --git a/src/backend/utils/adt/pg_locale.c b/src/backend/utils/adt/pg_locale.c index 1a047a97d7..2b42d9ccd8 100644 --- a/src/backend/utils/adt/pg_locale.c +++ b/src/backend/utils/adt/pg_locale.c @@ -60,6 +60,7 @@ #include "mb/pg_wchar.h" #include "utils/builtins.h" #include "utils/formatting.h" +#include "utils/guc_hooks.h" #include "utils/hsearch.h" #include "utils/lsyscache.h" #include "utils/memutils.h" diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c index 50b588e3d0..c746759eef 100644 --- a/src/backend/utils/adt/selfuncs.c +++ b/src/backend/utils/adt/selfuncs.c @@ -123,6 +123,7 @@ #include "statistics/statistics.h" #include "storage/bufmgr.h" #include "utils/acl.h" +#include "utils/array.h" #include "utils/builtins.h" #include "utils/date.h" #include "utils/datum.h" diff --git a/src/backend/utils/adt/varchar.c b/src/backend/utils/adt/varchar.c index bbeb0a2653..68e2e6f7a7 100644 --- a/src/backend/utils/adt/varchar.c +++ b/src/backend/utils/adt/varchar.c @@ -15,6 +15,7 @@ #include "postgres.h" #include "access/detoast.h" +#include "access/htup_details.h" #include "catalog/pg_collation.h" #include "catalog/pg_type.h" #include "common/hashfn.h" diff --git a/src/backend/utils/adt/varlena.c b/src/backend/utils/adt/varlena.c index 6ef317e1f9..816c66b7e7 100644 --- a/src/backend/utils/adt/varlena.c +++ b/src/backend/utils/adt/varlena.c @@ -34,6 +34,7 @@ #include "regex/regex.h" #include "utils/builtins.h" #include "utils/bytea.h" +#include "utils/guc.h" #include "utils/lsyscache.h" #include "utils/memutils.h" #include "utils/pg_locale.h" diff --git a/src/backend/utils/cache/ts_cache.c b/src/backend/utils/cache/ts_cache.c index 24808dfbb1..890832f353 100644 --- a/src/backend/utils/cache/ts_cache.c +++ b/src/backend/utils/cache/ts_cache.c @@ -42,6 +42,7 @@ #include "utils/builtins.h" #include "utils/catcache.h" #include "utils/fmgroids.h" +#include "utils/guc_hooks.h" #include "utils/inval.h" #include "utils/lsyscache.h" #include "utils/memutils.h" @@ -584,7 +585,7 @@ getTSCurrentConfig(bool emitError) /* GUC check_hook for default_text_search_config */ bool -check_TSCurrentConfig(char **newval, void **extra, GucSource source) +check_default_text_search_config(char **newval, void **extra, GucSource source) { /* * If we aren't inside a transaction, or connected to a database, we @@ -645,7 +646,7 @@ check_TSCurrentConfig(char **newval, void **extra, GucSource source) /* GUC assign_hook for default_text_search_config */ void -assign_TSCurrentConfig(const char *newval, void *extra) +assign_default_text_search_config(const char *newval, void *extra) { /* Just reset the cache to force a lookup on first use */ TSCurrentConfigCache = InvalidOid; diff --git a/src/backend/utils/error/elog.c b/src/backend/utils/error/elog.c index cb3c289889..96c694da8f 100644 --- a/src/backend/utils/error/elog.c +++ b/src/backend/utils/error/elog.c @@ -79,9 +79,10 @@ #include "storage/ipc.h" #include "storage/proc.h" #include "tcop/tcopprot.h" -#include "utils/guc.h" +#include "utils/guc_hooks.h" #include "utils/memutils.h" #include "utils/ps_status.h" +#include "utils/varlena.h" /* In this module, access gettext() via err_gettext() */ @@ -113,6 +114,9 @@ char *Log_destination_string = NULL; bool syslog_sequence_numbers = true; bool syslog_split_messages = true; +/* Processed form of backtrace_symbols GUC */ +static char *backtrace_symbol_list; + #ifdef HAVE_SYSLOG /* @@ -1957,14 +1961,159 @@ DebugFileOpen(void) } -#ifdef HAVE_SYSLOG +/* + * GUC check_hook for backtrace_functions + * + * We split the input string, where commas separate function names + * and certain whitespace chars are ignored, into a \0-separated (and + * \0\0-terminated) list of function names. This formulation allows + * easy scanning when an error is thrown while avoiding the use of + * non-reentrant strtok(), as well as keeping the output data in a + * single palloc() chunk. + */ +bool +check_backtrace_functions(char **newval, void **extra, GucSource source) +{ + int newvallen = strlen(*newval); + char *someval; + int validlen; + int i; + int j; + + /* + * Allow characters that can be C identifiers and commas as separators, as + * well as some whitespace for readability. + */ + validlen = strspn(*newval, + "0123456789_" + "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + ", \n\t"); + if (validlen != newvallen) + { + GUC_check_errdetail("invalid character"); + return false; + } + + if (*newval[0] == '\0') + { + *extra = NULL; + return true; + } + + /* + * Allocate space for the output and create the copy. We could discount + * whitespace chars to save some memory, but it doesn't seem worth the + * trouble. + */ + someval = guc_malloc(ERROR, newvallen + 1 + 1); + for (i = 0, j = 0; i < newvallen; i++) + { + if ((*newval)[i] == ',') + someval[j++] = '\0'; /* next item */ + else if ((*newval)[i] == ' ' || + (*newval)[i] == '\n' || + (*newval)[i] == '\t') + ; /* ignore these */ + else + someval[j++] = (*newval)[i]; /* copy anything else */ + } + + /* two \0s end the setting */ + someval[j] = '\0'; + someval[j + 1] = '\0'; + + *extra = someval; + return true; +} /* - * Set or update the parameters for syslog logging + * GUC assign_hook for backtrace_functions */ void -set_syslog_parameters(const char *ident, int facility) +assign_backtrace_functions(const char *newval, void *extra) { + backtrace_symbol_list = (char *) extra; +} + +/* + * GUC check_hook for log_destination + */ +bool +check_log_destination(char **newval, void **extra, GucSource source) +{ + char *rawstring; + List *elemlist; + ListCell *l; + int newlogdest = 0; + int *myextra; + + /* Need a modifiable copy of string */ + rawstring = pstrdup(*newval); + + /* Parse string into list of identifiers */ + if (!SplitIdentifierString(rawstring, ',', &elemlist)) + { + /* syntax error in list */ + GUC_check_errdetail("List syntax is invalid."); + pfree(rawstring); + list_free(elemlist); + return false; + } + + foreach(l, elemlist) + { + char *tok = (char *) lfirst(l); + + if (pg_strcasecmp(tok, "stderr") == 0) + newlogdest |= LOG_DESTINATION_STDERR; + else if (pg_strcasecmp(tok, "csvlog") == 0) + newlogdest |= LOG_DESTINATION_CSVLOG; + else if (pg_strcasecmp(tok, "jsonlog") == 0) + newlogdest |= LOG_DESTINATION_JSONLOG; +#ifdef HAVE_SYSLOG + else if (pg_strcasecmp(tok, "syslog") == 0) + newlogdest |= LOG_DESTINATION_SYSLOG; +#endif +#ifdef WIN32 + else if (pg_strcasecmp(tok, "eventlog") == 0) + newlogdest |= LOG_DESTINATION_EVENTLOG; +#endif + else + { + GUC_check_errdetail("Unrecognized key word: \"%s\".", tok); + pfree(rawstring); + list_free(elemlist); + return false; + } + } + + pfree(rawstring); + list_free(elemlist); + + myextra = (int *) guc_malloc(ERROR, sizeof(int)); + *myextra = newlogdest; + *extra = (void *) myextra; + + return true; +} + +/* + * GUC assign_hook for log_destination + */ +void +assign_log_destination(const char *newval, void *extra) +{ + Log_destination = *((int *) extra); +} + +/* + * GUC assign_hook for syslog_ident + */ +void +assign_syslog_ident(const char *newval, void *extra) +{ +#ifdef HAVE_SYSLOG /* * guc.c is likely to call us repeatedly with same parameters, so don't * thrash the syslog connection unnecessarily. Also, we do not re-open @@ -1975,8 +2124,7 @@ set_syslog_parameters(const char *ident, int facility) * on guc.c's. This may be overly paranoid, but it ensures that we cannot * accidentally free a string that syslog is still using. */ - if (syslog_ident == NULL || strcmp(syslog_ident, ident) != 0 || - syslog_facility != facility) + if (syslog_ident == NULL || strcmp(syslog_ident, newval) != 0) { if (openlog_done) { @@ -1984,12 +2132,37 @@ set_syslog_parameters(const char *ident, int facility) openlog_done = false; } free(syslog_ident); - syslog_ident = strdup(ident); + syslog_ident = strdup(newval); /* if the strdup fails, we will cope in write_syslog() */ - syslog_facility = facility; } +#endif + /* Without syslog support, just ignore it */ } +/* + * GUC assign_hook for syslog_facility + */ +void +assign_syslog_facility(int newval, void *extra) +{ +#ifdef HAVE_SYSLOG + /* + * As above, don't thrash the syslog connection unnecessarily. + */ + if (syslog_facility != newval) + { + if (openlog_done) + { + closelog(); + openlog_done = false; + } + syslog_facility = newval; + } +#endif + /* Without syslog support, just ignore it */ +} + +#ifdef HAVE_SYSLOG /* * Write a message line to syslog diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c index 2b65ef3deb..4a207a7391 100644 --- a/src/backend/utils/init/postinit.c +++ b/src/backend/utils/init/postinit.c @@ -58,7 +58,7 @@ #include "utils/acl.h" #include "utils/builtins.h" #include "utils/fmgroids.h" -#include "utils/guc.h" +#include "utils/guc_hooks.h" #include "utils/memutils.h" #include "utils/pg_locale.h" #include "utils/portal.h" @@ -563,6 +563,54 @@ InitializeMaxBackends(void) elog(ERROR, "too many backends configured"); } +/* + * GUC check_hook for max_connections + */ +bool +check_max_connections(int *newval, void **extra, GucSource source) +{ + if (*newval + autovacuum_max_workers + 1 + + max_worker_processes + max_wal_senders > MAX_BACKENDS) + return false; + return true; +} + +/* + * GUC check_hook for autovacuum_max_workers + */ +bool +check_autovacuum_max_workers(int *newval, void **extra, GucSource source) +{ + if (MaxConnections + *newval + 1 + + max_worker_processes + max_wal_senders > MAX_BACKENDS) + return false; + return true; +} + +/* + * GUC check_hook for max_worker_processes + */ +bool +check_max_worker_processes(int *newval, void **extra, GucSource source) +{ + if (MaxConnections + autovacuum_max_workers + 1 + + *newval + max_wal_senders > MAX_BACKENDS) + return false; + return true; +} + +/* + * GUC check_hook for max_wal_senders + */ +bool +check_max_wal_senders(int *newval, void **extra, GucSource source) +{ + if (MaxConnections + autovacuum_max_workers + 1 + + max_worker_processes + *newval > MAX_BACKENDS) + return false; + return true; +} + /* * Early initialization of a backend (either standalone or under postmaster). * This happens even before InitPostgres. diff --git a/src/backend/utils/misc/Makefile b/src/backend/utils/misc/Makefile index cf7ce9bc83..6097309033 100644 --- a/src/backend/utils/misc/Makefile +++ b/src/backend/utils/misc/Makefile @@ -17,6 +17,8 @@ override CPPFLAGS := -I. -I$(srcdir) $(CPPFLAGS) OBJS = \ guc.o \ guc-file.o \ + guc_funcs.o \ + guc_tables.o \ help_config.o \ pg_config.o \ pg_controldata.o \ diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index ec64b39272..b11d609bbe 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -3,6 +3,14 @@ * * Support for grand unified configuration scheme, including SET * command, configuration file, and command line options. + * + * This file contains the generic option processing infrastructure. + * guc_funcs.c contains SQL-level functionality, including SET/SHOW + * commands and various system-administration SQL functions. + * guc_tables.c contains the arrays that define all the built-in + * GUC variables. Code that implements variable-specific behavior + * is scattered around the system in check, assign, and show hooks. + * * See src/backend/utils/misc/README for more information. * * @@ -16,109 +24,30 @@ */ #include "postgres.h" -#include -#include -#include #include -#ifdef HAVE_POLL_H -#include -#endif -#ifndef WIN32 -#include -#endif #include -#ifdef HAVE_SYSLOG -#include -#endif #include -#include "access/commit_ts.h" -#include "access/gin.h" -#include "access/rmgr.h" -#include "access/tableam.h" -#include "access/toast_compression.h" -#include "access/transam.h" -#include "access/twophase.h" #include "access/xact.h" -#include "access/xlog_internal.h" -#include "access/xlogprefetcher.h" -#include "access/xlogrecovery.h" -#include "catalog/namespace.h" +#include "access/xlog.h" #include "catalog/objectaccess.h" #include "catalog/pg_authid.h" #include "catalog/pg_parameter_acl.h" -#include "catalog/storage.h" -#include "commands/async.h" -#include "commands/prepare.h" -#include "commands/tablespace.h" -#include "commands/trigger.h" -#include "commands/user.h" -#include "commands/vacuum.h" -#include "commands/variable.h" -#include "common/string.h" -#include "funcapi.h" #include "guc_internal.h" -#include "jit/jit.h" -#include "libpq/auth.h" -#include "libpq/libpq.h" #include "libpq/pqformat.h" -#include "miscadmin.h" -#include "optimizer/cost.h" -#include "optimizer/geqo.h" -#include "optimizer/optimizer.h" -#include "optimizer/paths.h" -#include "optimizer/planmain.h" -#include "parser/parse_expr.h" -#include "parser/parse_type.h" -#include "parser/parser.h" #include "parser/scansup.h" -#include "pgstat.h" -#include "postmaster/autovacuum.h" -#include "postmaster/bgworker_internals.h" -#include "postmaster/bgwriter.h" -#include "postmaster/postmaster.h" -#include "postmaster/startup.h" -#include "postmaster/syslogger.h" -#include "postmaster/walwriter.h" -#include "replication/logicallauncher.h" -#include "replication/reorderbuffer.h" -#include "replication/slot.h" -#include "replication/syncrep.h" -#include "replication/walreceiver.h" -#include "replication/walsender.h" -#include "storage/bufmgr.h" -#include "storage/dsm_impl.h" #include "storage/fd.h" -#include "storage/large_object.h" -#include "storage/pg_shmem.h" -#include "storage/predicate.h" -#include "storage/proc.h" -#include "storage/standby.h" +#include "storage/lwlock.h" +#include "storage/shmem.h" #include "tcop/tcopprot.h" -#include "tsearch/ts_cache.h" #include "utils/acl.h" #include "utils/backend_status.h" #include "utils/builtins.h" -#include "utils/bytea.h" #include "utils/float.h" #include "utils/guc_tables.h" #include "utils/memutils.h" -#include "utils/pg_locale.h" -#include "utils/pg_lsn.h" -#include "utils/plancache.h" -#include "utils/portal.h" -#include "utils/ps_status.h" -#include "utils/queryjumble.h" -#include "utils/rls.h" -#include "utils/snapmgr.h" -#include "utils/tzparser.h" -#include "utils/inval.h" -#include "utils/varlena.h" -#include "utils/xml.h" +#include "utils/timestamp.h" -#ifndef PG_KRB_SRVTAB -#define PG_KRB_SRVTAB "" -#endif #define CONFIG_FILENAME "postgresql.conf" #define HBA_FILENAME "pg_hba.conf" @@ -135,23 +64,6 @@ */ #define REALTYPE_PRECISION 17 -/* XXX these should appear in other modules' header files */ -extern bool Log_disconnections; -extern int CommitDelay; -extern int CommitSiblings; -extern char *default_tablespace; -extern char *temp_tablespaces; -extern bool ignore_checksum_failure; -extern bool ignore_invalid_pages; -extern bool synchronize_seqscans; - -#ifdef TRACE_SYNCSCAN -extern bool trace_syncscan; -#endif -#ifdef DEBUG_BOUNDED_SORT -extern bool optimize_bounded_sort; -#endif - static int GUC_check_errcode_value; static List *reserved_class_prefix = NIL; @@ -161,725 +73,9 @@ char *GUC_check_errmsg_string; char *GUC_check_errdetail_string; char *GUC_check_errhint_string; -static void do_serialize(char **destptr, Size *maxbytes, const char *fmt,...) pg_attribute_printf(3, 4); +/* Kluge: for speed, we examine this GUC variable's value directly */ +extern bool in_hot_standby_guc; -static void set_config_sourcefile(const char *name, char *sourcefile, - int sourceline); -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); - -static bool check_log_destination(char **newval, void **extra, GucSource source); -static void assign_log_destination(const char *newval, void *extra); - -static bool check_wal_consistency_checking(char **newval, void **extra, - GucSource source); -static void assign_wal_consistency_checking(const char *newval, void *extra); - -#ifdef HAVE_SYSLOG -static int syslog_facility = LOG_LOCAL0; -#else -static int syslog_facility = 0; -#endif - -static void assign_syslog_facility(int newval, void *extra); -static void assign_syslog_ident(const char *newval, void *extra); -static void assign_session_replication_role(int newval, void *extra); -static bool check_temp_buffers(int *newval, void **extra, GucSource source); -static bool check_bonjour(bool *newval, void **extra, GucSource source); -static bool check_ssl(bool *newval, void **extra, GucSource source); -static bool check_stage_log_stats(bool *newval, void **extra, GucSource source); -static bool check_log_stats(bool *newval, void **extra, GucSource source); -static bool check_canonical_path(char **newval, void **extra, GucSource source); -static bool check_timezone_abbreviations(char **newval, void **extra, GucSource source); -static void assign_timezone_abbreviations(const char *newval, void *extra); -static void pg_timezone_abbrev_initialize(void); -static const char *show_archive_command(void); -static void assign_tcp_keepalives_idle(int newval, void *extra); -static void assign_tcp_keepalives_interval(int newval, void *extra); -static void assign_tcp_keepalives_count(int newval, void *extra); -static void assign_tcp_user_timeout(int newval, void *extra); -static const char *show_tcp_keepalives_idle(void); -static const char *show_tcp_keepalives_interval(void); -static const char *show_tcp_keepalives_count(void); -static const char *show_tcp_user_timeout(void); -static bool check_maxconnections(int *newval, void **extra, GucSource source); -static bool check_max_worker_processes(int *newval, void **extra, GucSource source); -static bool check_autovacuum_max_workers(int *newval, void **extra, GucSource source); -static bool check_max_wal_senders(int *newval, void **extra, GucSource source); -static bool check_autovacuum_work_mem(int *newval, void **extra, GucSource source); -static bool check_effective_io_concurrency(int *newval, void **extra, GucSource source); -static bool check_maintenance_io_concurrency(int *newval, void **extra, GucSource source); -static bool check_huge_page_size(int *newval, void **extra, GucSource source); -static bool check_client_connection_check_interval(int *newval, void **extra, GucSource source); -static void assign_maintenance_io_concurrency(int newval, void *extra); -static bool check_application_name(char **newval, void **extra, GucSource source); -static void assign_application_name(const char *newval, void *extra); -static bool check_cluster_name(char **newval, void **extra, GucSource source); -static const char *show_unix_socket_permissions(void); -static const char *show_log_file_mode(void); -static const char *show_data_directory_mode(void); -static const char *show_in_hot_standby(void); -static bool check_backtrace_functions(char **newval, void **extra, GucSource source); -static void assign_backtrace_functions(const char *newval, void *extra); -static bool check_recovery_target_timeline(char **newval, void **extra, GucSource source); -static void assign_recovery_target_timeline(const char *newval, void *extra); -static bool check_recovery_target(char **newval, void **extra, GucSource source); -static void assign_recovery_target(const char *newval, void *extra); -static bool check_recovery_target_xid(char **newval, void **extra, GucSource source); -static void assign_recovery_target_xid(const char *newval, void *extra); -static bool check_recovery_target_time(char **newval, void **extra, GucSource source); -static void assign_recovery_target_time(const char *newval, void *extra); -static bool check_recovery_target_name(char **newval, void **extra, GucSource source); -static void assign_recovery_target_name(const char *newval, void *extra); -static bool check_recovery_target_lsn(char **newval, void **extra, GucSource source); -static void assign_recovery_target_lsn(const char *newval, void *extra); -static bool check_primary_slot_name(char **newval, void **extra, GucSource source); -static bool check_default_with_oids(bool *newval, void **extra, GucSource source); - -/* - * Track whether there were any deferred checks for custom resource managers - * specified in wal_consistency_checking. - */ -static bool check_wal_consistency_checking_deferred = false; - -/* - * Options for enum values defined in this module. - * - * NOTE! Option values may not contain double quotes! - */ - -static const struct config_enum_entry bytea_output_options[] = { - {"escape", BYTEA_OUTPUT_ESCAPE, false}, - {"hex", BYTEA_OUTPUT_HEX, false}, - {NULL, 0, false} -}; - -StaticAssertDecl(lengthof(bytea_output_options) == (BYTEA_OUTPUT_HEX + 2), - "array length mismatch"); - -/* - * We have different sets for client and server message level options because - * they sort slightly different (see "log" level), and because "fatal"/"panic" - * aren't sensible for client_min_messages. - */ -static const struct config_enum_entry client_message_level_options[] = { - {"debug5", DEBUG5, false}, - {"debug4", DEBUG4, false}, - {"debug3", DEBUG3, false}, - {"debug2", DEBUG2, false}, - {"debug1", DEBUG1, false}, - {"debug", DEBUG2, true}, - {"log", LOG, false}, - {"info", INFO, true}, - {"notice", NOTICE, false}, - {"warning", WARNING, false}, - {"error", ERROR, false}, - {NULL, 0, false} -}; - -static const struct config_enum_entry server_message_level_options[] = { - {"debug5", DEBUG5, false}, - {"debug4", DEBUG4, false}, - {"debug3", DEBUG3, false}, - {"debug2", DEBUG2, false}, - {"debug1", DEBUG1, false}, - {"debug", DEBUG2, true}, - {"info", INFO, false}, - {"notice", NOTICE, false}, - {"warning", WARNING, false}, - {"error", ERROR, false}, - {"log", LOG, false}, - {"fatal", FATAL, false}, - {"panic", PANIC, false}, - {NULL, 0, false} -}; - -static const struct config_enum_entry intervalstyle_options[] = { - {"postgres", INTSTYLE_POSTGRES, false}, - {"postgres_verbose", INTSTYLE_POSTGRES_VERBOSE, false}, - {"sql_standard", INTSTYLE_SQL_STANDARD, false}, - {"iso_8601", INTSTYLE_ISO_8601, false}, - {NULL, 0, false} -}; - -StaticAssertDecl(lengthof(intervalstyle_options) == (INTSTYLE_ISO_8601 + 2), - "array length mismatch"); - -static const struct config_enum_entry log_error_verbosity_options[] = { - {"terse", PGERROR_TERSE, false}, - {"default", PGERROR_DEFAULT, false}, - {"verbose", PGERROR_VERBOSE, false}, - {NULL, 0, false} -}; - -StaticAssertDecl(lengthof(log_error_verbosity_options) == (PGERROR_VERBOSE + 2), - "array length mismatch"); - -static const struct config_enum_entry log_statement_options[] = { - {"none", LOGSTMT_NONE, false}, - {"ddl", LOGSTMT_DDL, false}, - {"mod", LOGSTMT_MOD, false}, - {"all", LOGSTMT_ALL, false}, - {NULL, 0, false} -}; - -StaticAssertDecl(lengthof(log_statement_options) == (LOGSTMT_ALL + 2), - "array length mismatch"); - -static const struct config_enum_entry isolation_level_options[] = { - {"serializable", XACT_SERIALIZABLE, false}, - {"repeatable read", XACT_REPEATABLE_READ, false}, - {"read committed", XACT_READ_COMMITTED, false}, - {"read uncommitted", XACT_READ_UNCOMMITTED, false}, - {NULL, 0} -}; - -static const struct config_enum_entry session_replication_role_options[] = { - {"origin", SESSION_REPLICATION_ROLE_ORIGIN, false}, - {"replica", SESSION_REPLICATION_ROLE_REPLICA, false}, - {"local", SESSION_REPLICATION_ROLE_LOCAL, false}, - {NULL, 0, false} -}; - -StaticAssertDecl(lengthof(session_replication_role_options) == (SESSION_REPLICATION_ROLE_LOCAL + 2), - "array length mismatch"); - -static const struct config_enum_entry syslog_facility_options[] = { -#ifdef HAVE_SYSLOG - {"local0", LOG_LOCAL0, false}, - {"local1", LOG_LOCAL1, false}, - {"local2", LOG_LOCAL2, false}, - {"local3", LOG_LOCAL3, false}, - {"local4", LOG_LOCAL4, false}, - {"local5", LOG_LOCAL5, false}, - {"local6", LOG_LOCAL6, false}, - {"local7", LOG_LOCAL7, false}, -#else - {"none", 0, false}, -#endif - {NULL, 0} -}; - -static const struct config_enum_entry track_function_options[] = { - {"none", TRACK_FUNC_OFF, false}, - {"pl", TRACK_FUNC_PL, false}, - {"all", TRACK_FUNC_ALL, false}, - {NULL, 0, false} -}; - -StaticAssertDecl(lengthof(track_function_options) == (TRACK_FUNC_ALL + 2), - "array length mismatch"); - -static const struct config_enum_entry stats_fetch_consistency[] = { - {"none", PGSTAT_FETCH_CONSISTENCY_NONE, false}, - {"cache", PGSTAT_FETCH_CONSISTENCY_CACHE, false}, - {"snapshot", PGSTAT_FETCH_CONSISTENCY_SNAPSHOT, false}, - {NULL, 0, false} -}; - -StaticAssertDecl(lengthof(stats_fetch_consistency) == (PGSTAT_FETCH_CONSISTENCY_SNAPSHOT + 2), - "array length mismatch"); - -static const struct config_enum_entry xmlbinary_options[] = { - {"base64", XMLBINARY_BASE64, false}, - {"hex", XMLBINARY_HEX, false}, - {NULL, 0, false} -}; - -StaticAssertDecl(lengthof(xmlbinary_options) == (XMLBINARY_HEX + 2), - "array length mismatch"); - -static const struct config_enum_entry xmloption_options[] = { - {"content", XMLOPTION_CONTENT, false}, - {"document", XMLOPTION_DOCUMENT, false}, - {NULL, 0, false} -}; - -StaticAssertDecl(lengthof(xmloption_options) == (XMLOPTION_CONTENT + 2), - "array length mismatch"); - -/* - * Although only "on", "off", and "safe_encoding" are documented, we - * accept all the likely variants of "on" and "off". - */ -static const struct config_enum_entry backslash_quote_options[] = { - {"safe_encoding", BACKSLASH_QUOTE_SAFE_ENCODING, false}, - {"on", BACKSLASH_QUOTE_ON, false}, - {"off", BACKSLASH_QUOTE_OFF, false}, - {"true", BACKSLASH_QUOTE_ON, true}, - {"false", BACKSLASH_QUOTE_OFF, true}, - {"yes", BACKSLASH_QUOTE_ON, true}, - {"no", BACKSLASH_QUOTE_OFF, true}, - {"1", BACKSLASH_QUOTE_ON, true}, - {"0", BACKSLASH_QUOTE_OFF, true}, - {NULL, 0, false} -}; - -/* - * Although only "on", "off", and "auto" are documented, we accept - * all the likely variants of "on" and "off". - */ -static const struct config_enum_entry compute_query_id_options[] = { - {"auto", COMPUTE_QUERY_ID_AUTO, false}, - {"regress", COMPUTE_QUERY_ID_REGRESS, false}, - {"on", COMPUTE_QUERY_ID_ON, false}, - {"off", COMPUTE_QUERY_ID_OFF, false}, - {"true", COMPUTE_QUERY_ID_ON, true}, - {"false", COMPUTE_QUERY_ID_OFF, true}, - {"yes", COMPUTE_QUERY_ID_ON, true}, - {"no", COMPUTE_QUERY_ID_OFF, true}, - {"1", COMPUTE_QUERY_ID_ON, true}, - {"0", COMPUTE_QUERY_ID_OFF, true}, - {NULL, 0, false} -}; - -/* - * Although only "on", "off", and "partition" are documented, we - * accept all the likely variants of "on" and "off". - */ -static const struct config_enum_entry constraint_exclusion_options[] = { - {"partition", CONSTRAINT_EXCLUSION_PARTITION, false}, - {"on", CONSTRAINT_EXCLUSION_ON, false}, - {"off", CONSTRAINT_EXCLUSION_OFF, false}, - {"true", CONSTRAINT_EXCLUSION_ON, true}, - {"false", CONSTRAINT_EXCLUSION_OFF, true}, - {"yes", CONSTRAINT_EXCLUSION_ON, true}, - {"no", CONSTRAINT_EXCLUSION_OFF, true}, - {"1", CONSTRAINT_EXCLUSION_ON, true}, - {"0", CONSTRAINT_EXCLUSION_OFF, true}, - {NULL, 0, false} -}; - -/* - * Although only "on", "off", "remote_apply", "remote_write", and "local" are - * documented, we accept all the likely variants of "on" and "off". - */ -static const struct config_enum_entry synchronous_commit_options[] = { - {"local", SYNCHRONOUS_COMMIT_LOCAL_FLUSH, false}, - {"remote_write", SYNCHRONOUS_COMMIT_REMOTE_WRITE, false}, - {"remote_apply", SYNCHRONOUS_COMMIT_REMOTE_APPLY, false}, - {"on", SYNCHRONOUS_COMMIT_ON, false}, - {"off", SYNCHRONOUS_COMMIT_OFF, false}, - {"true", SYNCHRONOUS_COMMIT_ON, true}, - {"false", SYNCHRONOUS_COMMIT_OFF, true}, - {"yes", SYNCHRONOUS_COMMIT_ON, true}, - {"no", SYNCHRONOUS_COMMIT_OFF, true}, - {"1", SYNCHRONOUS_COMMIT_ON, true}, - {"0", SYNCHRONOUS_COMMIT_OFF, true}, - {NULL, 0, false} -}; - -/* - * Although only "on", "off", "try" are documented, we accept all the likely - * variants of "on" and "off". - */ -static const struct config_enum_entry huge_pages_options[] = { - {"off", HUGE_PAGES_OFF, false}, - {"on", HUGE_PAGES_ON, false}, - {"try", HUGE_PAGES_TRY, false}, - {"true", HUGE_PAGES_ON, true}, - {"false", HUGE_PAGES_OFF, true}, - {"yes", HUGE_PAGES_ON, true}, - {"no", HUGE_PAGES_OFF, true}, - {"1", HUGE_PAGES_ON, true}, - {"0", HUGE_PAGES_OFF, true}, - {NULL, 0, false} -}; - -static const struct config_enum_entry recovery_prefetch_options[] = { - {"off", RECOVERY_PREFETCH_OFF, false}, - {"on", RECOVERY_PREFETCH_ON, false}, - {"try", RECOVERY_PREFETCH_TRY, false}, - {"true", RECOVERY_PREFETCH_ON, true}, - {"false", RECOVERY_PREFETCH_OFF, true}, - {"yes", RECOVERY_PREFETCH_ON, true}, - {"no", RECOVERY_PREFETCH_OFF, true}, - {"1", RECOVERY_PREFETCH_ON, true}, - {"0", RECOVERY_PREFETCH_OFF, true}, - {NULL, 0, false} -}; - -static const struct config_enum_entry force_parallel_mode_options[] = { - {"off", FORCE_PARALLEL_OFF, false}, - {"on", FORCE_PARALLEL_ON, false}, - {"regress", FORCE_PARALLEL_REGRESS, false}, - {"true", FORCE_PARALLEL_ON, true}, - {"false", FORCE_PARALLEL_OFF, true}, - {"yes", FORCE_PARALLEL_ON, true}, - {"no", FORCE_PARALLEL_OFF, true}, - {"1", FORCE_PARALLEL_ON, true}, - {"0", FORCE_PARALLEL_OFF, true}, - {NULL, 0, false} -}; - -static const struct config_enum_entry plan_cache_mode_options[] = { - {"auto", PLAN_CACHE_MODE_AUTO, false}, - {"force_generic_plan", PLAN_CACHE_MODE_FORCE_GENERIC_PLAN, false}, - {"force_custom_plan", PLAN_CACHE_MODE_FORCE_CUSTOM_PLAN, false}, - {NULL, 0, false} -}; - -static const struct config_enum_entry password_encryption_options[] = { - {"md5", PASSWORD_TYPE_MD5, false}, - {"scram-sha-256", PASSWORD_TYPE_SCRAM_SHA_256, false}, - {NULL, 0, false} -}; - -const struct config_enum_entry ssl_protocol_versions_info[] = { - {"", PG_TLS_ANY, false}, - {"TLSv1", PG_TLS1_VERSION, false}, - {"TLSv1.1", PG_TLS1_1_VERSION, false}, - {"TLSv1.2", PG_TLS1_2_VERSION, false}, - {"TLSv1.3", PG_TLS1_3_VERSION, false}, - {NULL, 0, false} -}; - -StaticAssertDecl(lengthof(ssl_protocol_versions_info) == (PG_TLS1_3_VERSION + 2), - "array length mismatch"); - -static struct config_enum_entry recovery_init_sync_method_options[] = { - {"fsync", RECOVERY_INIT_SYNC_METHOD_FSYNC, false}, -#ifdef HAVE_SYNCFS - {"syncfs", RECOVERY_INIT_SYNC_METHOD_SYNCFS, false}, -#endif - {NULL, 0, false} -}; - -static struct config_enum_entry shared_memory_options[] = { -#ifndef WIN32 - {"sysv", SHMEM_TYPE_SYSV, false}, -#endif -#ifndef EXEC_BACKEND - {"mmap", SHMEM_TYPE_MMAP, false}, -#endif -#ifdef WIN32 - {"windows", SHMEM_TYPE_WINDOWS, false}, -#endif - {NULL, 0, false} -}; - -static struct config_enum_entry default_toast_compression_options[] = { - {"pglz", TOAST_PGLZ_COMPRESSION, false}, -#ifdef USE_LZ4 - {"lz4", TOAST_LZ4_COMPRESSION, false}, -#endif - {NULL, 0, false} -}; - -static const struct config_enum_entry wal_compression_options[] = { - {"pglz", WAL_COMPRESSION_PGLZ, false}, -#ifdef USE_LZ4 - {"lz4", WAL_COMPRESSION_LZ4, false}, -#endif -#ifdef USE_ZSTD - {"zstd", WAL_COMPRESSION_ZSTD, false}, -#endif - {"on", WAL_COMPRESSION_PGLZ, false}, - {"off", WAL_COMPRESSION_NONE, false}, - {"true", WAL_COMPRESSION_PGLZ, true}, - {"false", WAL_COMPRESSION_NONE, true}, - {"yes", WAL_COMPRESSION_PGLZ, true}, - {"no", WAL_COMPRESSION_NONE, true}, - {"1", WAL_COMPRESSION_PGLZ, true}, - {"0", WAL_COMPRESSION_NONE, true}, - {NULL, 0, false} -}; - -/* - * Options for enum values stored in other modules - */ -extern const struct config_enum_entry wal_level_options[]; -extern const struct config_enum_entry archive_mode_options[]; -extern const struct config_enum_entry recovery_target_action_options[]; -extern const struct config_enum_entry sync_method_options[]; -extern const struct config_enum_entry dynamic_shared_memory_options[]; - -/* - * GUC option variables that are exported from this module - */ -bool log_duration = false; -bool Debug_print_plan = false; -bool Debug_print_parse = false; -bool Debug_print_rewritten = false; -bool Debug_pretty_print = true; - -bool log_parser_stats = false; -bool log_planner_stats = false; -bool log_executor_stats = false; -bool log_statement_stats = false; /* this is sort of all three above - * together */ -bool log_btree_build_stats = false; -char *event_source; - -bool row_security; -bool check_function_bodies = true; - -/* - * This GUC exists solely for backward compatibility, check its definition for - * details. - */ -bool default_with_oids = false; -bool session_auth_is_superuser; - -int log_min_error_statement = ERROR; -int log_min_messages = WARNING; -int client_min_messages = NOTICE; -int log_min_duration_sample = -1; -int log_min_duration_statement = -1; -int log_parameter_max_length = -1; -int log_parameter_max_length_on_error = 0; -int log_temp_files = -1; -double log_statement_sample_rate = 1.0; -double log_xact_sample_rate = 0; -int trace_recovery_messages = LOG; -char *backtrace_functions; -char *backtrace_symbol_list; - -int temp_file_limit = -1; - -int num_temp_buffers = 1024; - -char *cluster_name = ""; -char *ConfigFileName; -char *HbaFileName; -char *IdentFileName; -char *external_pid_file; - -char *pgstat_temp_directory; - -char *application_name; - -int tcp_keepalives_idle; -int tcp_keepalives_interval; -int tcp_keepalives_count; -int tcp_user_timeout; - -/* - * SSL renegotiation was been removed in PostgreSQL 9.5, but we tolerate it - * being set to zero (meaning never renegotiate) for backward compatibility. - * This avoids breaking compatibility with clients that have never supported - * renegotiation and therefore always try to zero it. - */ -int ssl_renegotiation_limit; - -/* - * This really belongs in pg_shmem.c, but is defined here so that it doesn't - * need to be duplicated in all the different implementations of pg_shmem.c. - */ -int huge_pages; -int huge_page_size; - -/* - * These variables are all dummies that don't do anything, except in some - * cases provide the value for SHOW to display. The real state is elsewhere - * and is kept in sync by assign_hooks. - */ -static char *syslog_ident_str; -static double phony_random_seed; -static char *client_encoding_string; -static char *datestyle_string; -static char *locale_collate; -static char *locale_ctype; -static char *server_encoding_string; -static char *server_version_string; -static int server_version_num; -static char *timezone_string; -static char *log_timezone_string; -static char *timezone_abbreviations_string; -static char *data_directory; -static char *session_authorization_string; -static int max_function_args; -static int max_index_keys; -static int max_identifier_length; -static int block_size; -static int segment_size; -static int shared_memory_size_mb; -static int shared_memory_size_in_huge_pages; -static int wal_block_size; -static bool data_checksums; -static bool integer_datetimes; -static bool assert_enabled; -static bool in_hot_standby; -static char *recovery_target_timeline_string; -static char *recovery_target_string; -static char *recovery_target_xid_string; -static char *recovery_target_name_string; -static char *recovery_target_lsn_string; - - -/* should be static, but commands/variable.c needs to get at this */ -char *role_string; - - -/* - * Displayable names for context types (enum GucContext) - * - * Note: these strings are deliberately not localized. - */ -const char *const GucContext_Names[] = -{ - /* PGC_INTERNAL */ "internal", - /* PGC_POSTMASTER */ "postmaster", - /* PGC_SIGHUP */ "sighup", - /* PGC_SU_BACKEND */ "superuser-backend", - /* PGC_BACKEND */ "backend", - /* PGC_SUSET */ "superuser", - /* PGC_USERSET */ "user" -}; - -StaticAssertDecl(lengthof(GucContext_Names) == (PGC_USERSET + 1), - "array length mismatch"); - -/* - * Displayable names for source types (enum GucSource) - * - * Note: these strings are deliberately not localized. - */ -const char *const GucSource_Names[] = -{ - /* PGC_S_DEFAULT */ "default", - /* PGC_S_DYNAMIC_DEFAULT */ "default", - /* PGC_S_ENV_VAR */ "environment variable", - /* PGC_S_FILE */ "configuration file", - /* PGC_S_ARGV */ "command line", - /* PGC_S_GLOBAL */ "global", - /* PGC_S_DATABASE */ "database", - /* PGC_S_USER */ "user", - /* PGC_S_DATABASE_USER */ "database user", - /* PGC_S_CLIENT */ "client", - /* PGC_S_OVERRIDE */ "override", - /* PGC_S_INTERACTIVE */ "interactive", - /* PGC_S_TEST */ "test", - /* PGC_S_SESSION */ "session" -}; - -StaticAssertDecl(lengthof(GucSource_Names) == (PGC_S_SESSION + 1), - "array length mismatch"); - -/* - * Displayable names for the groupings defined in enum config_group - */ -const char *const config_group_names[] = -{ - /* UNGROUPED */ - gettext_noop("Ungrouped"), - /* FILE_LOCATIONS */ - gettext_noop("File Locations"), - /* CONN_AUTH_SETTINGS */ - gettext_noop("Connections and Authentication / Connection Settings"), - /* CONN_AUTH_TCP */ - gettext_noop("Connections and Authentication / TCP Settings"), - /* CONN_AUTH_AUTH */ - gettext_noop("Connections and Authentication / Authentication"), - /* CONN_AUTH_SSL */ - gettext_noop("Connections and Authentication / SSL"), - /* RESOURCES_MEM */ - gettext_noop("Resource Usage / Memory"), - /* RESOURCES_DISK */ - gettext_noop("Resource Usage / Disk"), - /* RESOURCES_KERNEL */ - gettext_noop("Resource Usage / Kernel Resources"), - /* RESOURCES_VACUUM_DELAY */ - gettext_noop("Resource Usage / Cost-Based Vacuum Delay"), - /* RESOURCES_BGWRITER */ - gettext_noop("Resource Usage / Background Writer"), - /* RESOURCES_ASYNCHRONOUS */ - gettext_noop("Resource Usage / Asynchronous Behavior"), - /* WAL_SETTINGS */ - gettext_noop("Write-Ahead Log / Settings"), - /* WAL_CHECKPOINTS */ - gettext_noop("Write-Ahead Log / Checkpoints"), - /* WAL_ARCHIVING */ - gettext_noop("Write-Ahead Log / Archiving"), - /* WAL_RECOVERY */ - gettext_noop("Write-Ahead Log / Recovery"), - /* WAL_ARCHIVE_RECOVERY */ - gettext_noop("Write-Ahead Log / Archive Recovery"), - /* WAL_RECOVERY_TARGET */ - gettext_noop("Write-Ahead Log / Recovery Target"), - /* REPLICATION_SENDING */ - gettext_noop("Replication / Sending Servers"), - /* REPLICATION_PRIMARY */ - gettext_noop("Replication / Primary Server"), - /* REPLICATION_STANDBY */ - gettext_noop("Replication / Standby Servers"), - /* REPLICATION_SUBSCRIBERS */ - gettext_noop("Replication / Subscribers"), - /* QUERY_TUNING_METHOD */ - gettext_noop("Query Tuning / Planner Method Configuration"), - /* QUERY_TUNING_COST */ - gettext_noop("Query Tuning / Planner Cost Constants"), - /* QUERY_TUNING_GEQO */ - gettext_noop("Query Tuning / Genetic Query Optimizer"), - /* QUERY_TUNING_OTHER */ - gettext_noop("Query Tuning / Other Planner Options"), - /* LOGGING_WHERE */ - gettext_noop("Reporting and Logging / Where to Log"), - /* LOGGING_WHEN */ - gettext_noop("Reporting and Logging / When to Log"), - /* LOGGING_WHAT */ - gettext_noop("Reporting and Logging / What to Log"), - /* PROCESS_TITLE */ - gettext_noop("Reporting and Logging / Process Title"), - /* STATS_MONITORING */ - gettext_noop("Statistics / Monitoring"), - /* STATS_CUMULATIVE */ - gettext_noop("Statistics / Cumulative Query and Index Statistics"), - /* AUTOVACUUM */ - gettext_noop("Autovacuum"), - /* CLIENT_CONN_STATEMENT */ - gettext_noop("Client Connection Defaults / Statement Behavior"), - /* CLIENT_CONN_LOCALE */ - gettext_noop("Client Connection Defaults / Locale and Formatting"), - /* CLIENT_CONN_PRELOAD */ - gettext_noop("Client Connection Defaults / Shared Library Preloading"), - /* CLIENT_CONN_OTHER */ - gettext_noop("Client Connection Defaults / Other Defaults"), - /* LOCK_MANAGEMENT */ - gettext_noop("Lock Management"), - /* COMPAT_OPTIONS_PREVIOUS */ - gettext_noop("Version and Platform Compatibility / Previous PostgreSQL Versions"), - /* COMPAT_OPTIONS_CLIENT */ - gettext_noop("Version and Platform Compatibility / Other Platforms and Clients"), - /* ERROR_HANDLING */ - gettext_noop("Error Handling"), - /* PRESET_OPTIONS */ - gettext_noop("Preset Options"), - /* CUSTOM_OPTIONS */ - gettext_noop("Customized Options"), - /* DEVELOPER_OPTIONS */ - gettext_noop("Developer Options"), - /* help_config wants this array to be null-terminated */ - NULL -}; - -StaticAssertDecl(lengthof(config_group_names) == (DEVELOPER_OPTIONS + 2), - "array length mismatch"); - -/* - * Displayable names for GUC variable types (enum config_type) - * - * Note: these strings are deliberately not localized. - */ -const char *const config_type_names[] = -{ - /* PGC_BOOL */ "bool", - /* PGC_INT */ "integer", - /* PGC_REAL */ "real", - /* PGC_STRING */ "string", - /* PGC_ENUM */ "enum" -}; - -StaticAssertDecl(lengthof(config_type_names) == (PGC_ENUM + 1), - "array length mismatch"); /* * Unit conversion tables. @@ -979,4150 +175,6 @@ static const unit_conversion time_unit_conversion_table[] = {""} /* end of table marker */ }; -/* - * Contents of GUC tables - * - * See src/backend/utils/misc/README for design notes. - * - * TO ADD AN OPTION: - * - * 1. Declare a global variable of type bool, int, double, or char* - * and make use of it. - * - * 2. Decide at what times it's safe to set the option. See guc.h for - * details. - * - * 3. Decide on a name, a default value, upper and lower bounds (if - * applicable), etc. - * - * 4. Add a record below. - * - * 5. Add it to src/backend/utils/misc/postgresql.conf.sample, if - * appropriate. - * - * 6. Don't forget to document the option (at least in config.sgml). - * - * 7. If it's a new GUC_LIST_QUOTE option, you must add it to - * variable_is_guc_list_quote() in src/bin/pg_dump/dumputils.c. - */ - - -/******** option records follow ********/ - -static struct config_bool ConfigureNamesBool[] = -{ - { - {"enable_seqscan", PGC_USERSET, QUERY_TUNING_METHOD, - gettext_noop("Enables the planner's use of sequential-scan plans."), - NULL, - GUC_EXPLAIN - }, - &enable_seqscan, - true, - NULL, NULL, NULL - }, - { - {"enable_indexscan", PGC_USERSET, QUERY_TUNING_METHOD, - gettext_noop("Enables the planner's use of index-scan plans."), - NULL, - GUC_EXPLAIN - }, - &enable_indexscan, - true, - NULL, NULL, NULL - }, - { - {"enable_indexonlyscan", PGC_USERSET, QUERY_TUNING_METHOD, - gettext_noop("Enables the planner's use of index-only-scan plans."), - NULL, - GUC_EXPLAIN - }, - &enable_indexonlyscan, - true, - NULL, NULL, NULL - }, - { - {"enable_bitmapscan", PGC_USERSET, QUERY_TUNING_METHOD, - gettext_noop("Enables the planner's use of bitmap-scan plans."), - NULL, - GUC_EXPLAIN - }, - &enable_bitmapscan, - true, - NULL, NULL, NULL - }, - { - {"enable_tidscan", PGC_USERSET, QUERY_TUNING_METHOD, - gettext_noop("Enables the planner's use of TID scan plans."), - NULL, - GUC_EXPLAIN - }, - &enable_tidscan, - true, - NULL, NULL, NULL - }, - { - {"enable_sort", PGC_USERSET, QUERY_TUNING_METHOD, - gettext_noop("Enables the planner's use of explicit sort steps."), - NULL, - GUC_EXPLAIN - }, - &enable_sort, - true, - NULL, NULL, NULL - }, - { - {"enable_incremental_sort", PGC_USERSET, QUERY_TUNING_METHOD, - gettext_noop("Enables the planner's use of incremental sort steps."), - NULL, - GUC_EXPLAIN - }, - &enable_incremental_sort, - true, - NULL, NULL, NULL - }, - { - {"enable_hashagg", PGC_USERSET, QUERY_TUNING_METHOD, - gettext_noop("Enables the planner's use of hashed aggregation plans."), - NULL, - GUC_EXPLAIN - }, - &enable_hashagg, - true, - NULL, NULL, NULL - }, - { - {"enable_material", PGC_USERSET, QUERY_TUNING_METHOD, - gettext_noop("Enables the planner's use of materialization."), - NULL, - GUC_EXPLAIN - }, - &enable_material, - true, - NULL, NULL, NULL - }, - { - {"enable_memoize", PGC_USERSET, QUERY_TUNING_METHOD, - gettext_noop("Enables the planner's use of memoization."), - NULL, - GUC_EXPLAIN - }, - &enable_memoize, - true, - NULL, NULL, NULL - }, - { - {"enable_nestloop", PGC_USERSET, QUERY_TUNING_METHOD, - gettext_noop("Enables the planner's use of nested-loop join plans."), - NULL, - GUC_EXPLAIN - }, - &enable_nestloop, - true, - NULL, NULL, NULL - }, - { - {"enable_mergejoin", PGC_USERSET, QUERY_TUNING_METHOD, - gettext_noop("Enables the planner's use of merge join plans."), - NULL, - GUC_EXPLAIN - }, - &enable_mergejoin, - true, - NULL, NULL, NULL - }, - { - {"enable_hashjoin", PGC_USERSET, QUERY_TUNING_METHOD, - gettext_noop("Enables the planner's use of hash join plans."), - NULL, - GUC_EXPLAIN - }, - &enable_hashjoin, - true, - NULL, NULL, NULL - }, - { - {"enable_gathermerge", PGC_USERSET, QUERY_TUNING_METHOD, - gettext_noop("Enables the planner's use of gather merge plans."), - NULL, - GUC_EXPLAIN - }, - &enable_gathermerge, - true, - NULL, NULL, NULL - }, - { - {"enable_partitionwise_join", PGC_USERSET, QUERY_TUNING_METHOD, - gettext_noop("Enables partitionwise join."), - NULL, - GUC_EXPLAIN - }, - &enable_partitionwise_join, - false, - NULL, NULL, NULL - }, - { - {"enable_partitionwise_aggregate", PGC_USERSET, QUERY_TUNING_METHOD, - gettext_noop("Enables partitionwise aggregation and grouping."), - NULL, - GUC_EXPLAIN - }, - &enable_partitionwise_aggregate, - false, - NULL, NULL, NULL - }, - { - {"enable_parallel_append", PGC_USERSET, QUERY_TUNING_METHOD, - gettext_noop("Enables the planner's use of parallel append plans."), - NULL, - GUC_EXPLAIN - }, - &enable_parallel_append, - true, - NULL, NULL, NULL - }, - { - {"enable_parallel_hash", PGC_USERSET, QUERY_TUNING_METHOD, - gettext_noop("Enables the planner's use of parallel hash plans."), - NULL, - GUC_EXPLAIN - }, - &enable_parallel_hash, - true, - NULL, NULL, NULL - }, - { - {"enable_partition_pruning", PGC_USERSET, QUERY_TUNING_METHOD, - gettext_noop("Enables plan-time and execution-time partition pruning."), - gettext_noop("Allows the query planner and executor to compare partition " - "bounds to conditions in the query to determine which " - "partitions must be scanned."), - GUC_EXPLAIN - }, - &enable_partition_pruning, - true, - NULL, NULL, NULL - }, - { - {"enable_async_append", PGC_USERSET, QUERY_TUNING_METHOD, - gettext_noop("Enables the planner's use of async append plans."), - NULL, - GUC_EXPLAIN - }, - &enable_async_append, - true, - NULL, NULL, NULL - }, - { - {"enable_group_by_reordering", PGC_USERSET, QUERY_TUNING_METHOD, - gettext_noop("Enable reordering of GROUP BY key."), - NULL, - GUC_EXPLAIN - }, - &enable_group_by_reordering, - true, - NULL, NULL, NULL - }, - { - {"geqo", PGC_USERSET, QUERY_TUNING_GEQO, - gettext_noop("Enables genetic query optimization."), - gettext_noop("This algorithm attempts to do planning without " - "exhaustive searching."), - GUC_EXPLAIN - }, - &enable_geqo, - true, - NULL, NULL, NULL - }, - { - /* Not for general use --- used by SET SESSION AUTHORIZATION */ - {"is_superuser", PGC_INTERNAL, UNGROUPED, - gettext_noop("Shows whether the current user is a superuser."), - NULL, - GUC_REPORT | GUC_NO_SHOW_ALL | GUC_NO_RESET_ALL | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE - }, - &session_auth_is_superuser, - false, - NULL, NULL, NULL - }, - { - {"bonjour", PGC_POSTMASTER, CONN_AUTH_SETTINGS, - gettext_noop("Enables advertising the server via Bonjour."), - NULL - }, - &enable_bonjour, - false, - check_bonjour, NULL, NULL - }, - { - {"track_commit_timestamp", PGC_POSTMASTER, REPLICATION_SENDING, - gettext_noop("Collects transaction commit time."), - NULL - }, - &track_commit_timestamp, - false, - NULL, NULL, NULL - }, - { - {"ssl", PGC_SIGHUP, CONN_AUTH_SSL, - gettext_noop("Enables SSL connections."), - NULL - }, - &EnableSSL, - false, - check_ssl, NULL, NULL - }, - { - {"ssl_passphrase_command_supports_reload", PGC_SIGHUP, CONN_AUTH_SSL, - gettext_noop("Controls whether ssl_passphrase_command is called during server reload."), - NULL - }, - &ssl_passphrase_command_supports_reload, - false, - NULL, NULL, NULL - }, - { - {"ssl_prefer_server_ciphers", PGC_SIGHUP, CONN_AUTH_SSL, - gettext_noop("Give priority to server ciphersuite order."), - NULL - }, - &SSLPreferServerCiphers, - true, - NULL, NULL, NULL - }, - { - {"fsync", PGC_SIGHUP, WAL_SETTINGS, - gettext_noop("Forces synchronization of updates to disk."), - gettext_noop("The server will use the fsync() system call in several places to make " - "sure that updates are physically written to disk. This insures " - "that a database cluster will recover to a consistent state after " - "an operating system or hardware crash.") - }, - &enableFsync, - true, - NULL, NULL, NULL - }, - { - {"ignore_checksum_failure", PGC_SUSET, DEVELOPER_OPTIONS, - gettext_noop("Continues processing after a checksum failure."), - gettext_noop("Detection of a checksum failure normally causes PostgreSQL to " - "report an error, aborting the current transaction. Setting " - "ignore_checksum_failure to true causes the system to ignore the failure " - "(but still report a warning), and continue processing. This " - "behavior could cause crashes or other serious problems. Only " - "has an effect if checksums are enabled."), - GUC_NOT_IN_SAMPLE - }, - &ignore_checksum_failure, - false, - NULL, NULL, NULL - }, - { - {"zero_damaged_pages", PGC_SUSET, DEVELOPER_OPTIONS, - gettext_noop("Continues processing past damaged page headers."), - gettext_noop("Detection of a damaged page header normally causes PostgreSQL to " - "report an error, aborting the current transaction. Setting " - "zero_damaged_pages to true causes the system to instead report a " - "warning, zero out the damaged page, and continue processing. This " - "behavior will destroy data, namely all the rows on the damaged page."), - GUC_NOT_IN_SAMPLE - }, - &zero_damaged_pages, - false, - NULL, NULL, NULL - }, - { - {"ignore_invalid_pages", PGC_POSTMASTER, DEVELOPER_OPTIONS, - gettext_noop("Continues recovery after an invalid pages failure."), - gettext_noop("Detection of WAL records having references to " - "invalid pages during recovery causes PostgreSQL to " - "raise a PANIC-level error, aborting the recovery. " - "Setting ignore_invalid_pages to true causes " - "the system to ignore invalid page references " - "in WAL records (but still report a warning), " - "and continue recovery. This behavior may cause " - "crashes, data loss, propagate or hide corruption, " - "or other serious problems. Only has an effect " - "during recovery or in standby mode."), - GUC_NOT_IN_SAMPLE - }, - &ignore_invalid_pages, - false, - NULL, NULL, NULL - }, - { - {"full_page_writes", PGC_SIGHUP, WAL_SETTINGS, - gettext_noop("Writes full pages to WAL when first modified after a checkpoint."), - gettext_noop("A page write in process during an operating system crash might be " - "only partially written to disk. During recovery, the row changes " - "stored in WAL are not enough to recover. This option writes " - "pages when first modified after a checkpoint to WAL so full recovery " - "is possible.") - }, - &fullPageWrites, - true, - NULL, NULL, NULL - }, - - { - {"wal_log_hints", PGC_POSTMASTER, WAL_SETTINGS, - gettext_noop("Writes full pages to WAL when first modified after a checkpoint, even for a non-critical modification."), - NULL - }, - &wal_log_hints, - false, - NULL, NULL, NULL - }, - - { - {"wal_init_zero", PGC_SUSET, WAL_SETTINGS, - gettext_noop("Writes zeroes to new WAL files before first use."), - NULL - }, - &wal_init_zero, - true, - NULL, NULL, NULL - }, - - { - {"wal_recycle", PGC_SUSET, WAL_SETTINGS, - gettext_noop("Recycles WAL files by renaming them."), - NULL - }, - &wal_recycle, - true, - NULL, NULL, NULL - }, - - { - {"log_checkpoints", PGC_SIGHUP, LOGGING_WHAT, - gettext_noop("Logs each checkpoint."), - NULL - }, - &log_checkpoints, - true, - NULL, NULL, NULL - }, - { - {"log_connections", PGC_SU_BACKEND, LOGGING_WHAT, - gettext_noop("Logs each successful connection."), - NULL - }, - &Log_connections, - false, - NULL, NULL, NULL - }, - { - {"log_disconnections", PGC_SU_BACKEND, LOGGING_WHAT, - gettext_noop("Logs end of a session, including duration."), - NULL - }, - &Log_disconnections, - false, - NULL, NULL, NULL - }, - { - {"log_replication_commands", PGC_SUSET, LOGGING_WHAT, - gettext_noop("Logs each replication command."), - NULL - }, - &log_replication_commands, - false, - NULL, NULL, NULL - }, - { - {"debug_assertions", PGC_INTERNAL, PRESET_OPTIONS, - gettext_noop("Shows whether the running server has assertion checks enabled."), - NULL, - GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE - }, - &assert_enabled, -#ifdef USE_ASSERT_CHECKING - true, -#else - false, -#endif - NULL, NULL, NULL - }, - - { - {"exit_on_error", PGC_USERSET, ERROR_HANDLING_OPTIONS, - gettext_noop("Terminate session on any error."), - NULL - }, - &ExitOnAnyError, - false, - NULL, NULL, NULL - }, - { - {"restart_after_crash", PGC_SIGHUP, ERROR_HANDLING_OPTIONS, - gettext_noop("Reinitialize server after backend crash."), - NULL - }, - &restart_after_crash, - true, - NULL, NULL, NULL - }, - { - {"remove_temp_files_after_crash", PGC_SIGHUP, DEVELOPER_OPTIONS, - gettext_noop("Remove temporary files after backend crash."), - NULL, - GUC_NOT_IN_SAMPLE - }, - &remove_temp_files_after_crash, - true, - NULL, NULL, NULL - }, - - { - {"log_duration", PGC_SUSET, LOGGING_WHAT, - gettext_noop("Logs the duration of each completed SQL statement."), - NULL - }, - &log_duration, - false, - NULL, NULL, NULL - }, - { - {"debug_print_parse", PGC_USERSET, LOGGING_WHAT, - gettext_noop("Logs each query's parse tree."), - NULL - }, - &Debug_print_parse, - false, - NULL, NULL, NULL - }, - { - {"debug_print_rewritten", PGC_USERSET, LOGGING_WHAT, - gettext_noop("Logs each query's rewritten parse tree."), - NULL - }, - &Debug_print_rewritten, - false, - NULL, NULL, NULL - }, - { - {"debug_print_plan", PGC_USERSET, LOGGING_WHAT, - gettext_noop("Logs each query's execution plan."), - NULL - }, - &Debug_print_plan, - false, - NULL, NULL, NULL - }, - { - {"debug_pretty_print", PGC_USERSET, LOGGING_WHAT, - gettext_noop("Indents parse and plan tree displays."), - NULL - }, - &Debug_pretty_print, - true, - NULL, NULL, NULL - }, - { - {"log_parser_stats", PGC_SUSET, STATS_MONITORING, - gettext_noop("Writes parser performance statistics to the server log."), - NULL - }, - &log_parser_stats, - false, - check_stage_log_stats, NULL, NULL - }, - { - {"log_planner_stats", PGC_SUSET, STATS_MONITORING, - gettext_noop("Writes planner performance statistics to the server log."), - NULL - }, - &log_planner_stats, - false, - check_stage_log_stats, NULL, NULL - }, - { - {"log_executor_stats", PGC_SUSET, STATS_MONITORING, - gettext_noop("Writes executor performance statistics to the server log."), - NULL - }, - &log_executor_stats, - false, - check_stage_log_stats, NULL, NULL - }, - { - {"log_statement_stats", PGC_SUSET, STATS_MONITORING, - gettext_noop("Writes cumulative performance statistics to the server log."), - NULL - }, - &log_statement_stats, - false, - check_log_stats, NULL, NULL - }, -#ifdef BTREE_BUILD_STATS - { - {"log_btree_build_stats", PGC_SUSET, DEVELOPER_OPTIONS, - gettext_noop("Logs system resource usage statistics (memory and CPU) on various B-tree operations."), - NULL, - GUC_NOT_IN_SAMPLE - }, - &log_btree_build_stats, - false, - NULL, NULL, NULL - }, -#endif - - { - {"track_activities", PGC_SUSET, STATS_CUMULATIVE, - gettext_noop("Collects information about executing commands."), - gettext_noop("Enables the collection of information on the currently " - "executing command of each session, along with " - "the time at which that command began execution.") - }, - &pgstat_track_activities, - true, - NULL, NULL, NULL - }, - { - {"track_counts", PGC_SUSET, STATS_CUMULATIVE, - gettext_noop("Collects statistics on database activity."), - NULL - }, - &pgstat_track_counts, - true, - NULL, NULL, NULL - }, - { - {"track_io_timing", PGC_SUSET, STATS_CUMULATIVE, - gettext_noop("Collects timing statistics for database I/O activity."), - NULL - }, - &track_io_timing, - false, - NULL, NULL, NULL - }, - { - {"track_wal_io_timing", PGC_SUSET, STATS_CUMULATIVE, - gettext_noop("Collects timing statistics for WAL I/O activity."), - NULL - }, - &track_wal_io_timing, - false, - NULL, NULL, NULL - }, - - { - {"update_process_title", PGC_SUSET, PROCESS_TITLE, - gettext_noop("Updates the process title to show the active SQL command."), - gettext_noop("Enables updating of the process title every time a new SQL command is received by the server.") - }, - &update_process_title, -#ifdef WIN32 - false, -#else - true, -#endif - NULL, NULL, NULL - }, - - { - {"autovacuum", PGC_SIGHUP, AUTOVACUUM, - gettext_noop("Starts the autovacuum subprocess."), - NULL - }, - &autovacuum_start_daemon, - true, - NULL, NULL, NULL - }, - - { - {"trace_notify", PGC_USERSET, DEVELOPER_OPTIONS, - gettext_noop("Generates debugging output for LISTEN and NOTIFY."), - NULL, - GUC_NOT_IN_SAMPLE - }, - &Trace_notify, - false, - NULL, NULL, NULL - }, - -#ifdef LOCK_DEBUG - { - {"trace_locks", PGC_SUSET, DEVELOPER_OPTIONS, - gettext_noop("Emits information about lock usage."), - NULL, - GUC_NOT_IN_SAMPLE - }, - &Trace_locks, - false, - NULL, NULL, NULL - }, - { - {"trace_userlocks", PGC_SUSET, DEVELOPER_OPTIONS, - gettext_noop("Emits information about user lock usage."), - NULL, - GUC_NOT_IN_SAMPLE - }, - &Trace_userlocks, - false, - NULL, NULL, NULL - }, - { - {"trace_lwlocks", PGC_SUSET, DEVELOPER_OPTIONS, - gettext_noop("Emits information about lightweight lock usage."), - NULL, - GUC_NOT_IN_SAMPLE - }, - &Trace_lwlocks, - false, - NULL, NULL, NULL - }, - { - {"debug_deadlocks", PGC_SUSET, DEVELOPER_OPTIONS, - gettext_noop("Dumps information about all current locks when a deadlock timeout occurs."), - NULL, - GUC_NOT_IN_SAMPLE - }, - &Debug_deadlocks, - false, - NULL, NULL, NULL - }, -#endif - - { - {"log_lock_waits", PGC_SUSET, LOGGING_WHAT, - gettext_noop("Logs long lock waits."), - NULL - }, - &log_lock_waits, - false, - NULL, NULL, NULL - }, - { - {"log_recovery_conflict_waits", PGC_SIGHUP, LOGGING_WHAT, - gettext_noop("Logs standby recovery conflict waits."), - NULL - }, - &log_recovery_conflict_waits, - false, - NULL, NULL, NULL - }, - { - {"log_hostname", PGC_SIGHUP, LOGGING_WHAT, - gettext_noop("Logs the host name in the connection logs."), - gettext_noop("By default, connection logs only show the IP address " - "of the connecting host. If you want them to show the host name you " - "can turn this on, but depending on your host name resolution " - "setup it might impose a non-negligible performance penalty.") - }, - &log_hostname, - false, - NULL, NULL, NULL - }, - { - {"transform_null_equals", PGC_USERSET, COMPAT_OPTIONS_CLIENT, - gettext_noop("Treats \"expr=NULL\" as \"expr IS NULL\"."), - gettext_noop("When turned on, expressions of the form expr = NULL " - "(or NULL = expr) are treated as expr IS NULL, that is, they " - "return true if expr evaluates to the null value, and false " - "otherwise. The correct behavior of expr = NULL is to always " - "return null (unknown).") - }, - &Transform_null_equals, - false, - NULL, NULL, NULL - }, - { - {"db_user_namespace", PGC_SIGHUP, CONN_AUTH_AUTH, - gettext_noop("Enables per-database user names."), - NULL - }, - &Db_user_namespace, - false, - NULL, NULL, NULL - }, - { - {"default_transaction_read_only", PGC_USERSET, CLIENT_CONN_STATEMENT, - gettext_noop("Sets the default read-only status of new transactions."), - NULL, - GUC_REPORT - }, - &DefaultXactReadOnly, - false, - NULL, NULL, NULL - }, - { - {"transaction_read_only", PGC_USERSET, CLIENT_CONN_STATEMENT, - gettext_noop("Sets the current transaction's read-only status."), - NULL, - GUC_NO_RESET_ALL | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE - }, - &XactReadOnly, - false, - check_transaction_read_only, NULL, NULL - }, - { - {"default_transaction_deferrable", PGC_USERSET, CLIENT_CONN_STATEMENT, - gettext_noop("Sets the default deferrable status of new transactions."), - NULL - }, - &DefaultXactDeferrable, - false, - NULL, NULL, NULL - }, - { - {"transaction_deferrable", PGC_USERSET, CLIENT_CONN_STATEMENT, - gettext_noop("Whether to defer a read-only serializable transaction until it can be executed with no possible serialization failures."), - NULL, - GUC_NO_RESET_ALL | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE - }, - &XactDeferrable, - false, - check_transaction_deferrable, NULL, NULL - }, - { - {"row_security", PGC_USERSET, CLIENT_CONN_STATEMENT, - gettext_noop("Enable row security."), - gettext_noop("When enabled, row security will be applied to all users.") - }, - &row_security, - true, - NULL, NULL, NULL - }, - { - {"check_function_bodies", PGC_USERSET, CLIENT_CONN_STATEMENT, - gettext_noop("Check routine bodies during CREATE FUNCTION and CREATE PROCEDURE."), - NULL - }, - &check_function_bodies, - true, - NULL, NULL, NULL - }, - { - {"array_nulls", PGC_USERSET, COMPAT_OPTIONS_PREVIOUS, - gettext_noop("Enable input of NULL elements in arrays."), - gettext_noop("When turned on, unquoted NULL in an array input " - "value means a null value; " - "otherwise it is taken literally.") - }, - &Array_nulls, - true, - NULL, NULL, NULL - }, - - /* - * WITH OIDS support, and consequently default_with_oids, was removed in - * PostgreSQL 12, but we tolerate the parameter being set to false to - * avoid unnecessarily breaking older dump files. - */ - { - {"default_with_oids", PGC_USERSET, COMPAT_OPTIONS_PREVIOUS, - gettext_noop("WITH OIDS is no longer supported; this can only be false."), - NULL, - GUC_NO_SHOW_ALL | GUC_NOT_IN_SAMPLE - }, - &default_with_oids, - false, - check_default_with_oids, NULL, NULL - }, - { - {"logging_collector", PGC_POSTMASTER, LOGGING_WHERE, - gettext_noop("Start a subprocess to capture stderr output and/or csvlogs into log files."), - NULL - }, - &Logging_collector, - false, - NULL, NULL, NULL - }, - { - {"log_truncate_on_rotation", PGC_SIGHUP, LOGGING_WHERE, - gettext_noop("Truncate existing log files of same name during log rotation."), - NULL - }, - &Log_truncate_on_rotation, - false, - NULL, NULL, NULL - }, - -#ifdef TRACE_SORT - { - {"trace_sort", PGC_USERSET, DEVELOPER_OPTIONS, - gettext_noop("Emit information about resource usage in sorting."), - NULL, - GUC_NOT_IN_SAMPLE - }, - &trace_sort, - false, - NULL, NULL, NULL - }, -#endif - -#ifdef TRACE_SYNCSCAN - /* this is undocumented because not exposed in a standard build */ - { - {"trace_syncscan", PGC_USERSET, DEVELOPER_OPTIONS, - gettext_noop("Generate debugging output for synchronized scanning."), - NULL, - GUC_NOT_IN_SAMPLE - }, - &trace_syncscan, - false, - NULL, NULL, NULL - }, -#endif - -#ifdef DEBUG_BOUNDED_SORT - /* this is undocumented because not exposed in a standard build */ - { - { - "optimize_bounded_sort", PGC_USERSET, QUERY_TUNING_METHOD, - gettext_noop("Enable bounded sorting using heap sort."), - NULL, - GUC_NOT_IN_SAMPLE | GUC_EXPLAIN - }, - &optimize_bounded_sort, - true, - NULL, NULL, NULL - }, -#endif - -#ifdef WAL_DEBUG - { - {"wal_debug", PGC_SUSET, DEVELOPER_OPTIONS, - gettext_noop("Emit WAL-related debugging output."), - NULL, - GUC_NOT_IN_SAMPLE - }, - &XLOG_DEBUG, - false, - NULL, NULL, NULL - }, -#endif - - { - {"integer_datetimes", PGC_INTERNAL, PRESET_OPTIONS, - gettext_noop("Shows whether datetimes are integer based."), - NULL, - GUC_REPORT | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE - }, - &integer_datetimes, - true, - NULL, NULL, NULL - }, - - { - {"krb_caseins_users", PGC_SIGHUP, CONN_AUTH_AUTH, - gettext_noop("Sets whether Kerberos and GSSAPI user names should be treated as case-insensitive."), - NULL - }, - &pg_krb_caseins_users, - false, - NULL, NULL, NULL - }, - - { - {"escape_string_warning", PGC_USERSET, COMPAT_OPTIONS_PREVIOUS, - gettext_noop("Warn about backslash escapes in ordinary string literals."), - NULL - }, - &escape_string_warning, - true, - NULL, NULL, NULL - }, - - { - {"standard_conforming_strings", PGC_USERSET, COMPAT_OPTIONS_PREVIOUS, - gettext_noop("Causes '...' strings to treat backslashes literally."), - NULL, - GUC_REPORT - }, - &standard_conforming_strings, - true, - NULL, NULL, NULL - }, - - { - {"synchronize_seqscans", PGC_USERSET, COMPAT_OPTIONS_PREVIOUS, - gettext_noop("Enable synchronized sequential scans."), - NULL - }, - &synchronize_seqscans, - true, - NULL, NULL, NULL - }, - - { - {"recovery_target_inclusive", PGC_POSTMASTER, WAL_RECOVERY_TARGET, - gettext_noop("Sets whether to include or exclude transaction with recovery target."), - NULL - }, - &recoveryTargetInclusive, - true, - NULL, NULL, NULL - }, - - { - {"hot_standby", PGC_POSTMASTER, REPLICATION_STANDBY, - gettext_noop("Allows connections and queries during recovery."), - NULL - }, - &EnableHotStandby, - true, - NULL, NULL, NULL - }, - - { - {"hot_standby_feedback", PGC_SIGHUP, REPLICATION_STANDBY, - gettext_noop("Allows feedback from a hot standby to the primary that will avoid query conflicts."), - NULL - }, - &hot_standby_feedback, - false, - NULL, NULL, NULL - }, - - { - {"in_hot_standby", PGC_INTERNAL, PRESET_OPTIONS, - gettext_noop("Shows whether hot standby is currently active."), - NULL, - GUC_REPORT | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE - }, - &in_hot_standby, - false, - NULL, NULL, show_in_hot_standby - }, - - { - {"allow_system_table_mods", PGC_SUSET, DEVELOPER_OPTIONS, - gettext_noop("Allows modifications of the structure of system tables."), - NULL, - GUC_NOT_IN_SAMPLE - }, - &allowSystemTableMods, - false, - NULL, NULL, NULL - }, - - { - {"ignore_system_indexes", PGC_BACKEND, DEVELOPER_OPTIONS, - gettext_noop("Disables reading from system indexes."), - gettext_noop("It does not prevent updating the indexes, so it is safe " - "to use. The worst consequence is slowness."), - GUC_NOT_IN_SAMPLE - }, - &IgnoreSystemIndexes, - false, - NULL, NULL, NULL - }, - - { - {"allow_in_place_tablespaces", PGC_SUSET, DEVELOPER_OPTIONS, - gettext_noop("Allows tablespaces directly inside pg_tblspc, for testing."), - NULL, - GUC_NOT_IN_SAMPLE - }, - &allow_in_place_tablespaces, - false, - NULL, NULL, NULL - }, - - { - {"lo_compat_privileges", PGC_SUSET, COMPAT_OPTIONS_PREVIOUS, - gettext_noop("Enables backward compatibility mode for privilege checks on large objects."), - gettext_noop("Skips privilege checks when reading or modifying large objects, " - "for compatibility with PostgreSQL releases prior to 9.0.") - }, - &lo_compat_privileges, - false, - NULL, NULL, NULL - }, - - { - {"quote_all_identifiers", PGC_USERSET, COMPAT_OPTIONS_PREVIOUS, - gettext_noop("When generating SQL fragments, quote all identifiers."), - NULL, - }, - "e_all_identifiers, - false, - NULL, NULL, NULL - }, - - { - {"data_checksums", PGC_INTERNAL, PRESET_OPTIONS, - gettext_noop("Shows whether data checksums are turned on for this cluster."), - NULL, - GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE | GUC_RUNTIME_COMPUTED - }, - &data_checksums, - false, - NULL, NULL, NULL - }, - - { - {"syslog_sequence_numbers", PGC_SIGHUP, LOGGING_WHERE, - gettext_noop("Add sequence number to syslog messages to avoid duplicate suppression."), - NULL - }, - &syslog_sequence_numbers, - true, - NULL, NULL, NULL - }, - - { - {"syslog_split_messages", PGC_SIGHUP, LOGGING_WHERE, - gettext_noop("Split messages sent to syslog by lines and to fit into 1024 bytes."), - NULL - }, - &syslog_split_messages, - true, - NULL, NULL, NULL - }, - - { - {"parallel_leader_participation", PGC_USERSET, RESOURCES_ASYNCHRONOUS, - gettext_noop("Controls whether Gather and Gather Merge also run subplans."), - gettext_noop("Should gather nodes also run subplans or just gather tuples?"), - GUC_EXPLAIN - }, - ¶llel_leader_participation, - true, - NULL, NULL, NULL - }, - - { - {"jit", PGC_USERSET, QUERY_TUNING_OTHER, - gettext_noop("Allow JIT compilation."), - NULL, - GUC_EXPLAIN - }, - &jit_enabled, - true, - NULL, NULL, NULL - }, - - { - {"jit_debugging_support", PGC_SU_BACKEND, DEVELOPER_OPTIONS, - gettext_noop("Register JIT-compiled functions with debugger."), - NULL, - GUC_NOT_IN_SAMPLE - }, - &jit_debugging_support, - false, - - /* - * This is not guaranteed to be available, but given it's a developer - * oriented option, it doesn't seem worth adding code checking - * availability. - */ - NULL, NULL, NULL - }, - - { - {"jit_dump_bitcode", PGC_SUSET, DEVELOPER_OPTIONS, - gettext_noop("Write out LLVM bitcode to facilitate JIT debugging."), - NULL, - GUC_NOT_IN_SAMPLE - }, - &jit_dump_bitcode, - false, - NULL, NULL, NULL - }, - - { - {"jit_expressions", PGC_USERSET, DEVELOPER_OPTIONS, - gettext_noop("Allow JIT compilation of expressions."), - NULL, - GUC_NOT_IN_SAMPLE - }, - &jit_expressions, - true, - NULL, NULL, NULL - }, - - { - {"jit_profiling_support", PGC_SU_BACKEND, DEVELOPER_OPTIONS, - gettext_noop("Register JIT-compiled functions with perf profiler."), - NULL, - GUC_NOT_IN_SAMPLE - }, - &jit_profiling_support, - false, - - /* - * This is not guaranteed to be available, but given it's a developer - * oriented option, it doesn't seem worth adding code checking - * availability. - */ - NULL, NULL, NULL - }, - - { - {"jit_tuple_deforming", PGC_USERSET, DEVELOPER_OPTIONS, - gettext_noop("Allow JIT compilation of tuple deforming."), - NULL, - GUC_NOT_IN_SAMPLE - }, - &jit_tuple_deforming, - true, - NULL, NULL, NULL - }, - - { - {"data_sync_retry", PGC_POSTMASTER, ERROR_HANDLING_OPTIONS, - gettext_noop("Whether to continue running after a failure to sync data files."), - }, - &data_sync_retry, - false, - NULL, NULL, NULL - }, - - { - {"wal_receiver_create_temp_slot", PGC_SIGHUP, REPLICATION_STANDBY, - gettext_noop("Sets whether a WAL receiver should create a temporary replication slot if no permanent slot is configured."), - }, - &wal_receiver_create_temp_slot, - false, - NULL, NULL, NULL - }, - - /* End-of-list marker */ - { - {NULL, 0, 0, NULL, NULL}, NULL, false, NULL, NULL, NULL - } -}; - - -static struct config_int ConfigureNamesInt[] = -{ - { - {"archive_timeout", PGC_SIGHUP, WAL_ARCHIVING, - gettext_noop("Sets the amount of time to wait before forcing a " - "switch to the next WAL file."), - NULL, - GUC_UNIT_S - }, - &XLogArchiveTimeout, - 0, 0, INT_MAX / 2, - NULL, NULL, NULL - }, - { - {"post_auth_delay", PGC_BACKEND, DEVELOPER_OPTIONS, - gettext_noop("Sets the amount of time to wait after " - "authentication on connection startup."), - gettext_noop("This allows attaching a debugger to the process."), - GUC_NOT_IN_SAMPLE | GUC_UNIT_S - }, - &PostAuthDelay, - 0, 0, INT_MAX / 1000000, - NULL, NULL, NULL - }, - { - {"default_statistics_target", PGC_USERSET, QUERY_TUNING_OTHER, - gettext_noop("Sets the default statistics target."), - gettext_noop("This applies to table columns that have not had a " - "column-specific target set via ALTER TABLE SET STATISTICS.") - }, - &default_statistics_target, - 100, 1, 10000, - NULL, NULL, NULL - }, - { - {"from_collapse_limit", PGC_USERSET, QUERY_TUNING_OTHER, - gettext_noop("Sets the FROM-list size beyond which subqueries " - "are not collapsed."), - gettext_noop("The planner will merge subqueries into upper " - "queries if the resulting FROM list would have no more than " - "this many items."), - GUC_EXPLAIN - }, - &from_collapse_limit, - 8, 1, INT_MAX, - NULL, NULL, NULL - }, - { - {"join_collapse_limit", PGC_USERSET, QUERY_TUNING_OTHER, - gettext_noop("Sets the FROM-list size beyond which JOIN " - "constructs are not flattened."), - gettext_noop("The planner will flatten explicit JOIN " - "constructs into lists of FROM items whenever a " - "list of no more than this many items would result."), - GUC_EXPLAIN - }, - &join_collapse_limit, - 8, 1, INT_MAX, - NULL, NULL, NULL - }, - { - {"geqo_threshold", PGC_USERSET, QUERY_TUNING_GEQO, - gettext_noop("Sets the threshold of FROM items beyond which GEQO is used."), - NULL, - GUC_EXPLAIN - }, - &geqo_threshold, - 12, 2, INT_MAX, - NULL, NULL, NULL - }, - { - {"geqo_effort", PGC_USERSET, QUERY_TUNING_GEQO, - gettext_noop("GEQO: effort is used to set the default for other GEQO parameters."), - NULL, - GUC_EXPLAIN - }, - &Geqo_effort, - DEFAULT_GEQO_EFFORT, MIN_GEQO_EFFORT, MAX_GEQO_EFFORT, - NULL, NULL, NULL - }, - { - {"geqo_pool_size", PGC_USERSET, QUERY_TUNING_GEQO, - gettext_noop("GEQO: number of individuals in the population."), - gettext_noop("Zero selects a suitable default value."), - GUC_EXPLAIN - }, - &Geqo_pool_size, - 0, 0, INT_MAX, - NULL, NULL, NULL - }, - { - {"geqo_generations", PGC_USERSET, QUERY_TUNING_GEQO, - gettext_noop("GEQO: number of iterations of the algorithm."), - gettext_noop("Zero selects a suitable default value."), - GUC_EXPLAIN - }, - &Geqo_generations, - 0, 0, INT_MAX, - NULL, NULL, NULL - }, - - { - /* This is PGC_SUSET to prevent hiding from log_lock_waits. */ - {"deadlock_timeout", PGC_SUSET, LOCK_MANAGEMENT, - gettext_noop("Sets the time to wait on a lock before checking for deadlock."), - NULL, - GUC_UNIT_MS - }, - &DeadlockTimeout, - 1000, 1, INT_MAX, - NULL, NULL, NULL - }, - - { - {"max_standby_archive_delay", PGC_SIGHUP, REPLICATION_STANDBY, - gettext_noop("Sets the maximum delay before canceling queries when a hot standby server is processing archived WAL data."), - NULL, - GUC_UNIT_MS - }, - &max_standby_archive_delay, - 30 * 1000, -1, INT_MAX, - NULL, NULL, NULL - }, - - { - {"max_standby_streaming_delay", PGC_SIGHUP, REPLICATION_STANDBY, - gettext_noop("Sets the maximum delay before canceling queries when a hot standby server is processing streamed WAL data."), - NULL, - GUC_UNIT_MS - }, - &max_standby_streaming_delay, - 30 * 1000, -1, INT_MAX, - NULL, NULL, NULL - }, - - { - {"recovery_min_apply_delay", PGC_SIGHUP, REPLICATION_STANDBY, - gettext_noop("Sets the minimum delay for applying changes during recovery."), - NULL, - GUC_UNIT_MS - }, - &recovery_min_apply_delay, - 0, 0, INT_MAX, - NULL, NULL, NULL - }, - - { - {"wal_receiver_status_interval", PGC_SIGHUP, REPLICATION_STANDBY, - gettext_noop("Sets the maximum interval between WAL receiver status reports to the sending server."), - NULL, - GUC_UNIT_S - }, - &wal_receiver_status_interval, - 10, 0, INT_MAX / 1000, - NULL, NULL, NULL - }, - - { - {"wal_receiver_timeout", PGC_SIGHUP, REPLICATION_STANDBY, - gettext_noop("Sets the maximum wait time to receive data from the sending server."), - NULL, - GUC_UNIT_MS - }, - &wal_receiver_timeout, - 60 * 1000, 0, INT_MAX, - NULL, NULL, NULL - }, - - { - {"max_connections", PGC_POSTMASTER, CONN_AUTH_SETTINGS, - gettext_noop("Sets the maximum number of concurrent connections."), - NULL - }, - &MaxConnections, - 100, 1, MAX_BACKENDS, - check_maxconnections, NULL, NULL - }, - - { - /* see max_connections */ - {"superuser_reserved_connections", PGC_POSTMASTER, CONN_AUTH_SETTINGS, - gettext_noop("Sets the number of connection slots reserved for superusers."), - NULL - }, - &ReservedBackends, - 3, 0, MAX_BACKENDS, - NULL, NULL, NULL - }, - - { - {"min_dynamic_shared_memory", PGC_POSTMASTER, RESOURCES_MEM, - gettext_noop("Amount of dynamic shared memory reserved at startup."), - NULL, - GUC_UNIT_MB - }, - &min_dynamic_shared_memory, - 0, 0, (int) Min((size_t) INT_MAX, SIZE_MAX / (1024 * 1024)), - NULL, NULL, NULL - }, - - /* - * We sometimes multiply the number of shared buffers by two without - * checking for overflow, so we mustn't allow more than INT_MAX / 2. - */ - { - {"shared_buffers", PGC_POSTMASTER, RESOURCES_MEM, - gettext_noop("Sets the number of shared memory buffers used by the server."), - NULL, - GUC_UNIT_BLOCKS - }, - &NBuffers, - 16384, 16, INT_MAX / 2, - NULL, NULL, NULL - }, - - { - {"shared_memory_size", PGC_INTERNAL, PRESET_OPTIONS, - gettext_noop("Shows the size of the server's main shared memory area (rounded up to the nearest MB)."), - NULL, - GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE | GUC_UNIT_MB | GUC_RUNTIME_COMPUTED - }, - &shared_memory_size_mb, - 0, 0, INT_MAX, - NULL, NULL, NULL - }, - - { - {"shared_memory_size_in_huge_pages", PGC_INTERNAL, PRESET_OPTIONS, - gettext_noop("Shows the number of huge pages needed for the main shared memory area."), - gettext_noop("-1 indicates that the value could not be determined."), - GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE | GUC_RUNTIME_COMPUTED - }, - &shared_memory_size_in_huge_pages, - -1, -1, INT_MAX, - NULL, NULL, NULL - }, - - { - {"temp_buffers", PGC_USERSET, RESOURCES_MEM, - gettext_noop("Sets the maximum number of temporary buffers used by each session."), - NULL, - GUC_UNIT_BLOCKS | GUC_EXPLAIN - }, - &num_temp_buffers, - 1024, 100, INT_MAX / 2, - check_temp_buffers, NULL, NULL - }, - - { - {"port", PGC_POSTMASTER, CONN_AUTH_SETTINGS, - gettext_noop("Sets the TCP port the server listens on."), - NULL - }, - &PostPortNumber, - DEF_PGPORT, 1, 65535, - NULL, NULL, NULL - }, - - { - {"unix_socket_permissions", PGC_POSTMASTER, CONN_AUTH_SETTINGS, - gettext_noop("Sets the access permissions of the Unix-domain socket."), - gettext_noop("Unix-domain sockets use the usual Unix file system " - "permission set. The parameter value is expected " - "to be a numeric mode specification in the form " - "accepted by the chmod and umask system calls. " - "(To use the customary octal format the number must " - "start with a 0 (zero).)") - }, - &Unix_socket_permissions, - 0777, 0000, 0777, - NULL, NULL, show_unix_socket_permissions - }, - - { - {"log_file_mode", PGC_SIGHUP, LOGGING_WHERE, - gettext_noop("Sets the file permissions for log files."), - gettext_noop("The parameter value is expected " - "to be a numeric mode specification in the form " - "accepted by the chmod and umask system calls. " - "(To use the customary octal format the number must " - "start with a 0 (zero).)") - }, - &Log_file_mode, - 0600, 0000, 0777, - NULL, NULL, show_log_file_mode - }, - - - { - {"data_directory_mode", PGC_INTERNAL, PRESET_OPTIONS, - gettext_noop("Shows the mode of the data directory."), - gettext_noop("The parameter value is a numeric mode specification " - "in the form accepted by the chmod and umask system " - "calls. (To use the customary octal format the number " - "must start with a 0 (zero).)"), - GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE | GUC_RUNTIME_COMPUTED - }, - &data_directory_mode, - 0700, 0000, 0777, - NULL, NULL, show_data_directory_mode - }, - - { - {"work_mem", PGC_USERSET, RESOURCES_MEM, - gettext_noop("Sets the maximum memory to be used for query workspaces."), - gettext_noop("This much memory can be used by each internal " - "sort operation and hash table before switching to " - "temporary disk files."), - GUC_UNIT_KB | GUC_EXPLAIN - }, - &work_mem, - 4096, 64, MAX_KILOBYTES, - NULL, NULL, NULL - }, - - { - {"maintenance_work_mem", PGC_USERSET, RESOURCES_MEM, - gettext_noop("Sets the maximum memory to be used for maintenance operations."), - gettext_noop("This includes operations such as VACUUM and CREATE INDEX."), - GUC_UNIT_KB - }, - &maintenance_work_mem, - 65536, 1024, MAX_KILOBYTES, - NULL, NULL, NULL - }, - - { - {"logical_decoding_work_mem", PGC_USERSET, RESOURCES_MEM, - gettext_noop("Sets the maximum memory to be used for logical decoding."), - gettext_noop("This much memory can be used by each internal " - "reorder buffer before spilling to disk."), - GUC_UNIT_KB - }, - &logical_decoding_work_mem, - 65536, 64, MAX_KILOBYTES, - NULL, NULL, NULL - }, - - /* - * We use the hopefully-safely-small value of 100kB as the compiled-in - * default for max_stack_depth. InitializeGUCOptions will increase it if - * possible, depending on the actual platform-specific stack limit. - */ - { - {"max_stack_depth", PGC_SUSET, RESOURCES_MEM, - gettext_noop("Sets the maximum stack depth, in kilobytes."), - NULL, - GUC_UNIT_KB - }, - &max_stack_depth, - 100, 100, MAX_KILOBYTES, - check_max_stack_depth, assign_max_stack_depth, NULL - }, - - { - {"temp_file_limit", PGC_SUSET, RESOURCES_DISK, - gettext_noop("Limits the total size of all temporary files used by each process."), - gettext_noop("-1 means no limit."), - GUC_UNIT_KB - }, - &temp_file_limit, - -1, -1, INT_MAX, - NULL, NULL, NULL - }, - - { - {"vacuum_cost_page_hit", PGC_USERSET, RESOURCES_VACUUM_DELAY, - gettext_noop("Vacuum cost for a page found in the buffer cache."), - NULL - }, - &VacuumCostPageHit, - 1, 0, 10000, - NULL, NULL, NULL - }, - - { - {"vacuum_cost_page_miss", PGC_USERSET, RESOURCES_VACUUM_DELAY, - gettext_noop("Vacuum cost for a page not found in the buffer cache."), - NULL - }, - &VacuumCostPageMiss, - 2, 0, 10000, - NULL, NULL, NULL - }, - - { - {"vacuum_cost_page_dirty", PGC_USERSET, RESOURCES_VACUUM_DELAY, - gettext_noop("Vacuum cost for a page dirtied by vacuum."), - NULL - }, - &VacuumCostPageDirty, - 20, 0, 10000, - NULL, NULL, NULL - }, - - { - {"vacuum_cost_limit", PGC_USERSET, RESOURCES_VACUUM_DELAY, - gettext_noop("Vacuum cost amount available before napping."), - NULL - }, - &VacuumCostLimit, - 200, 1, 10000, - NULL, NULL, NULL - }, - - { - {"autovacuum_vacuum_cost_limit", PGC_SIGHUP, AUTOVACUUM, - gettext_noop("Vacuum cost amount available before napping, for autovacuum."), - NULL - }, - &autovacuum_vac_cost_limit, - -1, -1, 10000, - NULL, NULL, NULL - }, - - { - {"max_files_per_process", PGC_POSTMASTER, RESOURCES_KERNEL, - gettext_noop("Sets the maximum number of simultaneously open files for each server process."), - NULL - }, - &max_files_per_process, - 1000, 64, INT_MAX, - NULL, NULL, NULL - }, - - /* - * See also CheckRequiredParameterValues() if this parameter changes - */ - { - {"max_prepared_transactions", PGC_POSTMASTER, RESOURCES_MEM, - gettext_noop("Sets the maximum number of simultaneously prepared transactions."), - NULL - }, - &max_prepared_xacts, - 0, 0, MAX_BACKENDS, - NULL, NULL, NULL - }, - -#ifdef LOCK_DEBUG - { - {"trace_lock_oidmin", PGC_SUSET, DEVELOPER_OPTIONS, - gettext_noop("Sets the minimum OID of tables for tracking locks."), - gettext_noop("Is used to avoid output on system tables."), - GUC_NOT_IN_SAMPLE - }, - &Trace_lock_oidmin, - FirstNormalObjectId, 0, INT_MAX, - NULL, NULL, NULL - }, - { - {"trace_lock_table", PGC_SUSET, DEVELOPER_OPTIONS, - gettext_noop("Sets the OID of the table with unconditionally lock tracing."), - NULL, - GUC_NOT_IN_SAMPLE - }, - &Trace_lock_table, - 0, 0, INT_MAX, - NULL, NULL, NULL - }, -#endif - - { - {"statement_timeout", PGC_USERSET, CLIENT_CONN_STATEMENT, - gettext_noop("Sets the maximum allowed duration of any statement."), - gettext_noop("A value of 0 turns off the timeout."), - GUC_UNIT_MS - }, - &StatementTimeout, - 0, 0, INT_MAX, - NULL, NULL, NULL - }, - - { - {"lock_timeout", PGC_USERSET, CLIENT_CONN_STATEMENT, - gettext_noop("Sets the maximum allowed duration of any wait for a lock."), - gettext_noop("A value of 0 turns off the timeout."), - GUC_UNIT_MS - }, - &LockTimeout, - 0, 0, INT_MAX, - NULL, NULL, NULL - }, - - { - {"idle_in_transaction_session_timeout", PGC_USERSET, CLIENT_CONN_STATEMENT, - gettext_noop("Sets the maximum allowed idle time between queries, when in a transaction."), - gettext_noop("A value of 0 turns off the timeout."), - GUC_UNIT_MS - }, - &IdleInTransactionSessionTimeout, - 0, 0, INT_MAX, - NULL, NULL, NULL - }, - - { - {"idle_session_timeout", PGC_USERSET, CLIENT_CONN_STATEMENT, - gettext_noop("Sets the maximum allowed idle time between queries, when not in a transaction."), - gettext_noop("A value of 0 turns off the timeout."), - GUC_UNIT_MS - }, - &IdleSessionTimeout, - 0, 0, INT_MAX, - NULL, NULL, NULL - }, - - { - {"vacuum_freeze_min_age", PGC_USERSET, CLIENT_CONN_STATEMENT, - gettext_noop("Minimum age at which VACUUM should freeze a table row."), - NULL - }, - &vacuum_freeze_min_age, - 50000000, 0, 1000000000, - NULL, NULL, NULL - }, - - { - {"vacuum_freeze_table_age", PGC_USERSET, CLIENT_CONN_STATEMENT, - gettext_noop("Age at which VACUUM should scan whole table to freeze tuples."), - NULL - }, - &vacuum_freeze_table_age, - 150000000, 0, 2000000000, - NULL, NULL, NULL - }, - - { - {"vacuum_multixact_freeze_min_age", PGC_USERSET, CLIENT_CONN_STATEMENT, - gettext_noop("Minimum age at which VACUUM should freeze a MultiXactId in a table row."), - NULL - }, - &vacuum_multixact_freeze_min_age, - 5000000, 0, 1000000000, - NULL, NULL, NULL - }, - - { - {"vacuum_multixact_freeze_table_age", PGC_USERSET, CLIENT_CONN_STATEMENT, - gettext_noop("Multixact age at which VACUUM should scan whole table to freeze tuples."), - NULL - }, - &vacuum_multixact_freeze_table_age, - 150000000, 0, 2000000000, - NULL, NULL, NULL - }, - - { - {"vacuum_defer_cleanup_age", PGC_SIGHUP, REPLICATION_PRIMARY, - gettext_noop("Number of transactions by which VACUUM and HOT cleanup should be deferred, if any."), - NULL - }, - &vacuum_defer_cleanup_age, - 0, 0, 1000000, /* see ComputeXidHorizons */ - NULL, NULL, NULL - }, - { - {"vacuum_failsafe_age", PGC_USERSET, CLIENT_CONN_STATEMENT, - gettext_noop("Age at which VACUUM should trigger failsafe to avoid a wraparound outage."), - NULL - }, - &vacuum_failsafe_age, - 1600000000, 0, 2100000000, - NULL, NULL, NULL - }, - { - {"vacuum_multixact_failsafe_age", PGC_USERSET, CLIENT_CONN_STATEMENT, - gettext_noop("Multixact age at which VACUUM should trigger failsafe to avoid a wraparound outage."), - NULL - }, - &vacuum_multixact_failsafe_age, - 1600000000, 0, 2100000000, - NULL, NULL, NULL - }, - - /* - * See also CheckRequiredParameterValues() if this parameter changes - */ - { - {"max_locks_per_transaction", PGC_POSTMASTER, LOCK_MANAGEMENT, - gettext_noop("Sets the maximum number of locks per transaction."), - gettext_noop("The shared lock table is sized on the assumption that " - "at most max_locks_per_transaction * max_connections distinct " - "objects will need to be locked at any one time.") - }, - &max_locks_per_xact, - 64, 10, INT_MAX, - NULL, NULL, NULL - }, - - { - {"max_pred_locks_per_transaction", PGC_POSTMASTER, LOCK_MANAGEMENT, - gettext_noop("Sets the maximum number of predicate locks per transaction."), - gettext_noop("The shared predicate lock table is sized on the assumption that " - "at most max_pred_locks_per_transaction * max_connections distinct " - "objects will need to be locked at any one time.") - }, - &max_predicate_locks_per_xact, - 64, 10, INT_MAX, - NULL, NULL, NULL - }, - - { - {"max_pred_locks_per_relation", PGC_SIGHUP, LOCK_MANAGEMENT, - gettext_noop("Sets the maximum number of predicate-locked pages and tuples per relation."), - gettext_noop("If more than this total of pages and tuples in the same relation are locked " - "by a connection, those locks are replaced by a relation-level lock.") - }, - &max_predicate_locks_per_relation, - -2, INT_MIN, INT_MAX, - NULL, NULL, NULL - }, - - { - {"max_pred_locks_per_page", PGC_SIGHUP, LOCK_MANAGEMENT, - gettext_noop("Sets the maximum number of predicate-locked tuples per page."), - gettext_noop("If more than this number of tuples on the same page are locked " - "by a connection, those locks are replaced by a page-level lock.") - }, - &max_predicate_locks_per_page, - 2, 0, INT_MAX, - NULL, NULL, NULL - }, - - { - {"authentication_timeout", PGC_SIGHUP, CONN_AUTH_AUTH, - gettext_noop("Sets the maximum allowed time to complete client authentication."), - NULL, - GUC_UNIT_S - }, - &AuthenticationTimeout, - 60, 1, 600, - NULL, NULL, NULL - }, - - { - /* Not for general use */ - {"pre_auth_delay", PGC_SIGHUP, DEVELOPER_OPTIONS, - gettext_noop("Sets the amount of time to wait before " - "authentication on connection startup."), - gettext_noop("This allows attaching a debugger to the process."), - GUC_NOT_IN_SAMPLE | GUC_UNIT_S - }, - &PreAuthDelay, - 0, 0, 60, - NULL, NULL, NULL - }, - - { - {"wal_decode_buffer_size", PGC_POSTMASTER, WAL_RECOVERY, - gettext_noop("Buffer size for reading ahead in the WAL during recovery."), - gettext_noop("This controls the maximum distance we can read ahead in the WAL to prefetch referenced data blocks."), - GUC_UNIT_BYTE - }, - &wal_decode_buffer_size, - 512 * 1024, 64 * 1024, MaxAllocSize, - NULL, NULL, NULL - }, - - { - {"wal_keep_size", PGC_SIGHUP, REPLICATION_SENDING, - gettext_noop("Sets the size of WAL files held for standby servers."), - NULL, - GUC_UNIT_MB - }, - &wal_keep_size_mb, - 0, 0, MAX_KILOBYTES, - NULL, NULL, NULL - }, - - { - {"min_wal_size", PGC_SIGHUP, WAL_CHECKPOINTS, - gettext_noop("Sets the minimum size to shrink the WAL to."), - NULL, - GUC_UNIT_MB - }, - &min_wal_size_mb, - DEFAULT_MIN_WAL_SEGS * (DEFAULT_XLOG_SEG_SIZE / (1024 * 1024)), - 2, MAX_KILOBYTES, - NULL, NULL, NULL - }, - - { - {"max_wal_size", PGC_SIGHUP, WAL_CHECKPOINTS, - gettext_noop("Sets the WAL size that triggers a checkpoint."), - NULL, - GUC_UNIT_MB - }, - &max_wal_size_mb, - DEFAULT_MAX_WAL_SEGS * (DEFAULT_XLOG_SEG_SIZE / (1024 * 1024)), - 2, MAX_KILOBYTES, - NULL, assign_max_wal_size, NULL - }, - - { - {"checkpoint_timeout", PGC_SIGHUP, WAL_CHECKPOINTS, - gettext_noop("Sets the maximum time between automatic WAL checkpoints."), - NULL, - GUC_UNIT_S - }, - &CheckPointTimeout, - 300, 30, 86400, - NULL, NULL, NULL - }, - - { - {"checkpoint_warning", PGC_SIGHUP, WAL_CHECKPOINTS, - gettext_noop("Sets the maximum time before warning if checkpoints " - "triggered by WAL volume happen too frequently."), - gettext_noop("Write a message to the server log if checkpoints " - "caused by the filling of WAL segment files happen more " - "frequently than this amount of time. " - "Zero turns off the warning."), - GUC_UNIT_S - }, - &CheckPointWarning, - 30, 0, INT_MAX, - NULL, NULL, NULL - }, - - { - {"checkpoint_flush_after", PGC_SIGHUP, WAL_CHECKPOINTS, - gettext_noop("Number of pages after which previously performed writes are flushed to disk."), - NULL, - GUC_UNIT_BLOCKS - }, - &checkpoint_flush_after, - DEFAULT_CHECKPOINT_FLUSH_AFTER, 0, WRITEBACK_MAX_PENDING_FLUSHES, - NULL, NULL, NULL - }, - - { - {"wal_buffers", PGC_POSTMASTER, WAL_SETTINGS, - gettext_noop("Sets the number of disk-page buffers in shared memory for WAL."), - NULL, - GUC_UNIT_XBLOCKS - }, - &XLOGbuffers, - -1, -1, (INT_MAX / XLOG_BLCKSZ), - check_wal_buffers, NULL, NULL - }, - - { - {"wal_writer_delay", PGC_SIGHUP, WAL_SETTINGS, - gettext_noop("Time between WAL flushes performed in the WAL writer."), - NULL, - GUC_UNIT_MS - }, - &WalWriterDelay, - 200, 1, 10000, - NULL, NULL, NULL - }, - - { - {"wal_writer_flush_after", PGC_SIGHUP, WAL_SETTINGS, - gettext_noop("Amount of WAL written out by WAL writer that triggers a flush."), - NULL, - GUC_UNIT_XBLOCKS - }, - &WalWriterFlushAfter, - (1024 * 1024) / XLOG_BLCKSZ, 0, INT_MAX, - NULL, NULL, NULL - }, - - { - {"wal_skip_threshold", PGC_USERSET, WAL_SETTINGS, - gettext_noop("Minimum size of new file to fsync instead of writing WAL."), - NULL, - GUC_UNIT_KB - }, - &wal_skip_threshold, - 2048, 0, MAX_KILOBYTES, - NULL, NULL, NULL - }, - - { - {"max_wal_senders", PGC_POSTMASTER, REPLICATION_SENDING, - gettext_noop("Sets the maximum number of simultaneously running WAL sender processes."), - NULL - }, - &max_wal_senders, - 10, 0, MAX_BACKENDS, - check_max_wal_senders, NULL, NULL - }, - - { - /* see max_wal_senders */ - {"max_replication_slots", PGC_POSTMASTER, REPLICATION_SENDING, - gettext_noop("Sets the maximum number of simultaneously defined replication slots."), - NULL - }, - &max_replication_slots, - 10, 0, MAX_BACKENDS /* XXX? */ , - NULL, NULL, NULL - }, - - { - {"max_slot_wal_keep_size", PGC_SIGHUP, REPLICATION_SENDING, - gettext_noop("Sets the maximum WAL size that can be reserved by replication slots."), - gettext_noop("Replication slots will be marked as failed, and segments released " - "for deletion or recycling, if this much space is occupied by WAL " - "on disk."), - GUC_UNIT_MB - }, - &max_slot_wal_keep_size_mb, - -1, -1, MAX_KILOBYTES, - NULL, NULL, NULL - }, - - { - {"wal_sender_timeout", PGC_USERSET, REPLICATION_SENDING, - gettext_noop("Sets the maximum time to wait for WAL replication."), - NULL, - GUC_UNIT_MS - }, - &wal_sender_timeout, - 60 * 1000, 0, INT_MAX, - NULL, NULL, NULL - }, - - { - {"commit_delay", PGC_SUSET, WAL_SETTINGS, - gettext_noop("Sets the delay in microseconds between transaction commit and " - "flushing WAL to disk."), - NULL - /* we have no microseconds designation, so can't supply units here */ - }, - &CommitDelay, - 0, 0, 100000, - NULL, NULL, NULL - }, - - { - {"commit_siblings", PGC_USERSET, WAL_SETTINGS, - gettext_noop("Sets the minimum number of concurrent open transactions " - "required before performing commit_delay."), - NULL - }, - &CommitSiblings, - 5, 0, 1000, - NULL, NULL, NULL - }, - - { - {"extra_float_digits", PGC_USERSET, CLIENT_CONN_LOCALE, - gettext_noop("Sets the number of digits displayed for floating-point values."), - gettext_noop("This affects real, double precision, and geometric data types. " - "A zero or negative parameter value is added to the standard " - "number of digits (FLT_DIG or DBL_DIG as appropriate). " - "Any value greater than zero selects precise output mode.") - }, - &extra_float_digits, - 1, -15, 3, - NULL, NULL, NULL - }, - - { - {"log_min_duration_sample", PGC_SUSET, LOGGING_WHEN, - gettext_noop("Sets the minimum execution time above which " - "a sample of statements will be logged." - " Sampling is determined by log_statement_sample_rate."), - gettext_noop("Zero logs a sample of all queries. -1 turns this feature off."), - GUC_UNIT_MS - }, - &log_min_duration_sample, - -1, -1, INT_MAX, - NULL, NULL, NULL - }, - - { - {"log_min_duration_statement", PGC_SUSET, LOGGING_WHEN, - gettext_noop("Sets the minimum execution time above which " - "all statements will be logged."), - gettext_noop("Zero prints all queries. -1 turns this feature off."), - GUC_UNIT_MS - }, - &log_min_duration_statement, - -1, -1, INT_MAX, - NULL, NULL, NULL - }, - - { - {"log_autovacuum_min_duration", PGC_SIGHUP, LOGGING_WHAT, - gettext_noop("Sets the minimum execution time above which " - "autovacuum actions will be logged."), - gettext_noop("Zero prints all actions. -1 turns autovacuum logging off."), - GUC_UNIT_MS - }, - &Log_autovacuum_min_duration, - 600000, -1, INT_MAX, - NULL, NULL, NULL - }, - - { - {"log_parameter_max_length", PGC_SUSET, LOGGING_WHAT, - gettext_noop("Sets the maximum length in bytes of data logged for bind " - "parameter values when logging statements."), - gettext_noop("-1 to print values in full."), - GUC_UNIT_BYTE - }, - &log_parameter_max_length, - -1, -1, INT_MAX / 2, - NULL, NULL, NULL - }, - - { - {"log_parameter_max_length_on_error", PGC_USERSET, LOGGING_WHAT, - gettext_noop("Sets the maximum length in bytes of data logged for bind " - "parameter values when logging statements, on error."), - gettext_noop("-1 to print values in full."), - GUC_UNIT_BYTE - }, - &log_parameter_max_length_on_error, - 0, -1, INT_MAX / 2, - NULL, NULL, NULL - }, - - { - {"bgwriter_delay", PGC_SIGHUP, RESOURCES_BGWRITER, - gettext_noop("Background writer sleep time between rounds."), - NULL, - GUC_UNIT_MS - }, - &BgWriterDelay, - 200, 10, 10000, - NULL, NULL, NULL - }, - - { - {"bgwriter_lru_maxpages", PGC_SIGHUP, RESOURCES_BGWRITER, - gettext_noop("Background writer maximum number of LRU pages to flush per round."), - NULL - }, - &bgwriter_lru_maxpages, - 100, 0, INT_MAX / 2, /* Same upper limit as shared_buffers */ - NULL, NULL, NULL - }, - - { - {"bgwriter_flush_after", PGC_SIGHUP, RESOURCES_BGWRITER, - gettext_noop("Number of pages after which previously performed writes are flushed to disk."), - NULL, - GUC_UNIT_BLOCKS - }, - &bgwriter_flush_after, - DEFAULT_BGWRITER_FLUSH_AFTER, 0, WRITEBACK_MAX_PENDING_FLUSHES, - NULL, NULL, NULL - }, - - { - {"effective_io_concurrency", - PGC_USERSET, - RESOURCES_ASYNCHRONOUS, - gettext_noop("Number of simultaneous requests that can be handled efficiently by the disk subsystem."), - NULL, - GUC_EXPLAIN - }, - &effective_io_concurrency, -#ifdef USE_PREFETCH - 1, -#else - 0, -#endif - 0, MAX_IO_CONCURRENCY, - check_effective_io_concurrency, NULL, NULL - }, - - { - {"maintenance_io_concurrency", - PGC_USERSET, - RESOURCES_ASYNCHRONOUS, - gettext_noop("A variant of effective_io_concurrency that is used for maintenance work."), - NULL, - GUC_EXPLAIN - }, - &maintenance_io_concurrency, -#ifdef USE_PREFETCH - 10, -#else - 0, -#endif - 0, MAX_IO_CONCURRENCY, - check_maintenance_io_concurrency, assign_maintenance_io_concurrency, - NULL - }, - - { - {"backend_flush_after", PGC_USERSET, RESOURCES_ASYNCHRONOUS, - gettext_noop("Number of pages after which previously performed writes are flushed to disk."), - NULL, - GUC_UNIT_BLOCKS - }, - &backend_flush_after, - DEFAULT_BACKEND_FLUSH_AFTER, 0, WRITEBACK_MAX_PENDING_FLUSHES, - NULL, NULL, NULL - }, - - { - {"max_worker_processes", - PGC_POSTMASTER, - RESOURCES_ASYNCHRONOUS, - gettext_noop("Maximum number of concurrent worker processes."), - NULL, - }, - &max_worker_processes, - 8, 0, MAX_BACKENDS, - check_max_worker_processes, NULL, NULL - }, - - { - {"max_logical_replication_workers", - PGC_POSTMASTER, - REPLICATION_SUBSCRIBERS, - gettext_noop("Maximum number of logical replication worker processes."), - NULL, - }, - &max_logical_replication_workers, - 4, 0, MAX_BACKENDS, - NULL, NULL, NULL - }, - - { - {"max_sync_workers_per_subscription", - PGC_SIGHUP, - REPLICATION_SUBSCRIBERS, - gettext_noop("Maximum number of table synchronization workers per subscription."), - NULL, - }, - &max_sync_workers_per_subscription, - 2, 0, MAX_BACKENDS, - NULL, NULL, NULL - }, - - { - {"log_rotation_age", PGC_SIGHUP, LOGGING_WHERE, - gettext_noop("Sets the amount of time to wait before forcing " - "log file rotation."), - NULL, - GUC_UNIT_MIN - }, - &Log_RotationAge, - HOURS_PER_DAY * MINS_PER_HOUR, 0, INT_MAX / SECS_PER_MINUTE, - NULL, NULL, NULL - }, - - { - {"log_rotation_size", PGC_SIGHUP, LOGGING_WHERE, - gettext_noop("Sets the maximum size a log file can reach before " - "being rotated."), - NULL, - GUC_UNIT_KB - }, - &Log_RotationSize, - 10 * 1024, 0, INT_MAX / 1024, - NULL, NULL, NULL - }, - - { - {"max_function_args", PGC_INTERNAL, PRESET_OPTIONS, - gettext_noop("Shows the maximum number of function arguments."), - NULL, - GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE - }, - &max_function_args, - FUNC_MAX_ARGS, FUNC_MAX_ARGS, FUNC_MAX_ARGS, - NULL, NULL, NULL - }, - - { - {"max_index_keys", PGC_INTERNAL, PRESET_OPTIONS, - gettext_noop("Shows the maximum number of index keys."), - NULL, - GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE - }, - &max_index_keys, - INDEX_MAX_KEYS, INDEX_MAX_KEYS, INDEX_MAX_KEYS, - NULL, NULL, NULL - }, - - { - {"max_identifier_length", PGC_INTERNAL, PRESET_OPTIONS, - gettext_noop("Shows the maximum identifier length."), - NULL, - GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE - }, - &max_identifier_length, - NAMEDATALEN - 1, NAMEDATALEN - 1, NAMEDATALEN - 1, - NULL, NULL, NULL - }, - - { - {"block_size", PGC_INTERNAL, PRESET_OPTIONS, - gettext_noop("Shows the size of a disk block."), - NULL, - GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE - }, - &block_size, - BLCKSZ, BLCKSZ, BLCKSZ, - NULL, NULL, NULL - }, - - { - {"segment_size", PGC_INTERNAL, PRESET_OPTIONS, - gettext_noop("Shows the number of pages per disk file."), - NULL, - GUC_UNIT_BLOCKS | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE - }, - &segment_size, - RELSEG_SIZE, RELSEG_SIZE, RELSEG_SIZE, - NULL, NULL, NULL - }, - - { - {"wal_block_size", PGC_INTERNAL, PRESET_OPTIONS, - gettext_noop("Shows the block size in the write ahead log."), - NULL, - GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE - }, - &wal_block_size, - XLOG_BLCKSZ, XLOG_BLCKSZ, XLOG_BLCKSZ, - NULL, NULL, NULL - }, - - { - {"wal_retrieve_retry_interval", PGC_SIGHUP, REPLICATION_STANDBY, - gettext_noop("Sets the time to wait before retrying to retrieve WAL " - "after a failed attempt."), - NULL, - GUC_UNIT_MS - }, - &wal_retrieve_retry_interval, - 5000, 1, INT_MAX, - NULL, NULL, NULL - }, - - { - {"wal_segment_size", PGC_INTERNAL, PRESET_OPTIONS, - gettext_noop("Shows the size of write ahead log segments."), - NULL, - GUC_UNIT_BYTE | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE | GUC_RUNTIME_COMPUTED - }, - &wal_segment_size, - DEFAULT_XLOG_SEG_SIZE, - WalSegMinSize, - WalSegMaxSize, - NULL, NULL, NULL - }, - - { - {"autovacuum_naptime", PGC_SIGHUP, AUTOVACUUM, - gettext_noop("Time to sleep between autovacuum runs."), - NULL, - GUC_UNIT_S - }, - &autovacuum_naptime, - 60, 1, INT_MAX / 1000, - NULL, NULL, NULL - }, - { - {"autovacuum_vacuum_threshold", PGC_SIGHUP, AUTOVACUUM, - gettext_noop("Minimum number of tuple updates or deletes prior to vacuum."), - NULL - }, - &autovacuum_vac_thresh, - 50, 0, INT_MAX, - NULL, NULL, NULL - }, - { - {"autovacuum_vacuum_insert_threshold", PGC_SIGHUP, AUTOVACUUM, - gettext_noop("Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums."), - NULL - }, - &autovacuum_vac_ins_thresh, - 1000, -1, INT_MAX, - NULL, NULL, NULL - }, - { - {"autovacuum_analyze_threshold", PGC_SIGHUP, AUTOVACUUM, - gettext_noop("Minimum number of tuple inserts, updates, or deletes prior to analyze."), - NULL - }, - &autovacuum_anl_thresh, - 50, 0, INT_MAX, - NULL, NULL, NULL - }, - { - /* see varsup.c for why this is PGC_POSTMASTER not PGC_SIGHUP */ - {"autovacuum_freeze_max_age", PGC_POSTMASTER, AUTOVACUUM, - gettext_noop("Age at which to autovacuum a table to prevent transaction ID wraparound."), - NULL - }, - &autovacuum_freeze_max_age, - - /* see vacuum_failsafe_age if you change the upper-limit value. */ - 200000000, 100000, 2000000000, - NULL, NULL, NULL - }, - { - /* see multixact.c for why this is PGC_POSTMASTER not PGC_SIGHUP */ - {"autovacuum_multixact_freeze_max_age", PGC_POSTMASTER, AUTOVACUUM, - gettext_noop("Multixact age at which to autovacuum a table to prevent multixact wraparound."), - NULL - }, - &autovacuum_multixact_freeze_max_age, - 400000000, 10000, 2000000000, - NULL, NULL, NULL - }, - { - /* see max_connections */ - {"autovacuum_max_workers", PGC_POSTMASTER, AUTOVACUUM, - gettext_noop("Sets the maximum number of simultaneously running autovacuum worker processes."), - NULL - }, - &autovacuum_max_workers, - 3, 1, MAX_BACKENDS, - check_autovacuum_max_workers, NULL, NULL - }, - - { - {"max_parallel_maintenance_workers", PGC_USERSET, RESOURCES_ASYNCHRONOUS, - gettext_noop("Sets the maximum number of parallel processes per maintenance operation."), - NULL - }, - &max_parallel_maintenance_workers, - 2, 0, 1024, - NULL, NULL, NULL - }, - - { - {"max_parallel_workers_per_gather", PGC_USERSET, RESOURCES_ASYNCHRONOUS, - gettext_noop("Sets the maximum number of parallel processes per executor node."), - NULL, - GUC_EXPLAIN - }, - &max_parallel_workers_per_gather, - 2, 0, MAX_PARALLEL_WORKER_LIMIT, - NULL, NULL, NULL - }, - - { - {"max_parallel_workers", PGC_USERSET, RESOURCES_ASYNCHRONOUS, - gettext_noop("Sets the maximum number of parallel workers that can be active at one time."), - NULL, - GUC_EXPLAIN - }, - &max_parallel_workers, - 8, 0, MAX_PARALLEL_WORKER_LIMIT, - NULL, NULL, NULL - }, - - { - {"autovacuum_work_mem", PGC_SIGHUP, RESOURCES_MEM, - gettext_noop("Sets the maximum memory to be used by each autovacuum worker process."), - NULL, - GUC_UNIT_KB - }, - &autovacuum_work_mem, - -1, -1, MAX_KILOBYTES, - check_autovacuum_work_mem, NULL, NULL - }, - - { - {"old_snapshot_threshold", PGC_POSTMASTER, RESOURCES_ASYNCHRONOUS, - gettext_noop("Time before a snapshot is too old to read pages changed after the snapshot was taken."), - gettext_noop("A value of -1 disables this feature."), - GUC_UNIT_MIN - }, - &old_snapshot_threshold, - -1, -1, MINS_PER_HOUR * HOURS_PER_DAY * 60, - NULL, NULL, NULL - }, - - { - {"tcp_keepalives_idle", PGC_USERSET, CONN_AUTH_TCP, - gettext_noop("Time between issuing TCP keepalives."), - gettext_noop("A value of 0 uses the system default."), - GUC_UNIT_S - }, - &tcp_keepalives_idle, - 0, 0, INT_MAX, - NULL, assign_tcp_keepalives_idle, show_tcp_keepalives_idle - }, - - { - {"tcp_keepalives_interval", PGC_USERSET, CONN_AUTH_TCP, - gettext_noop("Time between TCP keepalive retransmits."), - gettext_noop("A value of 0 uses the system default."), - GUC_UNIT_S - }, - &tcp_keepalives_interval, - 0, 0, INT_MAX, - NULL, assign_tcp_keepalives_interval, show_tcp_keepalives_interval - }, - - { - {"ssl_renegotiation_limit", PGC_USERSET, COMPAT_OPTIONS_PREVIOUS, - gettext_noop("SSL renegotiation is no longer supported; this can only be 0."), - NULL, - GUC_NO_SHOW_ALL | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE, - }, - &ssl_renegotiation_limit, - 0, 0, 0, - NULL, NULL, NULL - }, - - { - {"tcp_keepalives_count", PGC_USERSET, CONN_AUTH_TCP, - gettext_noop("Maximum number of TCP keepalive retransmits."), - gettext_noop("This controls the number of consecutive keepalive retransmits that can be " - "lost before a connection is considered dead. A value of 0 uses the " - "system default."), - }, - &tcp_keepalives_count, - 0, 0, INT_MAX, - NULL, assign_tcp_keepalives_count, show_tcp_keepalives_count - }, - - { - {"gin_fuzzy_search_limit", PGC_USERSET, CLIENT_CONN_OTHER, - gettext_noop("Sets the maximum allowed result for exact search by GIN."), - NULL, - 0 - }, - &GinFuzzySearchLimit, - 0, 0, INT_MAX, - NULL, NULL, NULL - }, - - { - {"effective_cache_size", PGC_USERSET, QUERY_TUNING_COST, - gettext_noop("Sets the planner's assumption about the total size of the data caches."), - gettext_noop("That is, the total size of the caches (kernel cache and shared buffers) used for PostgreSQL data files. " - "This is measured in disk pages, which are normally 8 kB each."), - GUC_UNIT_BLOCKS | GUC_EXPLAIN, - }, - &effective_cache_size, - DEFAULT_EFFECTIVE_CACHE_SIZE, 1, INT_MAX, - NULL, NULL, NULL - }, - - { - {"min_parallel_table_scan_size", PGC_USERSET, QUERY_TUNING_COST, - gettext_noop("Sets the minimum amount of table data for a parallel scan."), - gettext_noop("If the planner estimates that it will read a number of table pages too small to reach this limit, a parallel scan will not be considered."), - GUC_UNIT_BLOCKS | GUC_EXPLAIN, - }, - &min_parallel_table_scan_size, - (8 * 1024 * 1024) / BLCKSZ, 0, INT_MAX / 3, - NULL, NULL, NULL - }, - - { - {"min_parallel_index_scan_size", PGC_USERSET, QUERY_TUNING_COST, - gettext_noop("Sets the minimum amount of index data for a parallel scan."), - gettext_noop("If the planner estimates that it will read a number of index pages too small to reach this limit, a parallel scan will not be considered."), - GUC_UNIT_BLOCKS | GUC_EXPLAIN, - }, - &min_parallel_index_scan_size, - (512 * 1024) / BLCKSZ, 0, INT_MAX / 3, - NULL, NULL, NULL - }, - - { - /* Can't be set in postgresql.conf */ - {"server_version_num", PGC_INTERNAL, PRESET_OPTIONS, - gettext_noop("Shows the server version as an integer."), - NULL, - GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE - }, - &server_version_num, - PG_VERSION_NUM, PG_VERSION_NUM, PG_VERSION_NUM, - NULL, NULL, NULL - }, - - { - {"log_temp_files", PGC_SUSET, LOGGING_WHAT, - gettext_noop("Log the use of temporary files larger than this number of kilobytes."), - gettext_noop("Zero logs all files. The default is -1 (turning this feature off)."), - GUC_UNIT_KB - }, - &log_temp_files, - -1, -1, INT_MAX, - NULL, NULL, NULL - }, - - { - {"track_activity_query_size", PGC_POSTMASTER, STATS_CUMULATIVE, - gettext_noop("Sets the size reserved for pg_stat_activity.query, in bytes."), - NULL, - GUC_UNIT_BYTE - }, - &pgstat_track_activity_query_size, - 1024, 100, 1048576, - NULL, NULL, NULL - }, - - { - {"gin_pending_list_limit", PGC_USERSET, CLIENT_CONN_STATEMENT, - gettext_noop("Sets the maximum size of the pending list for GIN index."), - NULL, - GUC_UNIT_KB - }, - &gin_pending_list_limit, - 4096, 64, MAX_KILOBYTES, - NULL, NULL, NULL - }, - - { - {"tcp_user_timeout", PGC_USERSET, CONN_AUTH_TCP, - gettext_noop("TCP user timeout."), - gettext_noop("A value of 0 uses the system default."), - GUC_UNIT_MS - }, - &tcp_user_timeout, - 0, 0, INT_MAX, - NULL, assign_tcp_user_timeout, show_tcp_user_timeout - }, - - { - {"huge_page_size", PGC_POSTMASTER, RESOURCES_MEM, - gettext_noop("The size of huge page that should be requested."), - NULL, - GUC_UNIT_KB - }, - &huge_page_size, - 0, 0, INT_MAX, - check_huge_page_size, NULL, NULL - }, - - { - {"debug_discard_caches", PGC_SUSET, DEVELOPER_OPTIONS, - gettext_noop("Aggressively flush system caches for debugging purposes."), - NULL, - GUC_NOT_IN_SAMPLE - }, - &debug_discard_caches, -#ifdef DISCARD_CACHES_ENABLED - /* Set default based on older compile-time-only cache clobber macros */ -#if defined(CLOBBER_CACHE_RECURSIVELY) - 3, -#elif defined(CLOBBER_CACHE_ALWAYS) - 1, -#else - 0, -#endif - 0, 5, -#else /* not DISCARD_CACHES_ENABLED */ - 0, 0, 0, -#endif /* not DISCARD_CACHES_ENABLED */ - NULL, NULL, NULL - }, - - { - {"client_connection_check_interval", PGC_USERSET, CONN_AUTH_TCP, - gettext_noop("Sets the time interval between checks for disconnection while running queries."), - NULL, - GUC_UNIT_MS - }, - &client_connection_check_interval, - 0, 0, INT_MAX, - check_client_connection_check_interval, NULL, NULL - }, - - { - {"log_startup_progress_interval", PGC_SIGHUP, LOGGING_WHEN, - gettext_noop("Time between progress updates for " - "long-running startup operations."), - gettext_noop("0 turns this feature off."), - GUC_UNIT_MS, - }, - &log_startup_progress_interval, - 10000, 0, INT_MAX, - NULL, NULL, NULL - }, - - /* End-of-list marker */ - { - {NULL, 0, 0, NULL, NULL}, NULL, 0, 0, 0, NULL, NULL, NULL - } -}; - - -static struct config_real ConfigureNamesReal[] = -{ - { - {"seq_page_cost", PGC_USERSET, QUERY_TUNING_COST, - gettext_noop("Sets the planner's estimate of the cost of a " - "sequentially fetched disk page."), - NULL, - GUC_EXPLAIN - }, - &seq_page_cost, - DEFAULT_SEQ_PAGE_COST, 0, DBL_MAX, - NULL, NULL, NULL - }, - { - {"random_page_cost", PGC_USERSET, QUERY_TUNING_COST, - gettext_noop("Sets the planner's estimate of the cost of a " - "nonsequentially fetched disk page."), - NULL, - GUC_EXPLAIN - }, - &random_page_cost, - DEFAULT_RANDOM_PAGE_COST, 0, DBL_MAX, - NULL, NULL, NULL - }, - { - {"cpu_tuple_cost", PGC_USERSET, QUERY_TUNING_COST, - gettext_noop("Sets the planner's estimate of the cost of " - "processing each tuple (row)."), - NULL, - GUC_EXPLAIN - }, - &cpu_tuple_cost, - DEFAULT_CPU_TUPLE_COST, 0, DBL_MAX, - NULL, NULL, NULL - }, - { - {"cpu_index_tuple_cost", PGC_USERSET, QUERY_TUNING_COST, - gettext_noop("Sets the planner's estimate of the cost of " - "processing each index entry during an index scan."), - NULL, - GUC_EXPLAIN - }, - &cpu_index_tuple_cost, - DEFAULT_CPU_INDEX_TUPLE_COST, 0, DBL_MAX, - NULL, NULL, NULL - }, - { - {"cpu_operator_cost", PGC_USERSET, QUERY_TUNING_COST, - gettext_noop("Sets the planner's estimate of the cost of " - "processing each operator or function call."), - NULL, - GUC_EXPLAIN - }, - &cpu_operator_cost, - DEFAULT_CPU_OPERATOR_COST, 0, DBL_MAX, - NULL, NULL, NULL - }, - { - {"parallel_tuple_cost", PGC_USERSET, QUERY_TUNING_COST, - gettext_noop("Sets the planner's estimate of the cost of " - "passing each tuple (row) from worker to leader backend."), - NULL, - GUC_EXPLAIN - }, - ¶llel_tuple_cost, - DEFAULT_PARALLEL_TUPLE_COST, 0, DBL_MAX, - NULL, NULL, NULL - }, - { - {"parallel_setup_cost", PGC_USERSET, QUERY_TUNING_COST, - gettext_noop("Sets the planner's estimate of the cost of " - "starting up worker processes for parallel query."), - NULL, - GUC_EXPLAIN - }, - ¶llel_setup_cost, - DEFAULT_PARALLEL_SETUP_COST, 0, DBL_MAX, - NULL, NULL, NULL - }, - - { - {"jit_above_cost", PGC_USERSET, QUERY_TUNING_COST, - gettext_noop("Perform JIT compilation if query is more expensive."), - gettext_noop("-1 disables JIT compilation."), - GUC_EXPLAIN - }, - &jit_above_cost, - 100000, -1, DBL_MAX, - NULL, NULL, NULL - }, - - { - {"jit_optimize_above_cost", PGC_USERSET, QUERY_TUNING_COST, - gettext_noop("Optimize JIT-compiled functions if query is more expensive."), - gettext_noop("-1 disables optimization."), - GUC_EXPLAIN - }, - &jit_optimize_above_cost, - 500000, -1, DBL_MAX, - NULL, NULL, NULL - }, - - { - {"jit_inline_above_cost", PGC_USERSET, QUERY_TUNING_COST, - gettext_noop("Perform JIT inlining if query is more expensive."), - gettext_noop("-1 disables inlining."), - GUC_EXPLAIN - }, - &jit_inline_above_cost, - 500000, -1, DBL_MAX, - NULL, NULL, NULL - }, - - { - {"cursor_tuple_fraction", PGC_USERSET, QUERY_TUNING_OTHER, - gettext_noop("Sets the planner's estimate of the fraction of " - "a cursor's rows that will be retrieved."), - NULL, - GUC_EXPLAIN - }, - &cursor_tuple_fraction, - DEFAULT_CURSOR_TUPLE_FRACTION, 0.0, 1.0, - NULL, NULL, NULL - }, - - { - {"recursive_worktable_factor", PGC_USERSET, QUERY_TUNING_OTHER, - gettext_noop("Sets the planner's estimate of the average size " - "of a recursive query's working table."), - NULL, - GUC_EXPLAIN - }, - &recursive_worktable_factor, - DEFAULT_RECURSIVE_WORKTABLE_FACTOR, 0.001, 1000000.0, - NULL, NULL, NULL - }, - - { - {"geqo_selection_bias", PGC_USERSET, QUERY_TUNING_GEQO, - gettext_noop("GEQO: selective pressure within the population."), - NULL, - GUC_EXPLAIN - }, - &Geqo_selection_bias, - DEFAULT_GEQO_SELECTION_BIAS, - MIN_GEQO_SELECTION_BIAS, MAX_GEQO_SELECTION_BIAS, - NULL, NULL, NULL - }, - { - {"geqo_seed", PGC_USERSET, QUERY_TUNING_GEQO, - gettext_noop("GEQO: seed for random path selection."), - NULL, - GUC_EXPLAIN - }, - &Geqo_seed, - 0.0, 0.0, 1.0, - NULL, NULL, NULL - }, - - { - {"hash_mem_multiplier", PGC_USERSET, RESOURCES_MEM, - gettext_noop("Multiple of work_mem to use for hash tables."), - NULL, - GUC_EXPLAIN - }, - &hash_mem_multiplier, - 2.0, 1.0, 1000.0, - NULL, NULL, NULL - }, - - { - {"bgwriter_lru_multiplier", PGC_SIGHUP, RESOURCES_BGWRITER, - gettext_noop("Multiple of the average buffer usage to free per round."), - NULL - }, - &bgwriter_lru_multiplier, - 2.0, 0.0, 10.0, - NULL, NULL, NULL - }, - - { - {"seed", PGC_USERSET, UNGROUPED, - gettext_noop("Sets the seed for random-number generation."), - NULL, - GUC_NO_SHOW_ALL | GUC_NO_RESET_ALL | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE - }, - &phony_random_seed, - 0.0, -1.0, 1.0, - check_random_seed, assign_random_seed, show_random_seed - }, - - { - {"vacuum_cost_delay", PGC_USERSET, RESOURCES_VACUUM_DELAY, - gettext_noop("Vacuum cost delay in milliseconds."), - NULL, - GUC_UNIT_MS - }, - &VacuumCostDelay, - 0, 0, 100, - NULL, NULL, NULL - }, - - { - {"autovacuum_vacuum_cost_delay", PGC_SIGHUP, AUTOVACUUM, - gettext_noop("Vacuum cost delay in milliseconds, for autovacuum."), - NULL, - GUC_UNIT_MS - }, - &autovacuum_vac_cost_delay, - 2, -1, 100, - NULL, NULL, NULL - }, - - { - {"autovacuum_vacuum_scale_factor", PGC_SIGHUP, AUTOVACUUM, - gettext_noop("Number of tuple updates or deletes prior to vacuum as a fraction of reltuples."), - NULL - }, - &autovacuum_vac_scale, - 0.2, 0.0, 100.0, - NULL, NULL, NULL - }, - - { - {"autovacuum_vacuum_insert_scale_factor", PGC_SIGHUP, AUTOVACUUM, - gettext_noop("Number of tuple inserts prior to vacuum as a fraction of reltuples."), - NULL - }, - &autovacuum_vac_ins_scale, - 0.2, 0.0, 100.0, - NULL, NULL, NULL - }, - - { - {"autovacuum_analyze_scale_factor", PGC_SIGHUP, AUTOVACUUM, - gettext_noop("Number of tuple inserts, updates, or deletes prior to analyze as a fraction of reltuples."), - NULL - }, - &autovacuum_anl_scale, - 0.1, 0.0, 100.0, - NULL, NULL, NULL - }, - - { - {"checkpoint_completion_target", PGC_SIGHUP, WAL_CHECKPOINTS, - gettext_noop("Time spent flushing dirty buffers during checkpoint, as fraction of checkpoint interval."), - NULL - }, - &CheckPointCompletionTarget, - 0.9, 0.0, 1.0, - NULL, NULL, NULL - }, - - { - {"log_statement_sample_rate", PGC_SUSET, LOGGING_WHEN, - gettext_noop("Fraction of statements exceeding log_min_duration_sample to be logged."), - gettext_noop("Use a value between 0.0 (never log) and 1.0 (always log).") - }, - &log_statement_sample_rate, - 1.0, 0.0, 1.0, - NULL, NULL, NULL - }, - - { - {"log_transaction_sample_rate", PGC_SUSET, LOGGING_WHEN, - gettext_noop("Sets the fraction of transactions from which to log all statements."), - gettext_noop("Use a value between 0.0 (never log) and 1.0 (log all " - "statements for all transactions).") - }, - &log_xact_sample_rate, - 0.0, 0.0, 1.0, - NULL, NULL, NULL - }, - - /* End-of-list marker */ - { - {NULL, 0, 0, NULL, NULL}, NULL, 0.0, 0.0, 0.0, NULL, NULL, NULL - } -}; - - -static struct config_string ConfigureNamesString[] = -{ - { - {"archive_command", PGC_SIGHUP, WAL_ARCHIVING, - gettext_noop("Sets the shell command that will be called to archive a WAL file."), - gettext_noop("This is used only if \"archive_library\" is not set.") - }, - &XLogArchiveCommand, - "", - NULL, NULL, show_archive_command - }, - - { - {"archive_library", PGC_SIGHUP, WAL_ARCHIVING, - gettext_noop("Sets the library that will be called to archive a WAL file."), - gettext_noop("An empty string indicates that \"archive_command\" should be used.") - }, - &XLogArchiveLibrary, - "", - NULL, NULL, NULL - }, - - { - {"restore_command", PGC_SIGHUP, WAL_ARCHIVE_RECOVERY, - gettext_noop("Sets the shell command that will be called to retrieve an archived WAL file."), - NULL - }, - &recoveryRestoreCommand, - "", - NULL, NULL, NULL - }, - - { - {"archive_cleanup_command", PGC_SIGHUP, WAL_ARCHIVE_RECOVERY, - gettext_noop("Sets the shell command that will be executed at every restart point."), - NULL - }, - &archiveCleanupCommand, - "", - NULL, NULL, NULL - }, - - { - {"recovery_end_command", PGC_SIGHUP, WAL_ARCHIVE_RECOVERY, - gettext_noop("Sets the shell command that will be executed once at the end of recovery."), - NULL - }, - &recoveryEndCommand, - "", - NULL, NULL, NULL - }, - - { - {"recovery_target_timeline", PGC_POSTMASTER, WAL_RECOVERY_TARGET, - gettext_noop("Specifies the timeline to recover into."), - NULL - }, - &recovery_target_timeline_string, - "latest", - check_recovery_target_timeline, assign_recovery_target_timeline, NULL - }, - - { - {"recovery_target", PGC_POSTMASTER, WAL_RECOVERY_TARGET, - gettext_noop("Set to \"immediate\" to end recovery as soon as a consistent state is reached."), - NULL - }, - &recovery_target_string, - "", - check_recovery_target, assign_recovery_target, NULL - }, - { - {"recovery_target_xid", PGC_POSTMASTER, WAL_RECOVERY_TARGET, - gettext_noop("Sets the transaction ID up to which recovery will proceed."), - NULL - }, - &recovery_target_xid_string, - "", - check_recovery_target_xid, assign_recovery_target_xid, NULL - }, - { - {"recovery_target_time", PGC_POSTMASTER, WAL_RECOVERY_TARGET, - gettext_noop("Sets the time stamp up to which recovery will proceed."), - NULL - }, - &recovery_target_time_string, - "", - check_recovery_target_time, assign_recovery_target_time, NULL - }, - { - {"recovery_target_name", PGC_POSTMASTER, WAL_RECOVERY_TARGET, - gettext_noop("Sets the named restore point up to which recovery will proceed."), - NULL - }, - &recovery_target_name_string, - "", - check_recovery_target_name, assign_recovery_target_name, NULL - }, - { - {"recovery_target_lsn", PGC_POSTMASTER, WAL_RECOVERY_TARGET, - gettext_noop("Sets the LSN of the write-ahead log location up to which recovery will proceed."), - NULL - }, - &recovery_target_lsn_string, - "", - check_recovery_target_lsn, assign_recovery_target_lsn, NULL - }, - - { - {"promote_trigger_file", PGC_SIGHUP, REPLICATION_STANDBY, - gettext_noop("Specifies a file name whose presence ends recovery in the standby."), - NULL - }, - &PromoteTriggerFile, - "", - NULL, NULL, NULL - }, - - { - {"primary_conninfo", PGC_SIGHUP, REPLICATION_STANDBY, - gettext_noop("Sets the connection string to be used to connect to the sending server."), - NULL, - GUC_SUPERUSER_ONLY - }, - &PrimaryConnInfo, - "", - NULL, NULL, NULL - }, - - { - {"primary_slot_name", PGC_SIGHUP, REPLICATION_STANDBY, - gettext_noop("Sets the name of the replication slot to use on the sending server."), - NULL - }, - &PrimarySlotName, - "", - check_primary_slot_name, NULL, NULL - }, - - { - {"client_encoding", PGC_USERSET, CLIENT_CONN_LOCALE, - gettext_noop("Sets the client's character set encoding."), - NULL, - GUC_IS_NAME | GUC_REPORT - }, - &client_encoding_string, - "SQL_ASCII", - check_client_encoding, assign_client_encoding, NULL - }, - - { - {"log_line_prefix", PGC_SIGHUP, LOGGING_WHAT, - gettext_noop("Controls information prefixed to each log line."), - gettext_noop("If blank, no prefix is used.") - }, - &Log_line_prefix, - "%m [%p] ", - NULL, NULL, NULL - }, - - { - {"log_timezone", PGC_SIGHUP, LOGGING_WHAT, - gettext_noop("Sets the time zone to use in log messages."), - NULL - }, - &log_timezone_string, - "GMT", - check_log_timezone, assign_log_timezone, show_log_timezone - }, - - { - {"DateStyle", PGC_USERSET, CLIENT_CONN_LOCALE, - gettext_noop("Sets the display format for date and time values."), - gettext_noop("Also controls interpretation of ambiguous " - "date inputs."), - GUC_LIST_INPUT | GUC_REPORT - }, - &datestyle_string, - "ISO, MDY", - check_datestyle, assign_datestyle, NULL - }, - - { - {"default_table_access_method", PGC_USERSET, CLIENT_CONN_STATEMENT, - gettext_noop("Sets the default table access method for new tables."), - NULL, - GUC_IS_NAME - }, - &default_table_access_method, - DEFAULT_TABLE_ACCESS_METHOD, - check_default_table_access_method, NULL, NULL - }, - - { - {"default_tablespace", PGC_USERSET, CLIENT_CONN_STATEMENT, - gettext_noop("Sets the default tablespace to create tables and indexes in."), - gettext_noop("An empty string selects the database's default tablespace."), - GUC_IS_NAME - }, - &default_tablespace, - "", - check_default_tablespace, NULL, NULL - }, - - { - {"temp_tablespaces", PGC_USERSET, CLIENT_CONN_STATEMENT, - gettext_noop("Sets the tablespace(s) to use for temporary tables and sort files."), - NULL, - GUC_LIST_INPUT | GUC_LIST_QUOTE - }, - &temp_tablespaces, - "", - check_temp_tablespaces, assign_temp_tablespaces, NULL - }, - - { - {"dynamic_library_path", PGC_SUSET, CLIENT_CONN_OTHER, - gettext_noop("Sets the path for dynamically loadable modules."), - gettext_noop("If a dynamically loadable module needs to be opened and " - "the specified name does not have a directory component (i.e., the " - "name does not contain a slash), the system will search this path for " - "the specified file."), - GUC_SUPERUSER_ONLY - }, - &Dynamic_library_path, - "$libdir", - NULL, NULL, NULL - }, - - { - {"krb_server_keyfile", PGC_SIGHUP, CONN_AUTH_AUTH, - gettext_noop("Sets the location of the Kerberos server key file."), - NULL, - GUC_SUPERUSER_ONLY - }, - &pg_krb_server_keyfile, - PG_KRB_SRVTAB, - NULL, NULL, NULL - }, - - { - {"bonjour_name", PGC_POSTMASTER, CONN_AUTH_SETTINGS, - gettext_noop("Sets the Bonjour service name."), - NULL - }, - &bonjour_name, - "", - NULL, NULL, NULL - }, - - /* See main.c about why defaults for LC_foo are not all alike */ - - { - {"lc_collate", PGC_INTERNAL, PRESET_OPTIONS, - gettext_noop("Shows the collation order locale."), - NULL, - GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE - }, - &locale_collate, - "C", - NULL, NULL, NULL - }, - - { - {"lc_ctype", PGC_INTERNAL, PRESET_OPTIONS, - gettext_noop("Shows the character classification and case conversion locale."), - NULL, - GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE - }, - &locale_ctype, - "C", - NULL, NULL, NULL - }, - - { - {"lc_messages", PGC_SUSET, CLIENT_CONN_LOCALE, - gettext_noop("Sets the language in which messages are displayed."), - NULL - }, - &locale_messages, - "", - check_locale_messages, assign_locale_messages, NULL - }, - - { - {"lc_monetary", PGC_USERSET, CLIENT_CONN_LOCALE, - gettext_noop("Sets the locale for formatting monetary amounts."), - NULL - }, - &locale_monetary, - "C", - check_locale_monetary, assign_locale_monetary, NULL - }, - - { - {"lc_numeric", PGC_USERSET, CLIENT_CONN_LOCALE, - gettext_noop("Sets the locale for formatting numbers."), - NULL - }, - &locale_numeric, - "C", - check_locale_numeric, assign_locale_numeric, NULL - }, - - { - {"lc_time", PGC_USERSET, CLIENT_CONN_LOCALE, - gettext_noop("Sets the locale for formatting date and time values."), - NULL - }, - &locale_time, - "C", - check_locale_time, assign_locale_time, NULL - }, - - { - {"session_preload_libraries", PGC_SUSET, CLIENT_CONN_PRELOAD, - gettext_noop("Lists shared libraries to preload into each backend."), - NULL, - GUC_LIST_INPUT | GUC_LIST_QUOTE | GUC_SUPERUSER_ONLY - }, - &session_preload_libraries_string, - "", - NULL, NULL, NULL - }, - - { - {"shared_preload_libraries", PGC_POSTMASTER, CLIENT_CONN_PRELOAD, - gettext_noop("Lists shared libraries to preload into server."), - NULL, - GUC_LIST_INPUT | GUC_LIST_QUOTE | GUC_SUPERUSER_ONLY - }, - &shared_preload_libraries_string, - "", - NULL, NULL, NULL - }, - - { - {"local_preload_libraries", PGC_USERSET, CLIENT_CONN_PRELOAD, - gettext_noop("Lists unprivileged shared libraries to preload into each backend."), - NULL, - GUC_LIST_INPUT | GUC_LIST_QUOTE - }, - &local_preload_libraries_string, - "", - NULL, NULL, NULL - }, - - { - {"search_path", PGC_USERSET, CLIENT_CONN_STATEMENT, - gettext_noop("Sets the schema search order for names that are not schema-qualified."), - NULL, - GUC_LIST_INPUT | GUC_LIST_QUOTE | GUC_EXPLAIN - }, - &namespace_search_path, - "\"$user\", public", - check_search_path, assign_search_path, NULL - }, - - { - /* Can't be set in postgresql.conf */ - {"server_encoding", PGC_INTERNAL, PRESET_OPTIONS, - gettext_noop("Shows the server (database) character set encoding."), - NULL, - GUC_IS_NAME | GUC_REPORT | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE - }, - &server_encoding_string, - "SQL_ASCII", - NULL, NULL, NULL - }, - - { - /* Can't be set in postgresql.conf */ - {"server_version", PGC_INTERNAL, PRESET_OPTIONS, - gettext_noop("Shows the server version."), - NULL, - GUC_REPORT | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE - }, - &server_version_string, - PG_VERSION, - NULL, NULL, NULL - }, - - { - /* Not for general use --- used by SET ROLE */ - {"role", PGC_USERSET, UNGROUPED, - gettext_noop("Sets the current role."), - NULL, - GUC_IS_NAME | GUC_NO_SHOW_ALL | GUC_NO_RESET_ALL | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE | GUC_NOT_WHILE_SEC_REST - }, - &role_string, - "none", - check_role, assign_role, show_role - }, - - { - /* Not for general use --- used by SET SESSION AUTHORIZATION */ - {"session_authorization", PGC_USERSET, UNGROUPED, - gettext_noop("Sets the session user name."), - NULL, - GUC_IS_NAME | GUC_REPORT | GUC_NO_SHOW_ALL | GUC_NO_RESET_ALL | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE | GUC_NOT_WHILE_SEC_REST - }, - &session_authorization_string, - NULL, - check_session_authorization, assign_session_authorization, NULL - }, - - { - {"log_destination", PGC_SIGHUP, LOGGING_WHERE, - gettext_noop("Sets the destination for server log output."), - gettext_noop("Valid values are combinations of \"stderr\", " - "\"syslog\", \"csvlog\", \"jsonlog\", and \"eventlog\", " - "depending on the platform."), - GUC_LIST_INPUT - }, - &Log_destination_string, - "stderr", - check_log_destination, assign_log_destination, NULL - }, - { - {"log_directory", PGC_SIGHUP, LOGGING_WHERE, - gettext_noop("Sets the destination directory for log files."), - gettext_noop("Can be specified as relative to the data directory " - "or as absolute path."), - GUC_SUPERUSER_ONLY - }, - &Log_directory, - "log", - check_canonical_path, NULL, NULL - }, - { - {"log_filename", PGC_SIGHUP, LOGGING_WHERE, - gettext_noop("Sets the file name pattern for log files."), - NULL, - GUC_SUPERUSER_ONLY - }, - &Log_filename, - "postgresql-%Y-%m-%d_%H%M%S.log", - NULL, NULL, NULL - }, - - { - {"syslog_ident", PGC_SIGHUP, LOGGING_WHERE, - gettext_noop("Sets the program name used to identify PostgreSQL " - "messages in syslog."), - NULL - }, - &syslog_ident_str, - "postgres", - NULL, assign_syslog_ident, NULL - }, - - { - {"event_source", PGC_POSTMASTER, LOGGING_WHERE, - gettext_noop("Sets the application name used to identify " - "PostgreSQL messages in the event log."), - NULL - }, - &event_source, - DEFAULT_EVENT_SOURCE, - NULL, NULL, NULL - }, - - { - {"TimeZone", PGC_USERSET, CLIENT_CONN_LOCALE, - gettext_noop("Sets the time zone for displaying and interpreting time stamps."), - NULL, - GUC_REPORT - }, - &timezone_string, - "GMT", - check_timezone, assign_timezone, show_timezone - }, - { - {"timezone_abbreviations", PGC_USERSET, CLIENT_CONN_LOCALE, - gettext_noop("Selects a file of time zone abbreviations."), - NULL - }, - &timezone_abbreviations_string, - NULL, - check_timezone_abbreviations, assign_timezone_abbreviations, NULL - }, - - { - {"unix_socket_group", PGC_POSTMASTER, CONN_AUTH_SETTINGS, - gettext_noop("Sets the owning group of the Unix-domain socket."), - gettext_noop("The owning user of the socket is always the user " - "that starts the server.") - }, - &Unix_socket_group, - "", - NULL, NULL, NULL - }, - - { - {"unix_socket_directories", PGC_POSTMASTER, CONN_AUTH_SETTINGS, - gettext_noop("Sets the directories where Unix-domain sockets will be created."), - NULL, - GUC_LIST_INPUT | GUC_LIST_QUOTE | GUC_SUPERUSER_ONLY - }, - &Unix_socket_directories, - DEFAULT_PGSOCKET_DIR, - NULL, NULL, NULL - }, - - { - {"listen_addresses", PGC_POSTMASTER, CONN_AUTH_SETTINGS, - gettext_noop("Sets the host name or IP address(es) to listen to."), - NULL, - GUC_LIST_INPUT - }, - &ListenAddresses, - "localhost", - NULL, NULL, NULL - }, - - { - /* - * Can't be set by ALTER SYSTEM as it can lead to recursive definition - * of data_directory. - */ - {"data_directory", PGC_POSTMASTER, FILE_LOCATIONS, - gettext_noop("Sets the server's data directory."), - NULL, - GUC_SUPERUSER_ONLY | GUC_DISALLOW_IN_AUTO_FILE - }, - &data_directory, - NULL, - NULL, NULL, NULL - }, - - { - {"config_file", PGC_POSTMASTER, FILE_LOCATIONS, - gettext_noop("Sets the server's main configuration file."), - NULL, - GUC_DISALLOW_IN_FILE | GUC_SUPERUSER_ONLY - }, - &ConfigFileName, - NULL, - NULL, NULL, NULL - }, - - { - {"hba_file", PGC_POSTMASTER, FILE_LOCATIONS, - gettext_noop("Sets the server's \"hba\" configuration file."), - NULL, - GUC_SUPERUSER_ONLY - }, - &HbaFileName, - NULL, - NULL, NULL, NULL - }, - - { - {"ident_file", PGC_POSTMASTER, FILE_LOCATIONS, - gettext_noop("Sets the server's \"ident\" configuration file."), - NULL, - GUC_SUPERUSER_ONLY - }, - &IdentFileName, - NULL, - NULL, NULL, NULL - }, - - { - {"external_pid_file", PGC_POSTMASTER, FILE_LOCATIONS, - gettext_noop("Writes the postmaster PID to the specified file."), - NULL, - GUC_SUPERUSER_ONLY - }, - &external_pid_file, - NULL, - check_canonical_path, NULL, NULL - }, - - { - {"ssl_library", PGC_INTERNAL, PRESET_OPTIONS, - gettext_noop("Shows the name of the SSL library."), - NULL, - GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE - }, - &ssl_library, -#ifdef USE_SSL - "OpenSSL", -#else - "", -#endif - NULL, NULL, NULL - }, - - { - {"ssl_cert_file", PGC_SIGHUP, CONN_AUTH_SSL, - gettext_noop("Location of the SSL server certificate file."), - NULL - }, - &ssl_cert_file, - "server.crt", - NULL, NULL, NULL - }, - - { - {"ssl_key_file", PGC_SIGHUP, CONN_AUTH_SSL, - gettext_noop("Location of the SSL server private key file."), - NULL - }, - &ssl_key_file, - "server.key", - NULL, NULL, NULL - }, - - { - {"ssl_ca_file", PGC_SIGHUP, CONN_AUTH_SSL, - gettext_noop("Location of the SSL certificate authority file."), - NULL - }, - &ssl_ca_file, - "", - NULL, NULL, NULL - }, - - { - {"ssl_crl_file", PGC_SIGHUP, CONN_AUTH_SSL, - gettext_noop("Location of the SSL certificate revocation list file."), - NULL - }, - &ssl_crl_file, - "", - NULL, NULL, NULL - }, - - { - {"ssl_crl_dir", PGC_SIGHUP, CONN_AUTH_SSL, - gettext_noop("Location of the SSL certificate revocation list directory."), - NULL - }, - &ssl_crl_dir, - "", - NULL, NULL, NULL - }, - - { - {"synchronous_standby_names", PGC_SIGHUP, REPLICATION_PRIMARY, - gettext_noop("Number of synchronous standbys and list of names of potential synchronous ones."), - NULL, - GUC_LIST_INPUT - }, - &SyncRepStandbyNames, - "", - check_synchronous_standby_names, assign_synchronous_standby_names, NULL - }, - - { - {"default_text_search_config", PGC_USERSET, CLIENT_CONN_LOCALE, - gettext_noop("Sets default text search configuration."), - NULL - }, - &TSCurrentConfig, - "pg_catalog.simple", - check_TSCurrentConfig, assign_TSCurrentConfig, NULL - }, - - { - {"ssl_ciphers", PGC_SIGHUP, CONN_AUTH_SSL, - gettext_noop("Sets the list of allowed SSL ciphers."), - NULL, - GUC_SUPERUSER_ONLY - }, - &SSLCipherSuites, -#ifdef USE_OPENSSL - "HIGH:MEDIUM:+3DES:!aNULL", -#else - "none", -#endif - NULL, NULL, NULL - }, - - { - {"ssl_ecdh_curve", PGC_SIGHUP, CONN_AUTH_SSL, - gettext_noop("Sets the curve to use for ECDH."), - NULL, - GUC_SUPERUSER_ONLY - }, - &SSLECDHCurve, -#ifdef USE_SSL - "prime256v1", -#else - "none", -#endif - NULL, NULL, NULL - }, - - { - {"ssl_dh_params_file", PGC_SIGHUP, CONN_AUTH_SSL, - gettext_noop("Location of the SSL DH parameters file."), - NULL, - GUC_SUPERUSER_ONLY - }, - &ssl_dh_params_file, - "", - NULL, NULL, NULL - }, - - { - {"ssl_passphrase_command", PGC_SIGHUP, CONN_AUTH_SSL, - gettext_noop("Command to obtain passphrases for SSL."), - NULL, - GUC_SUPERUSER_ONLY - }, - &ssl_passphrase_command, - "", - NULL, NULL, NULL - }, - - { - {"application_name", PGC_USERSET, LOGGING_WHAT, - gettext_noop("Sets the application name to be reported in statistics and logs."), - NULL, - GUC_IS_NAME | GUC_REPORT | GUC_NOT_IN_SAMPLE - }, - &application_name, - "", - check_application_name, assign_application_name, NULL - }, - - { - {"cluster_name", PGC_POSTMASTER, PROCESS_TITLE, - gettext_noop("Sets the name of the cluster, which is included in the process title."), - NULL, - GUC_IS_NAME - }, - &cluster_name, - "", - check_cluster_name, NULL, NULL - }, - - { - {"wal_consistency_checking", PGC_SUSET, DEVELOPER_OPTIONS, - gettext_noop("Sets the WAL resource managers for which WAL consistency checks are done."), - gettext_noop("Full-page images will be logged for all data blocks and cross-checked against the results of WAL replay."), - GUC_LIST_INPUT | GUC_NOT_IN_SAMPLE - }, - &wal_consistency_checking_string, - "", - check_wal_consistency_checking, assign_wal_consistency_checking, NULL - }, - - { - {"jit_provider", PGC_POSTMASTER, CLIENT_CONN_PRELOAD, - gettext_noop("JIT provider to use."), - NULL, - GUC_SUPERUSER_ONLY - }, - &jit_provider, - "llvmjit", - NULL, NULL, NULL - }, - - { - {"backtrace_functions", PGC_SUSET, DEVELOPER_OPTIONS, - gettext_noop("Log backtrace for errors in these functions."), - NULL, - GUC_NOT_IN_SAMPLE - }, - &backtrace_functions, - "", - check_backtrace_functions, assign_backtrace_functions, NULL - }, - - /* End-of-list marker */ - { - {NULL, 0, 0, NULL, NULL}, NULL, NULL, NULL, NULL, NULL - } -}; - - -static struct config_enum ConfigureNamesEnum[] = -{ - { - {"backslash_quote", PGC_USERSET, COMPAT_OPTIONS_PREVIOUS, - gettext_noop("Sets whether \"\\'\" is allowed in string literals."), - NULL - }, - &backslash_quote, - BACKSLASH_QUOTE_SAFE_ENCODING, backslash_quote_options, - NULL, NULL, NULL - }, - - { - {"bytea_output", PGC_USERSET, CLIENT_CONN_STATEMENT, - gettext_noop("Sets the output format for bytea."), - NULL - }, - &bytea_output, - BYTEA_OUTPUT_HEX, bytea_output_options, - NULL, NULL, NULL - }, - - { - {"client_min_messages", PGC_USERSET, CLIENT_CONN_STATEMENT, - gettext_noop("Sets the message levels that are sent to the client."), - gettext_noop("Each level includes all the levels that follow it. The later" - " the level, the fewer messages are sent.") - }, - &client_min_messages, - NOTICE, client_message_level_options, - NULL, NULL, NULL - }, - - { - {"compute_query_id", PGC_SUSET, STATS_MONITORING, - gettext_noop("Enables in-core computation of query identifiers."), - NULL - }, - &compute_query_id, - COMPUTE_QUERY_ID_AUTO, compute_query_id_options, - NULL, NULL, NULL - }, - - { - {"constraint_exclusion", PGC_USERSET, QUERY_TUNING_OTHER, - gettext_noop("Enables the planner to use constraints to optimize queries."), - gettext_noop("Table scans will be skipped if their constraints" - " guarantee that no rows match the query."), - GUC_EXPLAIN - }, - &constraint_exclusion, - CONSTRAINT_EXCLUSION_PARTITION, constraint_exclusion_options, - NULL, NULL, NULL - }, - - { - {"default_toast_compression", PGC_USERSET, CLIENT_CONN_STATEMENT, - gettext_noop("Sets the default compression method for compressible values."), - NULL - }, - &default_toast_compression, - TOAST_PGLZ_COMPRESSION, - default_toast_compression_options, - NULL, NULL, NULL - }, - - { - {"default_transaction_isolation", PGC_USERSET, CLIENT_CONN_STATEMENT, - gettext_noop("Sets the transaction isolation level of each new transaction."), - NULL - }, - &DefaultXactIsoLevel, - XACT_READ_COMMITTED, isolation_level_options, - NULL, NULL, NULL - }, - - { - {"transaction_isolation", PGC_USERSET, CLIENT_CONN_STATEMENT, - gettext_noop("Sets the current transaction's isolation level."), - NULL, - GUC_NO_RESET_ALL | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE - }, - &XactIsoLevel, - XACT_READ_COMMITTED, isolation_level_options, - check_XactIsoLevel, NULL, NULL - }, - - { - {"IntervalStyle", PGC_USERSET, CLIENT_CONN_LOCALE, - gettext_noop("Sets the display format for interval values."), - NULL, - GUC_REPORT - }, - &IntervalStyle, - INTSTYLE_POSTGRES, intervalstyle_options, - NULL, NULL, NULL - }, - - { - {"log_error_verbosity", PGC_SUSET, LOGGING_WHAT, - gettext_noop("Sets the verbosity of logged messages."), - NULL - }, - &Log_error_verbosity, - PGERROR_DEFAULT, log_error_verbosity_options, - NULL, NULL, NULL - }, - - { - {"log_min_messages", PGC_SUSET, LOGGING_WHEN, - gettext_noop("Sets the message levels that are logged."), - gettext_noop("Each level includes all the levels that follow it. The later" - " the level, the fewer messages are sent.") - }, - &log_min_messages, - WARNING, server_message_level_options, - NULL, NULL, NULL - }, - - { - {"log_min_error_statement", PGC_SUSET, LOGGING_WHEN, - gettext_noop("Causes all statements generating error at or above this level to be logged."), - gettext_noop("Each level includes all the levels that follow it. The later" - " the level, the fewer messages are sent.") - }, - &log_min_error_statement, - ERROR, server_message_level_options, - NULL, NULL, NULL - }, - - { - {"log_statement", PGC_SUSET, LOGGING_WHAT, - gettext_noop("Sets the type of statements logged."), - NULL - }, - &log_statement, - LOGSTMT_NONE, log_statement_options, - NULL, NULL, NULL - }, - - { - {"syslog_facility", PGC_SIGHUP, LOGGING_WHERE, - gettext_noop("Sets the syslog \"facility\" to be used when syslog enabled."), - NULL - }, - &syslog_facility, -#ifdef HAVE_SYSLOG - LOG_LOCAL0, -#else - 0, -#endif - syslog_facility_options, - NULL, assign_syslog_facility, NULL - }, - - { - {"session_replication_role", PGC_SUSET, CLIENT_CONN_STATEMENT, - gettext_noop("Sets the session's behavior for triggers and rewrite rules."), - NULL - }, - &SessionReplicationRole, - SESSION_REPLICATION_ROLE_ORIGIN, session_replication_role_options, - NULL, assign_session_replication_role, NULL - }, - - { - {"synchronous_commit", PGC_USERSET, WAL_SETTINGS, - gettext_noop("Sets the current transaction's synchronization level."), - NULL - }, - &synchronous_commit, - SYNCHRONOUS_COMMIT_ON, synchronous_commit_options, - NULL, assign_synchronous_commit, NULL - }, - - { - {"archive_mode", PGC_POSTMASTER, WAL_ARCHIVING, - gettext_noop("Allows archiving of WAL files using archive_command."), - NULL - }, - &XLogArchiveMode, - ARCHIVE_MODE_OFF, archive_mode_options, - NULL, NULL, NULL - }, - - { - {"recovery_target_action", PGC_POSTMASTER, WAL_RECOVERY_TARGET, - gettext_noop("Sets the action to perform upon reaching the recovery target."), - NULL - }, - &recoveryTargetAction, - RECOVERY_TARGET_ACTION_PAUSE, recovery_target_action_options, - NULL, NULL, NULL - }, - - { - {"trace_recovery_messages", PGC_SIGHUP, DEVELOPER_OPTIONS, - gettext_noop("Enables logging of recovery-related debugging information."), - gettext_noop("Each level includes all the levels that follow it. The later" - " the level, the fewer messages are sent."), - GUC_NOT_IN_SAMPLE, - }, - &trace_recovery_messages, - - /* - * client_message_level_options allows too many values, really, but - * it's not worth having a separate options array for this. - */ - LOG, client_message_level_options, - NULL, NULL, NULL - }, - - { - {"track_functions", PGC_SUSET, STATS_CUMULATIVE, - gettext_noop("Collects function-level statistics on database activity."), - NULL - }, - &pgstat_track_functions, - TRACK_FUNC_OFF, track_function_options, - NULL, NULL, NULL - }, - - - { - {"stats_fetch_consistency", PGC_USERSET, STATS_CUMULATIVE, - gettext_noop("Sets the consistency of accesses to statistics data."), - NULL - }, - &pgstat_fetch_consistency, - PGSTAT_FETCH_CONSISTENCY_CACHE, stats_fetch_consistency, - NULL, NULL, NULL - }, - - { - {"wal_compression", PGC_SUSET, WAL_SETTINGS, - gettext_noop("Compresses full-page writes written in WAL file with specified method."), - NULL - }, - &wal_compression, - WAL_COMPRESSION_NONE, wal_compression_options, - NULL, NULL, NULL - }, - - { - {"wal_level", PGC_POSTMASTER, WAL_SETTINGS, - gettext_noop("Sets the level of information written to the WAL."), - NULL - }, - &wal_level, - WAL_LEVEL_REPLICA, wal_level_options, - NULL, NULL, NULL - }, - - { - {"dynamic_shared_memory_type", PGC_POSTMASTER, RESOURCES_MEM, - gettext_noop("Selects the dynamic shared memory implementation used."), - NULL - }, - &dynamic_shared_memory_type, - DEFAULT_DYNAMIC_SHARED_MEMORY_TYPE, dynamic_shared_memory_options, - NULL, NULL, NULL - }, - - { - {"shared_memory_type", PGC_POSTMASTER, RESOURCES_MEM, - gettext_noop("Selects the shared memory implementation used for the main shared memory region."), - NULL - }, - &shared_memory_type, - DEFAULT_SHARED_MEMORY_TYPE, shared_memory_options, - NULL, NULL, NULL - }, - - { - {"wal_sync_method", PGC_SIGHUP, WAL_SETTINGS, - gettext_noop("Selects the method used for forcing WAL updates to disk."), - NULL - }, - &sync_method, - DEFAULT_SYNC_METHOD, sync_method_options, - NULL, assign_xlog_sync_method, NULL - }, - - { - {"xmlbinary", PGC_USERSET, CLIENT_CONN_STATEMENT, - gettext_noop("Sets how binary values are to be encoded in XML."), - NULL - }, - &xmlbinary, - XMLBINARY_BASE64, xmlbinary_options, - NULL, NULL, NULL - }, - - { - {"xmloption", PGC_USERSET, CLIENT_CONN_STATEMENT, - gettext_noop("Sets whether XML data in implicit parsing and serialization " - "operations is to be considered as documents or content fragments."), - NULL - }, - &xmloption, - XMLOPTION_CONTENT, xmloption_options, - NULL, NULL, NULL - }, - - { - {"huge_pages", PGC_POSTMASTER, RESOURCES_MEM, - gettext_noop("Use of huge pages on Linux or Windows."), - NULL - }, - &huge_pages, - HUGE_PAGES_TRY, huge_pages_options, - NULL, NULL, NULL - }, - - { - {"recovery_prefetch", PGC_SIGHUP, WAL_RECOVERY, - gettext_noop("Prefetch referenced blocks during recovery."), - gettext_noop("Look ahead in the WAL to find references to uncached data.") - }, - &recovery_prefetch, - RECOVERY_PREFETCH_TRY, recovery_prefetch_options, - check_recovery_prefetch, assign_recovery_prefetch, NULL - }, - - { - {"force_parallel_mode", PGC_USERSET, DEVELOPER_OPTIONS, - gettext_noop("Forces use of parallel query facilities."), - gettext_noop("If possible, run query using a parallel worker and with parallel restrictions."), - GUC_NOT_IN_SAMPLE | GUC_EXPLAIN - }, - &force_parallel_mode, - FORCE_PARALLEL_OFF, force_parallel_mode_options, - NULL, NULL, NULL - }, - - { - {"password_encryption", PGC_USERSET, CONN_AUTH_AUTH, - gettext_noop("Chooses the algorithm for encrypting passwords."), - NULL - }, - &Password_encryption, - PASSWORD_TYPE_SCRAM_SHA_256, password_encryption_options, - NULL, NULL, NULL - }, - - { - {"plan_cache_mode", PGC_USERSET, QUERY_TUNING_OTHER, - gettext_noop("Controls the planner's selection of custom or generic plan."), - gettext_noop("Prepared statements can have custom and generic plans, and the planner " - "will attempt to choose which is better. This can be set to override " - "the default behavior."), - GUC_EXPLAIN - }, - &plan_cache_mode, - PLAN_CACHE_MODE_AUTO, plan_cache_mode_options, - NULL, NULL, NULL - }, - - { - {"ssl_min_protocol_version", PGC_SIGHUP, CONN_AUTH_SSL, - gettext_noop("Sets the minimum SSL/TLS protocol version to use."), - NULL, - GUC_SUPERUSER_ONLY - }, - &ssl_min_protocol_version, - PG_TLS1_2_VERSION, - ssl_protocol_versions_info + 1, /* don't allow PG_TLS_ANY */ - NULL, NULL, NULL - }, - - { - {"ssl_max_protocol_version", PGC_SIGHUP, CONN_AUTH_SSL, - gettext_noop("Sets the maximum SSL/TLS protocol version to use."), - NULL, - GUC_SUPERUSER_ONLY - }, - &ssl_max_protocol_version, - PG_TLS_ANY, - ssl_protocol_versions_info, - NULL, NULL, NULL - }, - - { - {"recovery_init_sync_method", PGC_SIGHUP, ERROR_HANDLING_OPTIONS, - gettext_noop("Sets the method for synchronizing the data directory before crash recovery."), - }, - &recovery_init_sync_method, - RECOVERY_INIT_SYNC_METHOD_FSYNC, recovery_init_sync_method_options, - NULL, NULL, NULL - }, - - /* End-of-list marker */ - { - {NULL, 0, 0, NULL, NULL}, NULL, 0, NULL, NULL, NULL, NULL - } -}; - -/******** end of options list ********/ - - /* * To allow continued support of obsolete names for GUC variables, we apply * the following mappings to any unrecognized name. Note that an old name @@ -5157,27 +209,39 @@ static bool report_needed; /* true if any GUC_REPORT reports are needed */ static int GUCNestLevel = 0; /* 1 when in main transaction */ -static struct config_generic *find_option(const char *name, bool create_placeholders, bool skip_errors, int elevel); static int guc_var_compare(const void *a, const void *b); static void InitializeGUCOptionsFromEnvironment(void); static void InitializeOneGUCOption(struct config_generic *gconf); +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 void ShowGUCConfigOption(const char *name, DestReceiver *dest); -static void ShowAllGUCConfig(DestReceiver *dest); -static char *_ShowOption(struct config_generic *record, bool use_units); 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_p); 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, 4); +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); + /* * This function handles both actual config file (re)loads and execution of @@ -5534,7 +598,7 @@ bail_out: /* * Some infrastructure for checking malloc/strdup/realloc calls */ -static void * +void * guc_malloc(int elevel, size_t size) { void *data; @@ -5550,7 +614,7 @@ guc_malloc(int elevel, size_t size) return data; } -static void * +void * guc_realloc(int elevel, void *old, size_t size) { void *data; @@ -5566,7 +630,7 @@ guc_realloc(int elevel, void *old, size_t size) return data; } -static char * +char * guc_strdup(int elevel, const char *src) { char *data; @@ -5979,7 +1043,7 @@ add_placeholder_variable(const char *name, int elevel) * can only happen when create_placeholders is true, so callers passing * false need not think terribly hard about this.) */ -static struct config_generic * +struct config_generic * find_option(const char *name, bool create_placeholders, bool skip_errors, int elevel) { @@ -6226,35 +1290,6 @@ InitializeGUCOptions(void) InitializeGUCOptionsFromEnvironment(); } -/* - * If any custom resource managers were specified in the - * wal_consistency_checking GUC, processing was deferred. Now that - * shared_preload_libraries have been loaded, process wal_consistency_checking - * again. - */ -void -InitializeWalConsistencyChecking(void) -{ - Assert(process_shared_preload_libraries_done); - - if (check_wal_consistency_checking_deferred) - { - struct config_generic *guc; - - guc = find_option("wal_consistency_checking", false, false, ERROR); - - check_wal_consistency_checking_deferred = false; - - set_config_option_ext("wal_consistency_checking", - wal_consistency_checking_string, - guc->scontext, guc->source, guc->srole, - GUC_ACTION_SET, true, ERROR, false); - - /* checking should not be deferred again */ - Assert(!check_wal_consistency_checking_deferred); - } -} - /* * Assign any GUC values that can come from the server's environment. * @@ -6448,6 +1483,7 @@ SelectConfigFiles(const char *userDoption, const char *progname) char *configdir; char *fname; struct stat stat_buf; + struct config_string *data_directory_rec; /* configdir is -D option, or $PGDATA if no -D */ if (userDoption) @@ -6521,8 +1557,10 @@ SelectConfigFiles(const char *userDoption, const char *progname) * Note: SetDataDir will copy and absolute-ize its argument, so we don't * have to. */ - if (data_directory) - SetDataDir(data_directory); + data_directory_rec = (struct config_string *) + find_option("data_directory", false, false, PANIC); + if (*data_directory_rec->variable) + SetDataDir(*data_directory_rec->variable); else if (configdir) SetDataDir(configdir); else @@ -6613,6 +1651,23 @@ SelectConfigFiles(const char *userDoption, const char *progname) return true; } +/* + * pg_timezone_abbrev_initialize --- set default value if not done already + * + * This is called after initial loading of postgresql.conf. If no + * timezone_abbreviations setting was found therein, select default. + * If a non-default value is already installed, nothing will happen. + * + * This can also be called from ProcessConfigFile to establish the default + * value after a postgresql.conf entry for it is removed. + */ +static void +pg_timezone_abbrev_initialize(void) +{ + SetConfigOption("timezone_abbreviations", "Default", + PGC_POSTMASTER, PGC_S_DYNAMIC_DEFAULT); +} + /* * Reset all options to their saved default values (implements RESET ALL) @@ -7192,7 +2247,7 @@ ReportChangedGUCOptions(void) * client. For speed, we rely on the assumption that it can never * transition from false to true. */ - if (in_hot_standby && !RecoveryInProgress()) + if (in_hot_standby_guc && !RecoveryInProgress()) SetConfigOption("in_hot_standby", "false", PGC_INTERNAL, PGC_S_OVERRIDE); @@ -7221,7 +2276,7 @@ ReportChangedGUCOptions(void) static void ReportGUCOption(struct config_generic *record) { - char *val = _ShowOption(record, false); + char *val = ShowGUCOption(record, false); if (record->last_reported == NULL || strcmp(val, record->last_reported) != 0) @@ -7400,7 +2455,7 @@ convert_real_from_base_unit(double base_value, int base_unit, * Return the name of a GUC's base unit (e.g. "ms") given its flags. * Return NULL if the GUC is unitless. */ -static const char * +const char * get_config_unit_name(int flags) { switch (flags & (GUC_UNIT_MEMORY | GUC_UNIT_TIME)) @@ -7653,12 +2708,12 @@ config_enum_lookup_by_name(struct config_enum *record, const char *value, /* - * Return a list of all available options for an enum, excluding - * hidden ones, separated by the given separator. + * Return a palloc'd string listing all the available options for an enum GUC + * (excluding hidden ones), separated by the given separator. * If prefix is non-NULL, it is added before the first enum value. * If suffix is non-NULL, it is added to the end of the string. */ -static char * +char * config_enum_get_options(struct config_enum *record, const char *prefix, const char *suffix, const char *separator) { @@ -8919,134 +3974,6 @@ GetConfigOptionFlags(const char *name, bool missing_ok) } -/* - * flatten_set_variable_args - * Given a parsenode List as emitted by the grammar for SET, - * convert to the flat string representation used by GUC. - * - * We need to be told the name of the variable the args are for, because - * the flattening rules vary (ugh). - * - * The result is NULL if args is NIL (i.e., SET ... TO DEFAULT), otherwise - * a palloc'd string. - */ -static char * -flatten_set_variable_args(const char *name, List *args) -{ - struct config_generic *record; - int flags; - StringInfoData buf; - ListCell *l; - - /* Fast path if just DEFAULT */ - if (args == NIL) - return NULL; - - /* - * Get flags for the variable; if it's not known, use default flags. - * (Caller might throw error later, but not our business to do so here.) - */ - record = find_option(name, false, true, WARNING); - if (record) - flags = record->flags; - else - flags = 0; - - /* Complain if list input and non-list variable */ - if ((flags & GUC_LIST_INPUT) == 0 && - list_length(args) != 1) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("SET %s takes only one argument", name))); - - initStringInfo(&buf); - - /* - * Each list member may be a plain A_Const node, or an A_Const within a - * TypeCast; the latter case is supported only for ConstInterval arguments - * (for SET TIME ZONE). - */ - foreach(l, args) - { - Node *arg = (Node *) lfirst(l); - char *val; - TypeName *typeName = NULL; - A_Const *con; - - if (l != list_head(args)) - appendStringInfoString(&buf, ", "); - - if (IsA(arg, TypeCast)) - { - TypeCast *tc = (TypeCast *) arg; - - arg = tc->arg; - typeName = tc->typeName; - } - - if (!IsA(arg, A_Const)) - elog(ERROR, "unrecognized node type: %d", (int) nodeTag(arg)); - con = (A_Const *) arg; - - switch (nodeTag(&con->val)) - { - case T_Integer: - appendStringInfo(&buf, "%d", intVal(&con->val)); - break; - case T_Float: - /* represented as a string, so just copy it */ - appendStringInfoString(&buf, castNode(Float, &con->val)->fval); - break; - case T_String: - val = strVal(&con->val); - if (typeName != NULL) - { - /* - * Must be a ConstInterval argument for TIME ZONE. Coerce - * to interval and back to normalize the value and account - * for any typmod. - */ - Oid typoid; - int32 typmod; - Datum interval; - char *intervalout; - - typenameTypeIdAndMod(NULL, typeName, &typoid, &typmod); - Assert(typoid == INTERVALOID); - - interval = - DirectFunctionCall3(interval_in, - CStringGetDatum(val), - ObjectIdGetDatum(InvalidOid), - Int32GetDatum(typmod)); - - intervalout = - DatumGetCString(DirectFunctionCall1(interval_out, - interval)); - appendStringInfo(&buf, "INTERVAL '%s'", intervalout); - } - else - { - /* - * Plain string literal or identifier. For quote mode, - * quote it if it's not a vanilla identifier. - */ - if (flags & GUC_LIST_QUOTE) - appendStringInfoString(&buf, quote_identifier(val)); - else - appendStringInfoString(&buf, val); - } - break; - default: - elog(ERROR, "unrecognized node type: %d", - (int) nodeTag(&con->val)); - break; - } - } - - return buf.data; -} - /* * Write updated configuration parameter values into a temporary file. * This function traverses the list of parameters and quotes the string @@ -9431,219 +4358,6 @@ AlterSystemSetConfigFile(AlterSystemStmt *altersysstmt) LWLockRelease(AutoFileLock); } -/* - * SET command - */ -void -ExecSetVariableStmt(VariableSetStmt *stmt, bool isTopLevel) -{ - GucAction action = stmt->is_local ? GUC_ACTION_LOCAL : GUC_ACTION_SET; - - /* - * Workers synchronize these parameters at the start of the parallel - * operation; then, we block SET during the operation. - */ - if (IsInParallelMode()) - ereport(ERROR, - (errcode(ERRCODE_INVALID_TRANSACTION_STATE), - errmsg("cannot set parameters during a parallel operation"))); - - switch (stmt->kind) - { - case VAR_SET_VALUE: - case VAR_SET_CURRENT: - if (stmt->is_local) - WarnNoTransactionBlock(isTopLevel, "SET LOCAL"); - (void) set_config_option(stmt->name, - ExtractSetVariableArgs(stmt), - (superuser() ? PGC_SUSET : PGC_USERSET), - PGC_S_SESSION, - action, true, 0, false); - break; - case VAR_SET_MULTI: - - /* - * Special-case SQL syntaxes. The TRANSACTION and SESSION - * CHARACTERISTICS cases effectively set more than one variable - * per statement. TRANSACTION SNAPSHOT only takes one argument, - * but we put it here anyway since it's a special case and not - * related to any GUC variable. - */ - if (strcmp(stmt->name, "TRANSACTION") == 0) - { - ListCell *head; - - WarnNoTransactionBlock(isTopLevel, "SET TRANSACTION"); - - foreach(head, stmt->args) - { - DefElem *item = (DefElem *) lfirst(head); - - if (strcmp(item->defname, "transaction_isolation") == 0) - SetPGVariable("transaction_isolation", - list_make1(item->arg), stmt->is_local); - else if (strcmp(item->defname, "transaction_read_only") == 0) - SetPGVariable("transaction_read_only", - list_make1(item->arg), stmt->is_local); - else if (strcmp(item->defname, "transaction_deferrable") == 0) - SetPGVariable("transaction_deferrable", - list_make1(item->arg), stmt->is_local); - else - elog(ERROR, "unexpected SET TRANSACTION element: %s", - item->defname); - } - } - else if (strcmp(stmt->name, "SESSION CHARACTERISTICS") == 0) - { - ListCell *head; - - foreach(head, stmt->args) - { - DefElem *item = (DefElem *) lfirst(head); - - if (strcmp(item->defname, "transaction_isolation") == 0) - SetPGVariable("default_transaction_isolation", - list_make1(item->arg), stmt->is_local); - else if (strcmp(item->defname, "transaction_read_only") == 0) - SetPGVariable("default_transaction_read_only", - list_make1(item->arg), stmt->is_local); - else if (strcmp(item->defname, "transaction_deferrable") == 0) - SetPGVariable("default_transaction_deferrable", - list_make1(item->arg), stmt->is_local); - else - elog(ERROR, "unexpected SET SESSION element: %s", - item->defname); - } - } - else if (strcmp(stmt->name, "TRANSACTION SNAPSHOT") == 0) - { - A_Const *con = linitial_node(A_Const, stmt->args); - - if (stmt->is_local) - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("SET LOCAL TRANSACTION SNAPSHOT is not implemented"))); - - WarnNoTransactionBlock(isTopLevel, "SET TRANSACTION"); - ImportSnapshot(strVal(&con->val)); - } - else - elog(ERROR, "unexpected SET MULTI element: %s", - stmt->name); - break; - case VAR_SET_DEFAULT: - if (stmt->is_local) - WarnNoTransactionBlock(isTopLevel, "SET LOCAL"); - /* fall through */ - case VAR_RESET: - if (strcmp(stmt->name, "transaction_isolation") == 0) - WarnNoTransactionBlock(isTopLevel, "RESET TRANSACTION"); - - (void) set_config_option(stmt->name, - NULL, - (superuser() ? PGC_SUSET : PGC_USERSET), - PGC_S_SESSION, - action, true, 0, false); - break; - case VAR_RESET_ALL: - ResetAllOptions(); - break; - } - - /* Invoke the post-alter hook for setting this GUC variable, by name. */ - InvokeObjectPostAlterHookArgStr(ParameterAclRelationId, stmt->name, - ACL_SET, stmt->kind, false); -} - -/* - * Get the value to assign for a VariableSetStmt, or NULL if it's RESET. - * The result is palloc'd. - * - * This is exported for use by actions such as ALTER ROLE SET. - */ -char * -ExtractSetVariableArgs(VariableSetStmt *stmt) -{ - switch (stmt->kind) - { - case VAR_SET_VALUE: - return flatten_set_variable_args(stmt->name, stmt->args); - case VAR_SET_CURRENT: - return GetConfigOptionByName(stmt->name, NULL, false); - default: - return NULL; - } -} - -/* - * SetPGVariable - SET command exported as an easily-C-callable function. - * - * This provides access to SET TO value, as well as SET TO DEFAULT (expressed - * by passing args == NIL), but not SET FROM CURRENT functionality. - */ -void -SetPGVariable(const char *name, List *args, bool is_local) -{ - char *argstring = flatten_set_variable_args(name, args); - - /* Note SET DEFAULT (argstring == NULL) is equivalent to RESET */ - (void) set_config_option(name, - argstring, - (superuser() ? PGC_SUSET : PGC_USERSET), - PGC_S_SESSION, - is_local ? GUC_ACTION_LOCAL : GUC_ACTION_SET, - true, 0, false); -} - -/* - * SET command wrapped as a SQL callable function. - */ -Datum -set_config_by_name(PG_FUNCTION_ARGS) -{ - char *name; - char *value; - char *new_value; - bool is_local; - - if (PG_ARGISNULL(0)) - ereport(ERROR, - (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED), - errmsg("SET requires parameter name"))); - - /* Get the GUC variable name */ - name = TextDatumGetCString(PG_GETARG_DATUM(0)); - - /* Get the desired value or set to NULL for a reset request */ - if (PG_ARGISNULL(1)) - value = NULL; - else - value = TextDatumGetCString(PG_GETARG_DATUM(1)); - - /* - * Get the desired state of is_local. Default to false if provided value - * is NULL - */ - if (PG_ARGISNULL(2)) - is_local = false; - else - is_local = PG_GETARG_BOOL(2); - - /* Note SET DEFAULT (argstring == NULL) is equivalent to RESET */ - (void) set_config_option(name, - value, - (superuser() ? PGC_SUSET : PGC_USERSET), - PGC_S_SESSION, - is_local ? GUC_ACTION_LOCAL : GUC_ACTION_SET, - true, 0, false); - - /* get the new current value */ - new_value = GetConfigOptionByName(name, NULL, false); - - /* Convert return string to text */ - PG_RETURN_TEXT_P(cstring_to_text(new_value)); -} - /* * Common code for DefineCustomXXXVariable subroutines: allocate the @@ -10086,155 +4800,6 @@ MarkGUCPrefixReserved(const char *className) } -/* - * SHOW command - */ -void -GetPGVariable(const char *name, DestReceiver *dest) -{ - if (guc_name_compare(name, "all") == 0) - ShowAllGUCConfig(dest); - else - ShowGUCConfigOption(name, dest); -} - -TupleDesc -GetPGVariableResultDesc(const char *name) -{ - TupleDesc tupdesc; - - if (guc_name_compare(name, "all") == 0) - { - /* need a tuple descriptor representing three TEXT columns */ - tupdesc = CreateTemplateTupleDesc(3); - TupleDescInitEntry(tupdesc, (AttrNumber) 1, "name", - TEXTOID, -1, 0); - TupleDescInitEntry(tupdesc, (AttrNumber) 2, "setting", - TEXTOID, -1, 0); - TupleDescInitEntry(tupdesc, (AttrNumber) 3, "description", - TEXTOID, -1, 0); - } - else - { - const char *varname; - - /* Get the canonical spelling of name */ - (void) GetConfigOptionByName(name, &varname, false); - - /* need a tuple descriptor representing a single TEXT column */ - tupdesc = CreateTemplateTupleDesc(1); - TupleDescInitEntry(tupdesc, (AttrNumber) 1, varname, - TEXTOID, -1, 0); - } - return tupdesc; -} - - -/* - * SHOW command - */ -static void -ShowGUCConfigOption(const char *name, DestReceiver *dest) -{ - TupOutputState *tstate; - TupleDesc tupdesc; - const char *varname; - char *value; - - /* Get the value and canonical spelling of name */ - value = GetConfigOptionByName(name, &varname, false); - - /* need a tuple descriptor representing a single TEXT column */ - tupdesc = CreateTemplateTupleDesc(1); - TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 1, varname, - TEXTOID, -1, 0); - - /* prepare for projection of tuples */ - tstate = begin_tup_output_tupdesc(dest, tupdesc, &TTSOpsVirtual); - - /* Send it */ - do_text_output_oneline(tstate, value); - - end_tup_output(tstate); -} - -/* - * SHOW ALL command - */ -static void -ShowAllGUCConfig(DestReceiver *dest) -{ - int i; - TupOutputState *tstate; - TupleDesc tupdesc; - Datum values[3]; - bool isnull[3] = {false, false, false}; - - /* need a tuple descriptor representing three TEXT columns */ - tupdesc = CreateTemplateTupleDesc(3); - TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 1, "name", - TEXTOID, -1, 0); - TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 2, "setting", - TEXTOID, -1, 0); - TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 3, "description", - TEXTOID, -1, 0); - - /* prepare for projection of tuples */ - tstate = begin_tup_output_tupdesc(dest, tupdesc, &TTSOpsVirtual); - - for (i = 0; i < num_guc_variables; i++) - { - struct config_generic *conf = guc_variables[i]; - char *setting; - - if ((conf->flags & GUC_NO_SHOW_ALL) || - ((conf->flags & GUC_SUPERUSER_ONLY) && - !has_privs_of_role(GetUserId(), ROLE_PG_READ_ALL_SETTINGS))) - continue; - - /* assign to the values array */ - values[0] = PointerGetDatum(cstring_to_text(conf->name)); - - setting = _ShowOption(conf, true); - if (setting) - { - values[1] = PointerGetDatum(cstring_to_text(setting)); - isnull[1] = false; - } - else - { - values[1] = PointerGetDatum(NULL); - isnull[1] = true; - } - - if (conf->short_desc) - { - values[2] = PointerGetDatum(cstring_to_text(conf->short_desc)); - isnull[2] = false; - } - else - { - values[2] = PointerGetDatum(NULL); - isnull[2] = true; - } - - /* send it to dest */ - do_tup_output(tstate, values, isnull); - - /* clean up */ - pfree(DatumGetPointer(values[0])); - if (setting) - { - pfree(setting); - pfree(DatumGetPointer(values[1])); - } - if (conf->short_desc) - pfree(DatumGetPointer(values[2])); - } - - end_tup_output(tstate); -} - /* * Return an array of modified GUC options to show in EXPLAIN. * @@ -10357,275 +4922,7 @@ GetConfigOptionByName(const char *name, const char **varname, bool missing_ok) if (varname) *varname = record->name; - return _ShowOption(record, true); -} - -/* - * Return some of the flags associated to the specified GUC in the shape of - * a text array, and NULL if it does not exist. An empty array is returned - * if the GUC exists without any meaningful flags to show. - */ -Datum -pg_settings_get_flags(PG_FUNCTION_ARGS) -{ -#define MAX_GUC_FLAGS 5 - char *varname = TextDatumGetCString(PG_GETARG_DATUM(0)); - struct config_generic *record; - int cnt = 0; - Datum flags[MAX_GUC_FLAGS]; - ArrayType *a; - - record = find_option(varname, false, true, ERROR); - - /* return NULL if no such variable */ - if (record == NULL) - PG_RETURN_NULL(); - - if (record->flags & GUC_EXPLAIN) - flags[cnt++] = CStringGetTextDatum("EXPLAIN"); - if (record->flags & GUC_NO_RESET_ALL) - flags[cnt++] = CStringGetTextDatum("NO_RESET_ALL"); - if (record->flags & GUC_NO_SHOW_ALL) - flags[cnt++] = CStringGetTextDatum("NO_SHOW_ALL"); - if (record->flags & GUC_NOT_IN_SAMPLE) - flags[cnt++] = CStringGetTextDatum("NOT_IN_SAMPLE"); - if (record->flags & GUC_RUNTIME_COMPUTED) - flags[cnt++] = CStringGetTextDatum("RUNTIME_COMPUTED"); - - Assert(cnt <= MAX_GUC_FLAGS); - - /* Returns the record as Datum */ - a = construct_array_builtin(flags, cnt, TEXTOID); - PG_RETURN_ARRAYTYPE_P(a); -} - -/* - * Return GUC variable value by variable number; optionally return canonical - * form of name. Return value is palloc'd. - */ -void -GetConfigOptionByNum(int varnum, const char **values, bool *noshow) -{ - char buffer[256]; - struct config_generic *conf; - - /* check requested variable number valid */ - Assert((varnum >= 0) && (varnum < num_guc_variables)); - - conf = guc_variables[varnum]; - - if (noshow) - { - if ((conf->flags & GUC_NO_SHOW_ALL) || - ((conf->flags & GUC_SUPERUSER_ONLY) && - !has_privs_of_role(GetUserId(), ROLE_PG_READ_ALL_SETTINGS))) - *noshow = true; - else - *noshow = false; - } - - /* first get the generic attributes */ - - /* name */ - values[0] = conf->name; - - /* setting: use _ShowOption in order to avoid duplicating the logic */ - values[1] = _ShowOption(conf, false); - - /* unit, if any (NULL is fine) */ - values[2] = get_config_unit_name(conf->flags); - - /* group */ - values[3] = _(config_group_names[conf->group]); - - /* short_desc */ - values[4] = conf->short_desc != NULL ? _(conf->short_desc) : NULL; - - /* extra_desc */ - values[5] = conf->long_desc != NULL ? _(conf->long_desc) : NULL; - - /* context */ - values[6] = GucContext_Names[conf->context]; - - /* vartype */ - values[7] = config_type_names[conf->vartype]; - - /* source */ - values[8] = GucSource_Names[conf->source]; - - /* now get the type specific attributes */ - switch (conf->vartype) - { - case PGC_BOOL: - { - struct config_bool *lconf = (struct config_bool *) conf; - - /* min_val */ - values[9] = NULL; - - /* max_val */ - values[10] = NULL; - - /* enumvals */ - values[11] = NULL; - - /* boot_val */ - values[12] = pstrdup(lconf->boot_val ? "on" : "off"); - - /* reset_val */ - values[13] = pstrdup(lconf->reset_val ? "on" : "off"); - } - break; - - case PGC_INT: - { - struct config_int *lconf = (struct config_int *) conf; - - /* min_val */ - snprintf(buffer, sizeof(buffer), "%d", lconf->min); - values[9] = pstrdup(buffer); - - /* max_val */ - snprintf(buffer, sizeof(buffer), "%d", lconf->max); - values[10] = pstrdup(buffer); - - /* enumvals */ - values[11] = NULL; - - /* boot_val */ - snprintf(buffer, sizeof(buffer), "%d", lconf->boot_val); - values[12] = pstrdup(buffer); - - /* reset_val */ - snprintf(buffer, sizeof(buffer), "%d", lconf->reset_val); - values[13] = pstrdup(buffer); - } - break; - - case PGC_REAL: - { - struct config_real *lconf = (struct config_real *) conf; - - /* min_val */ - snprintf(buffer, sizeof(buffer), "%g", lconf->min); - values[9] = pstrdup(buffer); - - /* max_val */ - snprintf(buffer, sizeof(buffer), "%g", lconf->max); - values[10] = pstrdup(buffer); - - /* enumvals */ - values[11] = NULL; - - /* boot_val */ - snprintf(buffer, sizeof(buffer), "%g", lconf->boot_val); - values[12] = pstrdup(buffer); - - /* reset_val */ - snprintf(buffer, sizeof(buffer), "%g", lconf->reset_val); - values[13] = pstrdup(buffer); - } - break; - - case PGC_STRING: - { - struct config_string *lconf = (struct config_string *) conf; - - /* min_val */ - values[9] = NULL; - - /* max_val */ - values[10] = NULL; - - /* enumvals */ - values[11] = NULL; - - /* boot_val */ - if (lconf->boot_val == NULL) - values[12] = NULL; - else - values[12] = pstrdup(lconf->boot_val); - - /* reset_val */ - if (lconf->reset_val == NULL) - values[13] = NULL; - else - values[13] = pstrdup(lconf->reset_val); - } - break; - - case PGC_ENUM: - { - struct config_enum *lconf = (struct config_enum *) conf; - - /* min_val */ - values[9] = NULL; - - /* max_val */ - values[10] = NULL; - - /* enumvals */ - - /* - * NOTE! enumvals with double quotes in them are not - * supported! - */ - values[11] = config_enum_get_options((struct config_enum *) conf, - "{\"", "\"}", "\",\""); - - /* boot_val */ - values[12] = pstrdup(config_enum_lookup_by_value(lconf, - lconf->boot_val)); - - /* reset_val */ - values[13] = pstrdup(config_enum_lookup_by_value(lconf, - lconf->reset_val)); - } - break; - - default: - { - /* - * should never get here, but in case we do, set 'em to NULL - */ - - /* min_val */ - values[9] = NULL; - - /* max_val */ - values[10] = NULL; - - /* enumvals */ - values[11] = NULL; - - /* boot_val */ - values[12] = NULL; - - /* reset_val */ - values[13] = NULL; - } - break; - } - - /* - * If the setting came from a config file, set the source location. For - * security reasons, we don't show source file/line number for - * insufficiently-privileged users. - */ - if (conf->source == PGC_S_FILE && - has_privs_of_role(GetUserId(), ROLE_PG_READ_ALL_SETTINGS)) - { - values[14] = conf->sourcefile; - snprintf(buffer, sizeof(buffer), "%d", conf->sourceline); - values[15] = pstrdup(buffer); - } - else - { - values[14] = NULL; - values[15] = NULL; - } - - values[16] = (conf->status & GUC_PENDING_RESTART) ? "t" : "f"; + return ShowGUCOption(record, true); } /* @@ -10638,253 +4935,14 @@ GetNumConfigOptions(void) } /* - * show_config_by_name - equiv to SHOW X command but implemented as - * a function. - */ -Datum -show_config_by_name(PG_FUNCTION_ARGS) -{ - char *varname = TextDatumGetCString(PG_GETARG_DATUM(0)); - char *varval; - - /* Get the value */ - varval = GetConfigOptionByName(varname, NULL, false); - - /* Convert to text */ - PG_RETURN_TEXT_P(cstring_to_text(varval)); -} - -/* - * show_config_by_name_missing_ok - equiv to SHOW X command but implemented as - * a function. If X does not exist, suppress the error and just return NULL - * if missing_ok is true. - */ -Datum -show_config_by_name_missing_ok(PG_FUNCTION_ARGS) -{ - char *varname = TextDatumGetCString(PG_GETARG_DATUM(0)); - bool missing_ok = PG_GETARG_BOOL(1); - char *varval; - - /* Get the value */ - varval = GetConfigOptionByName(varname, NULL, missing_ok); - - /* return NULL if no such variable */ - if (varval == NULL) - PG_RETURN_NULL(); - - /* Convert to text */ - PG_RETURN_TEXT_P(cstring_to_text(varval)); -} - -/* - * show_all_settings - equiv to SHOW ALL command but implemented as - * a Table Function. - */ -#define NUM_PG_SETTINGS_ATTS 17 - -Datum -show_all_settings(PG_FUNCTION_ARGS) -{ - FuncCallContext *funcctx; - TupleDesc tupdesc; - int call_cntr; - int max_calls; - AttInMetadata *attinmeta; - MemoryContext oldcontext; - - /* stuff done only on the first call of the function */ - if (SRF_IS_FIRSTCALL()) - { - /* create a function context for cross-call persistence */ - funcctx = SRF_FIRSTCALL_INIT(); - - /* - * switch to memory context appropriate for multiple function calls - */ - oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx); - - /* - * need a tuple descriptor representing NUM_PG_SETTINGS_ATTS columns - * of the appropriate types - */ - tupdesc = CreateTemplateTupleDesc(NUM_PG_SETTINGS_ATTS); - TupleDescInitEntry(tupdesc, (AttrNumber) 1, "name", - TEXTOID, -1, 0); - TupleDescInitEntry(tupdesc, (AttrNumber) 2, "setting", - TEXTOID, -1, 0); - TupleDescInitEntry(tupdesc, (AttrNumber) 3, "unit", - TEXTOID, -1, 0); - TupleDescInitEntry(tupdesc, (AttrNumber) 4, "category", - TEXTOID, -1, 0); - TupleDescInitEntry(tupdesc, (AttrNumber) 5, "short_desc", - TEXTOID, -1, 0); - TupleDescInitEntry(tupdesc, (AttrNumber) 6, "extra_desc", - TEXTOID, -1, 0); - TupleDescInitEntry(tupdesc, (AttrNumber) 7, "context", - TEXTOID, -1, 0); - TupleDescInitEntry(tupdesc, (AttrNumber) 8, "vartype", - TEXTOID, -1, 0); - TupleDescInitEntry(tupdesc, (AttrNumber) 9, "source", - TEXTOID, -1, 0); - TupleDescInitEntry(tupdesc, (AttrNumber) 10, "min_val", - TEXTOID, -1, 0); - TupleDescInitEntry(tupdesc, (AttrNumber) 11, "max_val", - TEXTOID, -1, 0); - TupleDescInitEntry(tupdesc, (AttrNumber) 12, "enumvals", - TEXTARRAYOID, -1, 0); - TupleDescInitEntry(tupdesc, (AttrNumber) 13, "boot_val", - TEXTOID, -1, 0); - TupleDescInitEntry(tupdesc, (AttrNumber) 14, "reset_val", - TEXTOID, -1, 0); - TupleDescInitEntry(tupdesc, (AttrNumber) 15, "sourcefile", - TEXTOID, -1, 0); - TupleDescInitEntry(tupdesc, (AttrNumber) 16, "sourceline", - INT4OID, -1, 0); - TupleDescInitEntry(tupdesc, (AttrNumber) 17, "pending_restart", - BOOLOID, -1, 0); - - /* - * Generate attribute metadata needed later to produce tuples from raw - * C strings - */ - attinmeta = TupleDescGetAttInMetadata(tupdesc); - funcctx->attinmeta = attinmeta; - - /* total number of tuples to be returned */ - funcctx->max_calls = GetNumConfigOptions(); - - MemoryContextSwitchTo(oldcontext); - } - - /* stuff done on every call of the function */ - funcctx = SRF_PERCALL_SETUP(); - - call_cntr = funcctx->call_cntr; - max_calls = funcctx->max_calls; - attinmeta = funcctx->attinmeta; - - if (call_cntr < max_calls) /* do when there is more left to send */ - { - char *values[NUM_PG_SETTINGS_ATTS]; - bool noshow; - HeapTuple tuple; - Datum result; - - /* - * Get the next visible GUC variable name and value - */ - do - { - GetConfigOptionByNum(call_cntr, (const char **) values, &noshow); - if (noshow) - { - /* bump the counter and get the next config setting */ - call_cntr = ++funcctx->call_cntr; - - /* make sure we haven't gone too far now */ - if (call_cntr >= max_calls) - SRF_RETURN_DONE(funcctx); - } - } while (noshow); - - /* build a tuple */ - tuple = BuildTupleFromCStrings(attinmeta, values); - - /* make the tuple into a datum */ - result = HeapTupleGetDatum(tuple); - - SRF_RETURN_NEXT(funcctx, result); - } - else - { - /* do when there is no more left */ - SRF_RETURN_DONE(funcctx); - } -} - -/* - * show_all_file_settings + * ShowGUCOption: get string value of variable * - * Returns a table of all parameter settings in all configuration files - * which includes the config file pathname, the line number, a sequence number - * indicating the order in which the settings were encountered, the parameter - * name and value, a bool showing if the value could be applied, and possibly - * an associated error message. (For problems such as syntax errors, the - * parameter name/value might be NULL.) - * - * Note: no filtering is done here, instead we depend on the GRANT system - * to prevent unprivileged users from accessing this function or the view - * built on top of it. + * We express a numeric value in appropriate units if it has units and + * use_units is true; else you just get the raw number. + * The result string is palloc'd. */ -Datum -show_all_file_settings(PG_FUNCTION_ARGS) -{ -#define NUM_PG_FILE_SETTINGS_ATTS 7 - ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo; - ConfigVariable *conf; - int seqno; - - /* Scan the config files using current context as workspace */ - conf = ProcessConfigFileInternal(PGC_SIGHUP, false, DEBUG3); - - /* Build a tuplestore to return our results in */ - SetSingleFuncCall(fcinfo, 0); - - /* Process the results and create a tuplestore */ - for (seqno = 1; conf != NULL; conf = conf->next, seqno++) - { - Datum values[NUM_PG_FILE_SETTINGS_ATTS]; - bool nulls[NUM_PG_FILE_SETTINGS_ATTS]; - - memset(values, 0, sizeof(values)); - memset(nulls, 0, sizeof(nulls)); - - /* sourcefile */ - if (conf->filename) - values[0] = PointerGetDatum(cstring_to_text(conf->filename)); - else - nulls[0] = true; - - /* sourceline (not meaningful if no sourcefile) */ - if (conf->filename) - values[1] = Int32GetDatum(conf->sourceline); - else - nulls[1] = true; - - /* seqno */ - values[2] = Int32GetDatum(seqno); - - /* name */ - if (conf->name) - values[3] = PointerGetDatum(cstring_to_text(conf->name)); - else - nulls[3] = true; - - /* setting */ - if (conf->value) - values[4] = PointerGetDatum(cstring_to_text(conf->value)); - else - nulls[4] = true; - - /* applied */ - values[5] = BoolGetDatum(conf->applied); - - /* error */ - if (conf->errmsg) - values[6] = PointerGetDatum(cstring_to_text(conf->errmsg)); - else - nulls[6] = true; - - /* shove row into tuplestore */ - tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc, values, nulls); - } - - return (Datum) 0; -} - -static char * -_ShowOption(struct config_generic *record, bool use_units) +char * +ShowGUCOption(struct config_generic *record, bool use_units) { char buffer[256]; const char *val; @@ -12365,989 +6423,3 @@ call_enum_check_hook(struct config_enum *conf, int *newval, void **extra, return true; } - - -/* - * check_hook, assign_hook and show_hook subroutines - */ - -static bool -check_wal_consistency_checking(char **newval, void **extra, GucSource source) -{ - char *rawstring; - List *elemlist; - ListCell *l; - bool newwalconsistency[RM_MAX_ID + 1]; - - /* Initialize the array */ - MemSet(newwalconsistency, 0, (RM_MAX_ID + 1) * sizeof(bool)); - - /* Need a modifiable copy of string */ - rawstring = pstrdup(*newval); - - /* Parse string into list of identifiers */ - if (!SplitIdentifierString(rawstring, ',', &elemlist)) - { - /* syntax error in list */ - GUC_check_errdetail("List syntax is invalid."); - pfree(rawstring); - list_free(elemlist); - return false; - } - - foreach(l, elemlist) - { - char *tok = (char *) lfirst(l); - bool found = false; - int rmid; - - /* Check for 'all'. */ - if (pg_strcasecmp(tok, "all") == 0) - { - for (rmid = 0; rmid <= RM_MAX_ID; rmid++) - if (RmgrIdExists(rmid) && GetRmgr(rmid).rm_mask != NULL) - newwalconsistency[rmid] = true; - found = true; - } - else - { - /* - * Check if the token matches with any individual resource - * manager. - */ - for (rmid = 0; rmid <= RM_MAX_ID; rmid++) - { - if (RmgrIdExists(rmid) && GetRmgr(rmid).rm_mask != NULL && - pg_strcasecmp(tok, GetRmgr(rmid).rm_name) == 0) - { - newwalconsistency[rmid] = true; - found = true; - } - } - } - - /* If a valid resource manager is found, check for the next one. */ - if (!found) - { - /* - * Perhaps it's a custom resource manager. If so, defer checking - * until InitializeWalConsistencyChecking(). - */ - if (!process_shared_preload_libraries_done) - { - check_wal_consistency_checking_deferred = true; - } - else - { - GUC_check_errdetail("Unrecognized key word: \"%s\".", tok); - pfree(rawstring); - list_free(elemlist); - return false; - } - } - } - - pfree(rawstring); - list_free(elemlist); - - /* assign new value */ - *extra = guc_malloc(ERROR, (RM_MAX_ID + 1) * sizeof(bool)); - memcpy(*extra, newwalconsistency, (RM_MAX_ID + 1) * sizeof(bool)); - return true; -} - -static void -assign_wal_consistency_checking(const char *newval, void *extra) -{ - /* - * If some checks were deferred, it's possible that the checks will fail - * later during InitializeWalConsistencyChecking(). But in that case, the - * postmaster will exit anyway, so it's safe to proceed with the - * assignment. - * - * Any built-in resource managers specified are assigned immediately, - * which affects WAL created before shared_preload_libraries are - * processed. Any custom resource managers specified won't be assigned - * until after shared_preload_libraries are processed, but that's OK - * because WAL for a custom resource manager can't be written before the - * module is loaded anyway. - */ - wal_consistency_checking = extra; -} - -static bool -check_log_destination(char **newval, void **extra, GucSource source) -{ - char *rawstring; - List *elemlist; - ListCell *l; - int newlogdest = 0; - int *myextra; - - /* Need a modifiable copy of string */ - rawstring = pstrdup(*newval); - - /* Parse string into list of identifiers */ - if (!SplitIdentifierString(rawstring, ',', &elemlist)) - { - /* syntax error in list */ - GUC_check_errdetail("List syntax is invalid."); - pfree(rawstring); - list_free(elemlist); - return false; - } - - foreach(l, elemlist) - { - char *tok = (char *) lfirst(l); - - if (pg_strcasecmp(tok, "stderr") == 0) - newlogdest |= LOG_DESTINATION_STDERR; - else if (pg_strcasecmp(tok, "csvlog") == 0) - newlogdest |= LOG_DESTINATION_CSVLOG; - else if (pg_strcasecmp(tok, "jsonlog") == 0) - newlogdest |= LOG_DESTINATION_JSONLOG; -#ifdef HAVE_SYSLOG - else if (pg_strcasecmp(tok, "syslog") == 0) - newlogdest |= LOG_DESTINATION_SYSLOG; -#endif -#ifdef WIN32 - else if (pg_strcasecmp(tok, "eventlog") == 0) - newlogdest |= LOG_DESTINATION_EVENTLOG; -#endif - else - { - GUC_check_errdetail("Unrecognized key word: \"%s\".", tok); - pfree(rawstring); - list_free(elemlist); - return false; - } - } - - pfree(rawstring); - list_free(elemlist); - - myextra = (int *) guc_malloc(ERROR, sizeof(int)); - *myextra = newlogdest; - *extra = (void *) myextra; - - return true; -} - -static void -assign_log_destination(const char *newval, void *extra) -{ - Log_destination = *((int *) extra); -} - -static void -assign_syslog_facility(int newval, void *extra) -{ -#ifdef HAVE_SYSLOG - set_syslog_parameters(syslog_ident_str ? syslog_ident_str : "postgres", - newval); -#endif - /* Without syslog support, just ignore it */ -} - -static void -assign_syslog_ident(const char *newval, void *extra) -{ -#ifdef HAVE_SYSLOG - set_syslog_parameters(newval, syslog_facility); -#endif - /* Without syslog support, it will always be set to "none", so ignore */ -} - - -static void -assign_session_replication_role(int newval, void *extra) -{ - /* - * Must flush the plan cache when changing replication role; but don't - * flush unnecessarily. - */ - if (SessionReplicationRole != newval) - ResetPlanCache(); -} - -static bool -check_temp_buffers(int *newval, void **extra, GucSource source) -{ - /* - * Once local buffers have been initialized, it's too late to change this. - * However, if this is only a test call, allow it. - */ - if (source != PGC_S_TEST && NLocBuffer && NLocBuffer != *newval) - { - GUC_check_errdetail("\"temp_buffers\" cannot be changed after any temporary tables have been accessed in the session."); - return false; - } - return true; -} - -static bool -check_bonjour(bool *newval, void **extra, GucSource source) -{ -#ifndef USE_BONJOUR - if (*newval) - { - GUC_check_errmsg("Bonjour is not supported by this build"); - return false; - } -#endif - return true; -} - -static bool -check_ssl(bool *newval, void **extra, GucSource source) -{ -#ifndef USE_SSL - if (*newval) - { - GUC_check_errmsg("SSL is not supported by this build"); - return false; - } -#endif - return true; -} - -static bool -check_stage_log_stats(bool *newval, void **extra, GucSource source) -{ - if (*newval && log_statement_stats) - { - GUC_check_errdetail("Cannot enable parameter when \"log_statement_stats\" is true."); - return false; - } - return true; -} - -static bool -check_log_stats(bool *newval, void **extra, GucSource source) -{ - if (*newval && - (log_parser_stats || log_planner_stats || log_executor_stats)) - { - GUC_check_errdetail("Cannot enable \"log_statement_stats\" when " - "\"log_parser_stats\", \"log_planner_stats\", " - "or \"log_executor_stats\" is true."); - return false; - } - return true; -} - -static bool -check_canonical_path(char **newval, void **extra, GucSource source) -{ - /* - * Since canonicalize_path never enlarges the string, we can just modify - * newval in-place. But watch out for NULL, which is the default value - * for external_pid_file. - */ - if (*newval) - canonicalize_path(*newval); - return true; -} - -static bool -check_timezone_abbreviations(char **newval, void **extra, GucSource source) -{ - /* - * The boot_val given above for timezone_abbreviations is NULL. When we - * see this we just do nothing. If this value isn't overridden from the - * config file then pg_timezone_abbrev_initialize() will eventually - * replace it with "Default". This hack has two purposes: to avoid - * wasting cycles loading values that might soon be overridden from the - * config file, and to avoid trying to read the timezone abbrev files - * during InitializeGUCOptions(). The latter doesn't work in an - * EXEC_BACKEND subprocess because my_exec_path hasn't been set yet and so - * we can't locate PGSHAREDIR. - */ - if (*newval == NULL) - { - Assert(source == PGC_S_DEFAULT); - return true; - } - - /* OK, load the file and produce a malloc'd TimeZoneAbbrevTable */ - *extra = load_tzoffsets(*newval); - - /* tzparser.c returns NULL on failure, reporting via GUC_check_errmsg */ - if (!*extra) - return false; - - return true; -} - -static void -assign_timezone_abbreviations(const char *newval, void *extra) -{ - /* Do nothing for the boot_val default of NULL */ - if (!extra) - return; - - InstallTimeZoneAbbrevs((TimeZoneAbbrevTable *) extra); -} - -/* - * pg_timezone_abbrev_initialize --- set default value if not done already - * - * This is called after initial loading of postgresql.conf. If no - * timezone_abbreviations setting was found therein, select default. - * If a non-default value is already installed, nothing will happen. - * - * This can also be called from ProcessConfigFile to establish the default - * value after a postgresql.conf entry for it is removed. - */ -static void -pg_timezone_abbrev_initialize(void) -{ - SetConfigOption("timezone_abbreviations", "Default", - PGC_POSTMASTER, PGC_S_DYNAMIC_DEFAULT); -} - -static const char * -show_archive_command(void) -{ - if (XLogArchivingActive()) - return XLogArchiveCommand; - else - return "(disabled)"; -} - -static void -assign_tcp_keepalives_idle(int newval, void *extra) -{ - /* - * The kernel API provides no way to test a value without setting it; and - * once we set it we might fail to unset it. So there seems little point - * in fully implementing the check-then-assign GUC API for these - * variables. Instead we just do the assignment on demand. pqcomm.c - * reports any problems via ereport(LOG). - * - * This approach means that the GUC value might have little to do with the - * actual kernel value, so we use a show_hook that retrieves the kernel - * value rather than trusting GUC's copy. - */ - (void) pq_setkeepalivesidle(newval, MyProcPort); -} - -static const char * -show_tcp_keepalives_idle(void) -{ - /* See comments in assign_tcp_keepalives_idle */ - static char nbuf[16]; - - snprintf(nbuf, sizeof(nbuf), "%d", pq_getkeepalivesidle(MyProcPort)); - return nbuf; -} - -static void -assign_tcp_keepalives_interval(int newval, void *extra) -{ - /* See comments in assign_tcp_keepalives_idle */ - (void) pq_setkeepalivesinterval(newval, MyProcPort); -} - -static const char * -show_tcp_keepalives_interval(void) -{ - /* See comments in assign_tcp_keepalives_idle */ - static char nbuf[16]; - - snprintf(nbuf, sizeof(nbuf), "%d", pq_getkeepalivesinterval(MyProcPort)); - return nbuf; -} - -static void -assign_tcp_keepalives_count(int newval, void *extra) -{ - /* See comments in assign_tcp_keepalives_idle */ - (void) pq_setkeepalivescount(newval, MyProcPort); -} - -static const char * -show_tcp_keepalives_count(void) -{ - /* See comments in assign_tcp_keepalives_idle */ - static char nbuf[16]; - - snprintf(nbuf, sizeof(nbuf), "%d", pq_getkeepalivescount(MyProcPort)); - return nbuf; -} - -static void -assign_tcp_user_timeout(int newval, void *extra) -{ - /* See comments in assign_tcp_keepalives_idle */ - (void) pq_settcpusertimeout(newval, MyProcPort); -} - -static const char * -show_tcp_user_timeout(void) -{ - /* See comments in assign_tcp_keepalives_idle */ - static char nbuf[16]; - - snprintf(nbuf, sizeof(nbuf), "%d", pq_gettcpusertimeout(MyProcPort)); - return nbuf; -} - -static bool -check_maxconnections(int *newval, void **extra, GucSource source) -{ - if (*newval + autovacuum_max_workers + 1 + - max_worker_processes + max_wal_senders > MAX_BACKENDS) - return false; - return true; -} - -static bool -check_autovacuum_max_workers(int *newval, void **extra, GucSource source) -{ - if (MaxConnections + *newval + 1 + - max_worker_processes + max_wal_senders > MAX_BACKENDS) - return false; - return true; -} - -static bool -check_max_wal_senders(int *newval, void **extra, GucSource source) -{ - if (MaxConnections + autovacuum_max_workers + 1 + - max_worker_processes + *newval > MAX_BACKENDS) - return false; - return true; -} - -static bool -check_autovacuum_work_mem(int *newval, void **extra, GucSource source) -{ - /* - * -1 indicates fallback. - * - * If we haven't yet changed the boot_val default of -1, just let it be. - * Autovacuum will look to maintenance_work_mem instead. - */ - if (*newval == -1) - return true; - - /* - * We clamp manually-set values to at least 1MB. Since - * maintenance_work_mem is always set to at least this value, do the same - * here. - */ - if (*newval < 1024) - *newval = 1024; - - return true; -} - -static bool -check_max_worker_processes(int *newval, void **extra, GucSource source) -{ - if (MaxConnections + autovacuum_max_workers + 1 + - *newval + max_wal_senders > MAX_BACKENDS) - return false; - return true; -} - -static bool -check_effective_io_concurrency(int *newval, void **extra, GucSource source) -{ -#ifndef USE_PREFETCH - if (*newval != 0) - { - GUC_check_errdetail("effective_io_concurrency must be set to 0 on platforms that lack posix_fadvise()."); - return false; - } -#endif /* USE_PREFETCH */ - return true; -} - -static bool -check_maintenance_io_concurrency(int *newval, void **extra, GucSource source) -{ -#ifndef USE_PREFETCH - if (*newval != 0) - { - GUC_check_errdetail("maintenance_io_concurrency must be set to 0 on platforms that lack posix_fadvise()."); - return false; - } -#endif /* USE_PREFETCH */ - return true; -} - -static bool -check_huge_page_size(int *newval, void **extra, GucSource source) -{ -#if !(defined(MAP_HUGE_MASK) && defined(MAP_HUGE_SHIFT)) - /* Recent enough Linux only, for now. See GetHugePageSize(). */ - if (*newval != 0) - { - GUC_check_errdetail("huge_page_size must be 0 on this platform."); - return false; - } -#endif - return true; -} - -static bool -check_client_connection_check_interval(int *newval, void **extra, GucSource source) -{ - if (!WaitEventSetCanReportClosed() && *newval != 0) - { - GUC_check_errdetail("client_connection_check_interval must be set to 0 on this platform."); - return false; - } - return true; -} - -static void -assign_maintenance_io_concurrency(int newval, void *extra) -{ -#ifdef USE_PREFETCH - /* - * Reconfigure recovery prefetching, because a setting it depends on - * changed. - */ - maintenance_io_concurrency = newval; - if (AmStartupProcess()) - XLogPrefetchReconfigure(); -#endif -} - -static bool -check_application_name(char **newval, void **extra, GucSource source) -{ - char *clean; - - /* Only allow clean ASCII chars in the application name */ - clean = pg_clean_ascii(*newval, MCXT_ALLOC_NO_OOM); - if (!clean) - return false; - - clean = guc_strdup(WARNING, clean); - if (!clean) - return false; - - *newval = clean; - return true; -} - -static void -assign_application_name(const char *newval, void *extra) -{ - /* Update the pg_stat_activity view */ - pgstat_report_appname(newval); -} - -static bool -check_cluster_name(char **newval, void **extra, GucSource source) -{ - char *clean; - - /* Only allow clean ASCII chars in the cluster name */ - clean = pg_clean_ascii(*newval, MCXT_ALLOC_NO_OOM); - if (!clean) - return false; - - clean = guc_strdup(WARNING, clean); - if (!clean) - return false; - - *newval = clean; - return true; -} - -static const char * -show_unix_socket_permissions(void) -{ - static char buf[12]; - - snprintf(buf, sizeof(buf), "%04o", Unix_socket_permissions); - return buf; -} - -static const char * -show_log_file_mode(void) -{ - static char buf[12]; - - snprintf(buf, sizeof(buf), "%04o", Log_file_mode); - return buf; -} - -static const char * -show_data_directory_mode(void) -{ - static char buf[12]; - - snprintf(buf, sizeof(buf), "%04o", data_directory_mode); - return buf; -} - -static const char * -show_in_hot_standby(void) -{ - /* - * We display the actual state based on shared memory, so that this GUC - * reports up-to-date state if examined intra-query. The underlying - * variable in_hot_standby changes only when we transmit a new value to - * the client. - */ - return RecoveryInProgress() ? "on" : "off"; -} - -/* - * We split the input string, where commas separate function names - * and certain whitespace chars are ignored, into a \0-separated (and - * \0\0-terminated) list of function names. This formulation allows - * easy scanning when an error is thrown while avoiding the use of - * non-reentrant strtok(), as well as keeping the output data in a - * single palloc() chunk. - */ -static bool -check_backtrace_functions(char **newval, void **extra, GucSource source) -{ - int newvallen = strlen(*newval); - char *someval; - int validlen; - int i; - int j; - - /* - * Allow characters that can be C identifiers and commas as separators, as - * well as some whitespace for readability. - */ - validlen = strspn(*newval, - "0123456789_" - "abcdefghijklmnopqrstuvwxyz" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - ", \n\t"); - if (validlen != newvallen) - { - GUC_check_errdetail("invalid character"); - return false; - } - - if (*newval[0] == '\0') - { - *extra = NULL; - return true; - } - - /* - * Allocate space for the output and create the copy. We could discount - * whitespace chars to save some memory, but it doesn't seem worth the - * trouble. - */ - someval = guc_malloc(ERROR, newvallen + 1 + 1); - for (i = 0, j = 0; i < newvallen; i++) - { - if ((*newval)[i] == ',') - someval[j++] = '\0'; /* next item */ - else if ((*newval)[i] == ' ' || - (*newval)[i] == '\n' || - (*newval)[i] == '\t') - ; /* ignore these */ - else - someval[j++] = (*newval)[i]; /* copy anything else */ - } - - /* two \0s end the setting */ - someval[j] = '\0'; - someval[j + 1] = '\0'; - - *extra = someval; - return true; -} - -static void -assign_backtrace_functions(const char *newval, void *extra) -{ - backtrace_symbol_list = (char *) extra; -} - -static bool -check_recovery_target_timeline(char **newval, void **extra, GucSource source) -{ - RecoveryTargetTimeLineGoal rttg; - RecoveryTargetTimeLineGoal *myextra; - - if (strcmp(*newval, "current") == 0) - rttg = RECOVERY_TARGET_TIMELINE_CONTROLFILE; - else if (strcmp(*newval, "latest") == 0) - rttg = RECOVERY_TARGET_TIMELINE_LATEST; - else - { - rttg = RECOVERY_TARGET_TIMELINE_NUMERIC; - - errno = 0; - strtoul(*newval, NULL, 0); - if (errno == EINVAL || errno == ERANGE) - { - GUC_check_errdetail("recovery_target_timeline is not a valid number."); - return false; - } - } - - myextra = (RecoveryTargetTimeLineGoal *) guc_malloc(ERROR, sizeof(RecoveryTargetTimeLineGoal)); - *myextra = rttg; - *extra = (void *) myextra; - - return true; -} - -static void -assign_recovery_target_timeline(const char *newval, void *extra) -{ - recoveryTargetTimeLineGoal = *((RecoveryTargetTimeLineGoal *) extra); - if (recoveryTargetTimeLineGoal == RECOVERY_TARGET_TIMELINE_NUMERIC) - recoveryTargetTLIRequested = (TimeLineID) strtoul(newval, NULL, 0); - else - recoveryTargetTLIRequested = 0; -} - -/* - * Recovery target settings: Only one of the several recovery_target* settings - * may be set. Setting a second one results in an error. The global variable - * recoveryTarget tracks which kind of recovery target was chosen. Other - * variables store the actual target value (for example a string or a xid). - * The assign functions of the parameters check whether a competing parameter - * was already set. But we want to allow setting the same parameter multiple - * times. We also want to allow unsetting a parameter and setting a different - * one, so we unset recoveryTarget when the parameter is set to an empty - * string. - */ - -static void -pg_attribute_noreturn() -error_multiple_recovery_targets(void) -{ - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("multiple recovery targets specified"), - errdetail("At most one of recovery_target, recovery_target_lsn, recovery_target_name, recovery_target_time, recovery_target_xid may be set."))); -} - -static bool -check_recovery_target(char **newval, void **extra, GucSource source) -{ - if (strcmp(*newval, "immediate") != 0 && strcmp(*newval, "") != 0) - { - GUC_check_errdetail("The only allowed value is \"immediate\"."); - return false; - } - return true; -} - -static void -assign_recovery_target(const char *newval, void *extra) -{ - if (recoveryTarget != RECOVERY_TARGET_UNSET && - recoveryTarget != RECOVERY_TARGET_IMMEDIATE) - error_multiple_recovery_targets(); - - if (newval && strcmp(newval, "") != 0) - recoveryTarget = RECOVERY_TARGET_IMMEDIATE; - else - recoveryTarget = RECOVERY_TARGET_UNSET; -} - -static bool -check_recovery_target_xid(char **newval, void **extra, GucSource source) -{ - if (strcmp(*newval, "") != 0) - { - TransactionId xid; - TransactionId *myextra; - - errno = 0; - xid = (TransactionId) strtou64(*newval, NULL, 0); - if (errno == EINVAL || errno == ERANGE) - return false; - - myextra = (TransactionId *) guc_malloc(ERROR, sizeof(TransactionId)); - *myextra = xid; - *extra = (void *) myextra; - } - return true; -} - -static void -assign_recovery_target_xid(const char *newval, void *extra) -{ - if (recoveryTarget != RECOVERY_TARGET_UNSET && - recoveryTarget != RECOVERY_TARGET_XID) - error_multiple_recovery_targets(); - - if (newval && strcmp(newval, "") != 0) - { - recoveryTarget = RECOVERY_TARGET_XID; - recoveryTargetXid = *((TransactionId *) extra); - } - else - recoveryTarget = RECOVERY_TARGET_UNSET; -} - -/* - * The interpretation of the recovery_target_time string can depend on the - * time zone setting, so we need to wait until after all GUC processing is - * done before we can do the final parsing of the string. This check function - * only does a parsing pass to catch syntax errors, but we store the string - * and parse it again when we need to use it. - */ -static bool -check_recovery_target_time(char **newval, void **extra, GucSource source) -{ - if (strcmp(*newval, "") != 0) - { - /* reject some special values */ - if (strcmp(*newval, "now") == 0 || - strcmp(*newval, "today") == 0 || - strcmp(*newval, "tomorrow") == 0 || - strcmp(*newval, "yesterday") == 0) - { - return false; - } - - /* - * parse timestamp value (see also timestamptz_in()) - */ - { - char *str = *newval; - fsec_t fsec; - struct pg_tm tt, - *tm = &tt; - int tz; - int dtype; - int nf; - int dterr; - char *field[MAXDATEFIELDS]; - int ftype[MAXDATEFIELDS]; - char workbuf[MAXDATELEN + MAXDATEFIELDS]; - TimestampTz timestamp; - - dterr = ParseDateTime(str, workbuf, sizeof(workbuf), - field, ftype, MAXDATEFIELDS, &nf); - if (dterr == 0) - dterr = DecodeDateTime(field, ftype, nf, &dtype, tm, &fsec, &tz); - if (dterr != 0) - return false; - if (dtype != DTK_DATE) - return false; - - if (tm2timestamp(tm, fsec, &tz, ×tamp) != 0) - { - GUC_check_errdetail("timestamp out of range: \"%s\"", str); - return false; - } - } - } - return true; -} - -static void -assign_recovery_target_time(const char *newval, void *extra) -{ - if (recoveryTarget != RECOVERY_TARGET_UNSET && - recoveryTarget != RECOVERY_TARGET_TIME) - error_multiple_recovery_targets(); - - if (newval && strcmp(newval, "") != 0) - recoveryTarget = RECOVERY_TARGET_TIME; - else - recoveryTarget = RECOVERY_TARGET_UNSET; -} - -static bool -check_recovery_target_name(char **newval, void **extra, GucSource source) -{ - /* Use the value of newval directly */ - if (strlen(*newval) >= MAXFNAMELEN) - { - GUC_check_errdetail("%s is too long (maximum %d characters).", - "recovery_target_name", MAXFNAMELEN - 1); - return false; - } - return true; -} - -static void -assign_recovery_target_name(const char *newval, void *extra) -{ - if (recoveryTarget != RECOVERY_TARGET_UNSET && - recoveryTarget != RECOVERY_TARGET_NAME) - error_multiple_recovery_targets(); - - if (newval && strcmp(newval, "") != 0) - { - recoveryTarget = RECOVERY_TARGET_NAME; - recoveryTargetName = newval; - } - else - recoveryTarget = RECOVERY_TARGET_UNSET; -} - -static bool -check_recovery_target_lsn(char **newval, void **extra, GucSource source) -{ - if (strcmp(*newval, "") != 0) - { - XLogRecPtr lsn; - XLogRecPtr *myextra; - bool have_error = false; - - lsn = pg_lsn_in_internal(*newval, &have_error); - if (have_error) - return false; - - myextra = (XLogRecPtr *) guc_malloc(ERROR, sizeof(XLogRecPtr)); - *myextra = lsn; - *extra = (void *) myextra; - } - return true; -} - -static void -assign_recovery_target_lsn(const char *newval, void *extra) -{ - if (recoveryTarget != RECOVERY_TARGET_UNSET && - recoveryTarget != RECOVERY_TARGET_LSN) - error_multiple_recovery_targets(); - - if (newval && strcmp(newval, "") != 0) - { - recoveryTarget = RECOVERY_TARGET_LSN; - recoveryTargetLSN = *((XLogRecPtr *) extra); - } - else - recoveryTarget = RECOVERY_TARGET_UNSET; -} - -static bool -check_primary_slot_name(char **newval, void **extra, GucSource source) -{ - if (*newval && strcmp(*newval, "") != 0 && - !ReplicationSlotValidateName(*newval, WARNING)) - return false; - - return true; -} - -static bool -check_default_with_oids(bool *newval, void **extra, GucSource source) -{ - if (*newval) - { - /* check the GUC's definition for an explanation */ - GUC_check_errcode(ERRCODE_FEATURE_NOT_SUPPORTED); - GUC_check_errmsg("tables declared WITH OIDS are not supported"); - - return false; - } - - return true; -} diff --git a/src/backend/utils/misc/guc_funcs.c b/src/backend/utils/misc/guc_funcs.c new file mode 100644 index 0000000000..3d2df18659 --- /dev/null +++ b/src/backend/utils/misc/guc_funcs.c @@ -0,0 +1,1047 @@ +/*-------------------------------------------------------------------- + * + * guc_funcs.c + * + * SQL commands and SQL-accessible functions related to GUC variables. + * + * + * Copyright (c) 2000-2022, PostgreSQL Global Development Group + * Written by Peter Eisentraut . + * + * IDENTIFICATION + * src/backend/utils/misc/guc_funcs.c + * + *-------------------------------------------------------------------- + */ +#include "postgres.h" + +#include +#include + +#include "access/xact.h" +#include "catalog/objectaccess.h" +#include "catalog/pg_authid.h" +#include "catalog/pg_parameter_acl.h" +#include "funcapi.h" +#include "guc_internal.h" +#include "parser/parse_type.h" +#include "utils/acl.h" +#include "utils/backend_status.h" +#include "utils/builtins.h" +#include "utils/guc_tables.h" +#include "utils/snapmgr.h" + +static char *flatten_set_variable_args(const char *name, List *args); +static void ShowGUCConfigOption(const char *name, DestReceiver *dest); +static void ShowAllGUCConfig(DestReceiver *dest); + + +/* + * SET command + */ +void +ExecSetVariableStmt(VariableSetStmt *stmt, bool isTopLevel) +{ + GucAction action = stmt->is_local ? GUC_ACTION_LOCAL : GUC_ACTION_SET; + + /* + * Workers synchronize these parameters at the start of the parallel + * operation; then, we block SET during the operation. + */ + if (IsInParallelMode()) + ereport(ERROR, + (errcode(ERRCODE_INVALID_TRANSACTION_STATE), + errmsg("cannot set parameters during a parallel operation"))); + + switch (stmt->kind) + { + case VAR_SET_VALUE: + case VAR_SET_CURRENT: + if (stmt->is_local) + WarnNoTransactionBlock(isTopLevel, "SET LOCAL"); + (void) set_config_option(stmt->name, + ExtractSetVariableArgs(stmt), + (superuser() ? PGC_SUSET : PGC_USERSET), + PGC_S_SESSION, + action, true, 0, false); + break; + case VAR_SET_MULTI: + + /* + * Special-case SQL syntaxes. The TRANSACTION and SESSION + * CHARACTERISTICS cases effectively set more than one variable + * per statement. TRANSACTION SNAPSHOT only takes one argument, + * but we put it here anyway since it's a special case and not + * related to any GUC variable. + */ + if (strcmp(stmt->name, "TRANSACTION") == 0) + { + ListCell *head; + + WarnNoTransactionBlock(isTopLevel, "SET TRANSACTION"); + + foreach(head, stmt->args) + { + DefElem *item = (DefElem *) lfirst(head); + + if (strcmp(item->defname, "transaction_isolation") == 0) + SetPGVariable("transaction_isolation", + list_make1(item->arg), stmt->is_local); + else if (strcmp(item->defname, "transaction_read_only") == 0) + SetPGVariable("transaction_read_only", + list_make1(item->arg), stmt->is_local); + else if (strcmp(item->defname, "transaction_deferrable") == 0) + SetPGVariable("transaction_deferrable", + list_make1(item->arg), stmt->is_local); + else + elog(ERROR, "unexpected SET TRANSACTION element: %s", + item->defname); + } + } + else if (strcmp(stmt->name, "SESSION CHARACTERISTICS") == 0) + { + ListCell *head; + + foreach(head, stmt->args) + { + DefElem *item = (DefElem *) lfirst(head); + + if (strcmp(item->defname, "transaction_isolation") == 0) + SetPGVariable("default_transaction_isolation", + list_make1(item->arg), stmt->is_local); + else if (strcmp(item->defname, "transaction_read_only") == 0) + SetPGVariable("default_transaction_read_only", + list_make1(item->arg), stmt->is_local); + else if (strcmp(item->defname, "transaction_deferrable") == 0) + SetPGVariable("default_transaction_deferrable", + list_make1(item->arg), stmt->is_local); + else + elog(ERROR, "unexpected SET SESSION element: %s", + item->defname); + } + } + else if (strcmp(stmt->name, "TRANSACTION SNAPSHOT") == 0) + { + A_Const *con = linitial_node(A_Const, stmt->args); + + if (stmt->is_local) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("SET LOCAL TRANSACTION SNAPSHOT is not implemented"))); + + WarnNoTransactionBlock(isTopLevel, "SET TRANSACTION"); + ImportSnapshot(strVal(&con->val)); + } + else + elog(ERROR, "unexpected SET MULTI element: %s", + stmt->name); + break; + case VAR_SET_DEFAULT: + if (stmt->is_local) + WarnNoTransactionBlock(isTopLevel, "SET LOCAL"); + /* fall through */ + case VAR_RESET: + if (strcmp(stmt->name, "transaction_isolation") == 0) + WarnNoTransactionBlock(isTopLevel, "RESET TRANSACTION"); + + (void) set_config_option(stmt->name, + NULL, + (superuser() ? PGC_SUSET : PGC_USERSET), + PGC_S_SESSION, + action, true, 0, false); + break; + case VAR_RESET_ALL: + ResetAllOptions(); + break; + } + + /* Invoke the post-alter hook for setting this GUC variable, by name. */ + InvokeObjectPostAlterHookArgStr(ParameterAclRelationId, stmt->name, + ACL_SET, stmt->kind, false); +} + +/* + * Get the value to assign for a VariableSetStmt, or NULL if it's RESET. + * The result is palloc'd. + * + * This is exported for use by actions such as ALTER ROLE SET. + */ +char * +ExtractSetVariableArgs(VariableSetStmt *stmt) +{ + switch (stmt->kind) + { + case VAR_SET_VALUE: + return flatten_set_variable_args(stmt->name, stmt->args); + case VAR_SET_CURRENT: + return GetConfigOptionByName(stmt->name, NULL, false); + default: + return NULL; + } +} + +/* + * flatten_set_variable_args + * Given a parsenode List as emitted by the grammar for SET, + * convert to the flat string representation used by GUC. + * + * We need to be told the name of the variable the args are for, because + * the flattening rules vary (ugh). + * + * The result is NULL if args is NIL (i.e., SET ... TO DEFAULT), otherwise + * a palloc'd string. + */ +static char * +flatten_set_variable_args(const char *name, List *args) +{ + struct config_generic *record; + int flags; + StringInfoData buf; + ListCell *l; + + /* Fast path if just DEFAULT */ + if (args == NIL) + return NULL; + + /* + * Get flags for the variable; if it's not known, use default flags. + * (Caller might throw error later, but not our business to do so here.) + */ + record = find_option(name, false, true, WARNING); + if (record) + flags = record->flags; + else + flags = 0; + + /* Complain if list input and non-list variable */ + if ((flags & GUC_LIST_INPUT) == 0 && + list_length(args) != 1) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("SET %s takes only one argument", name))); + + initStringInfo(&buf); + + /* + * Each list member may be a plain A_Const node, or an A_Const within a + * TypeCast; the latter case is supported only for ConstInterval arguments + * (for SET TIME ZONE). + */ + foreach(l, args) + { + Node *arg = (Node *) lfirst(l); + char *val; + TypeName *typeName = NULL; + A_Const *con; + + if (l != list_head(args)) + appendStringInfoString(&buf, ", "); + + if (IsA(arg, TypeCast)) + { + TypeCast *tc = (TypeCast *) arg; + + arg = tc->arg; + typeName = tc->typeName; + } + + if (!IsA(arg, A_Const)) + elog(ERROR, "unrecognized node type: %d", (int) nodeTag(arg)); + con = (A_Const *) arg; + + switch (nodeTag(&con->val)) + { + case T_Integer: + appendStringInfo(&buf, "%d", intVal(&con->val)); + break; + case T_Float: + /* represented as a string, so just copy it */ + appendStringInfoString(&buf, castNode(Float, &con->val)->fval); + break; + case T_String: + val = strVal(&con->val); + if (typeName != NULL) + { + /* + * Must be a ConstInterval argument for TIME ZONE. Coerce + * to interval and back to normalize the value and account + * for any typmod. + */ + Oid typoid; + int32 typmod; + Datum interval; + char *intervalout; + + typenameTypeIdAndMod(NULL, typeName, &typoid, &typmod); + Assert(typoid == INTERVALOID); + + interval = + DirectFunctionCall3(interval_in, + CStringGetDatum(val), + ObjectIdGetDatum(InvalidOid), + Int32GetDatum(typmod)); + + intervalout = + DatumGetCString(DirectFunctionCall1(interval_out, + interval)); + appendStringInfo(&buf, "INTERVAL '%s'", intervalout); + } + else + { + /* + * Plain string literal or identifier. For quote mode, + * quote it if it's not a vanilla identifier. + */ + if (flags & GUC_LIST_QUOTE) + appendStringInfoString(&buf, quote_identifier(val)); + else + appendStringInfoString(&buf, val); + } + break; + default: + elog(ERROR, "unrecognized node type: %d", + (int) nodeTag(&con->val)); + break; + } + } + + return buf.data; +} + +/* + * SetPGVariable - SET command exported as an easily-C-callable function. + * + * This provides access to SET TO value, as well as SET TO DEFAULT (expressed + * by passing args == NIL), but not SET FROM CURRENT functionality. + */ +void +SetPGVariable(const char *name, List *args, bool is_local) +{ + char *argstring = flatten_set_variable_args(name, args); + + /* Note SET DEFAULT (argstring == NULL) is equivalent to RESET */ + (void) set_config_option(name, + argstring, + (superuser() ? PGC_SUSET : PGC_USERSET), + PGC_S_SESSION, + is_local ? GUC_ACTION_LOCAL : GUC_ACTION_SET, + true, 0, false); +} + +/* + * SET command wrapped as a SQL callable function. + */ +Datum +set_config_by_name(PG_FUNCTION_ARGS) +{ + char *name; + char *value; + char *new_value; + bool is_local; + + if (PG_ARGISNULL(0)) + ereport(ERROR, + (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED), + errmsg("SET requires parameter name"))); + + /* Get the GUC variable name */ + name = TextDatumGetCString(PG_GETARG_DATUM(0)); + + /* Get the desired value or set to NULL for a reset request */ + if (PG_ARGISNULL(1)) + value = NULL; + else + value = TextDatumGetCString(PG_GETARG_DATUM(1)); + + /* + * Get the desired state of is_local. Default to false if provided value + * is NULL + */ + if (PG_ARGISNULL(2)) + is_local = false; + else + is_local = PG_GETARG_BOOL(2); + + /* Note SET DEFAULT (argstring == NULL) is equivalent to RESET */ + (void) set_config_option(name, + value, + (superuser() ? PGC_SUSET : PGC_USERSET), + PGC_S_SESSION, + is_local ? GUC_ACTION_LOCAL : GUC_ACTION_SET, + true, 0, false); + + /* get the new current value */ + new_value = GetConfigOptionByName(name, NULL, false); + + /* Convert return string to text */ + PG_RETURN_TEXT_P(cstring_to_text(new_value)); +} + + +/* + * SHOW command + */ +void +GetPGVariable(const char *name, DestReceiver *dest) +{ + if (guc_name_compare(name, "all") == 0) + ShowAllGUCConfig(dest); + else + ShowGUCConfigOption(name, dest); +} + +/* + * Get a tuple descriptor for SHOW's result + */ +TupleDesc +GetPGVariableResultDesc(const char *name) +{ + TupleDesc tupdesc; + + if (guc_name_compare(name, "all") == 0) + { + /* need a tuple descriptor representing three TEXT columns */ + tupdesc = CreateTemplateTupleDesc(3); + TupleDescInitEntry(tupdesc, (AttrNumber) 1, "name", + TEXTOID, -1, 0); + TupleDescInitEntry(tupdesc, (AttrNumber) 2, "setting", + TEXTOID, -1, 0); + TupleDescInitEntry(tupdesc, (AttrNumber) 3, "description", + TEXTOID, -1, 0); + } + else + { + const char *varname; + + /* Get the canonical spelling of name */ + (void) GetConfigOptionByName(name, &varname, false); + + /* need a tuple descriptor representing a single TEXT column */ + tupdesc = CreateTemplateTupleDesc(1); + TupleDescInitEntry(tupdesc, (AttrNumber) 1, varname, + TEXTOID, -1, 0); + } + return tupdesc; +} + +/* + * SHOW one variable + */ +static void +ShowGUCConfigOption(const char *name, DestReceiver *dest) +{ + TupOutputState *tstate; + TupleDesc tupdesc; + const char *varname; + char *value; + + /* Get the value and canonical spelling of name */ + value = GetConfigOptionByName(name, &varname, false); + + /* need a tuple descriptor representing a single TEXT column */ + tupdesc = CreateTemplateTupleDesc(1); + TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 1, varname, + TEXTOID, -1, 0); + + /* prepare for projection of tuples */ + tstate = begin_tup_output_tupdesc(dest, tupdesc, &TTSOpsVirtual); + + /* Send it */ + do_text_output_oneline(tstate, value); + + end_tup_output(tstate); +} + +/* + * SHOW ALL command + */ +static void +ShowAllGUCConfig(DestReceiver *dest) +{ + int i; + TupOutputState *tstate; + TupleDesc tupdesc; + Datum values[3]; + bool isnull[3] = {false, false, false}; + struct config_generic **guc_variables = get_guc_variables(); + int num_guc_variables = GetNumConfigOptions(); + + /* need a tuple descriptor representing three TEXT columns */ + tupdesc = CreateTemplateTupleDesc(3); + TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 1, "name", + TEXTOID, -1, 0); + TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 2, "setting", + TEXTOID, -1, 0); + TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 3, "description", + TEXTOID, -1, 0); + + /* prepare for projection of tuples */ + tstate = begin_tup_output_tupdesc(dest, tupdesc, &TTSOpsVirtual); + + for (i = 0; i < num_guc_variables; i++) + { + struct config_generic *conf = guc_variables[i]; + char *setting; + + if ((conf->flags & GUC_NO_SHOW_ALL) || + ((conf->flags & GUC_SUPERUSER_ONLY) && + !has_privs_of_role(GetUserId(), ROLE_PG_READ_ALL_SETTINGS))) + continue; + + /* assign to the values array */ + values[0] = PointerGetDatum(cstring_to_text(conf->name)); + + setting = ShowGUCOption(conf, true); + if (setting) + { + values[1] = PointerGetDatum(cstring_to_text(setting)); + isnull[1] = false; + } + else + { + values[1] = PointerGetDatum(NULL); + isnull[1] = true; + } + + if (conf->short_desc) + { + values[2] = PointerGetDatum(cstring_to_text(conf->short_desc)); + isnull[2] = false; + } + else + { + values[2] = PointerGetDatum(NULL); + isnull[2] = true; + } + + /* send it to dest */ + do_tup_output(tstate, values, isnull); + + /* clean up */ + pfree(DatumGetPointer(values[0])); + if (setting) + { + pfree(setting); + pfree(DatumGetPointer(values[1])); + } + if (conf->short_desc) + pfree(DatumGetPointer(values[2])); + } + + end_tup_output(tstate); +} + +/* + * Return some of the flags associated to the specified GUC in the shape of + * a text array, and NULL if it does not exist. An empty array is returned + * if the GUC exists without any meaningful flags to show. + */ +Datum +pg_settings_get_flags(PG_FUNCTION_ARGS) +{ +#define MAX_GUC_FLAGS 5 + char *varname = TextDatumGetCString(PG_GETARG_DATUM(0)); + struct config_generic *record; + int cnt = 0; + Datum flags[MAX_GUC_FLAGS]; + ArrayType *a; + + record = find_option(varname, false, true, ERROR); + + /* return NULL if no such variable */ + if (record == NULL) + PG_RETURN_NULL(); + + if (record->flags & GUC_EXPLAIN) + flags[cnt++] = CStringGetTextDatum("EXPLAIN"); + if (record->flags & GUC_NO_RESET_ALL) + flags[cnt++] = CStringGetTextDatum("NO_RESET_ALL"); + if (record->flags & GUC_NO_SHOW_ALL) + flags[cnt++] = CStringGetTextDatum("NO_SHOW_ALL"); + if (record->flags & GUC_NOT_IN_SAMPLE) + flags[cnt++] = CStringGetTextDatum("NOT_IN_SAMPLE"); + if (record->flags & GUC_RUNTIME_COMPUTED) + flags[cnt++] = CStringGetTextDatum("RUNTIME_COMPUTED"); + + Assert(cnt <= MAX_GUC_FLAGS); + + /* Returns the record as Datum */ + a = construct_array_builtin(flags, cnt, TEXTOID); + PG_RETURN_ARRAYTYPE_P(a); +} + +/* + * Return GUC variable value by variable number; optionally return canonical + * form of name. Return value is palloc'd. + */ +static void +GetConfigOptionByNum(int varnum, const char **values, bool *noshow) +{ + char buffer[256]; + struct config_generic *conf; + struct config_generic **guc_variables = get_guc_variables(); + + /* check requested variable number valid */ + Assert((varnum >= 0) && (varnum < GetNumConfigOptions())); + + conf = guc_variables[varnum]; + + if (noshow) + { + if ((conf->flags & GUC_NO_SHOW_ALL) || + ((conf->flags & GUC_SUPERUSER_ONLY) && + !has_privs_of_role(GetUserId(), ROLE_PG_READ_ALL_SETTINGS))) + *noshow = true; + else + *noshow = false; + } + + /* first get the generic attributes */ + + /* name */ + values[0] = conf->name; + + /* setting: use ShowGUCOption in order to avoid duplicating the logic */ + values[1] = ShowGUCOption(conf, false); + + /* unit, if any (NULL is fine) */ + values[2] = get_config_unit_name(conf->flags); + + /* group */ + values[3] = _(config_group_names[conf->group]); + + /* short_desc */ + values[4] = conf->short_desc != NULL ? _(conf->short_desc) : NULL; + + /* extra_desc */ + values[5] = conf->long_desc != NULL ? _(conf->long_desc) : NULL; + + /* context */ + values[6] = GucContext_Names[conf->context]; + + /* vartype */ + values[7] = config_type_names[conf->vartype]; + + /* source */ + values[8] = GucSource_Names[conf->source]; + + /* now get the type specific attributes */ + switch (conf->vartype) + { + case PGC_BOOL: + { + struct config_bool *lconf = (struct config_bool *) conf; + + /* min_val */ + values[9] = NULL; + + /* max_val */ + values[10] = NULL; + + /* enumvals */ + values[11] = NULL; + + /* boot_val */ + values[12] = pstrdup(lconf->boot_val ? "on" : "off"); + + /* reset_val */ + values[13] = pstrdup(lconf->reset_val ? "on" : "off"); + } + break; + + case PGC_INT: + { + struct config_int *lconf = (struct config_int *) conf; + + /* min_val */ + snprintf(buffer, sizeof(buffer), "%d", lconf->min); + values[9] = pstrdup(buffer); + + /* max_val */ + snprintf(buffer, sizeof(buffer), "%d", lconf->max); + values[10] = pstrdup(buffer); + + /* enumvals */ + values[11] = NULL; + + /* boot_val */ + snprintf(buffer, sizeof(buffer), "%d", lconf->boot_val); + values[12] = pstrdup(buffer); + + /* reset_val */ + snprintf(buffer, sizeof(buffer), "%d", lconf->reset_val); + values[13] = pstrdup(buffer); + } + break; + + case PGC_REAL: + { + struct config_real *lconf = (struct config_real *) conf; + + /* min_val */ + snprintf(buffer, sizeof(buffer), "%g", lconf->min); + values[9] = pstrdup(buffer); + + /* max_val */ + snprintf(buffer, sizeof(buffer), "%g", lconf->max); + values[10] = pstrdup(buffer); + + /* enumvals */ + values[11] = NULL; + + /* boot_val */ + snprintf(buffer, sizeof(buffer), "%g", lconf->boot_val); + values[12] = pstrdup(buffer); + + /* reset_val */ + snprintf(buffer, sizeof(buffer), "%g", lconf->reset_val); + values[13] = pstrdup(buffer); + } + break; + + case PGC_STRING: + { + struct config_string *lconf = (struct config_string *) conf; + + /* min_val */ + values[9] = NULL; + + /* max_val */ + values[10] = NULL; + + /* enumvals */ + values[11] = NULL; + + /* boot_val */ + if (lconf->boot_val == NULL) + values[12] = NULL; + else + values[12] = pstrdup(lconf->boot_val); + + /* reset_val */ + if (lconf->reset_val == NULL) + values[13] = NULL; + else + values[13] = pstrdup(lconf->reset_val); + } + break; + + case PGC_ENUM: + { + struct config_enum *lconf = (struct config_enum *) conf; + + /* min_val */ + values[9] = NULL; + + /* max_val */ + values[10] = NULL; + + /* enumvals */ + + /* + * NOTE! enumvals with double quotes in them are not + * supported! + */ + values[11] = config_enum_get_options((struct config_enum *) conf, + "{\"", "\"}", "\",\""); + + /* boot_val */ + values[12] = pstrdup(config_enum_lookup_by_value(lconf, + lconf->boot_val)); + + /* reset_val */ + values[13] = pstrdup(config_enum_lookup_by_value(lconf, + lconf->reset_val)); + } + break; + + default: + { + /* + * should never get here, but in case we do, set 'em to NULL + */ + + /* min_val */ + values[9] = NULL; + + /* max_val */ + values[10] = NULL; + + /* enumvals */ + values[11] = NULL; + + /* boot_val */ + values[12] = NULL; + + /* reset_val */ + values[13] = NULL; + } + break; + } + + /* + * If the setting came from a config file, set the source location. For + * security reasons, we don't show source file/line number for + * insufficiently-privileged users. + */ + if (conf->source == PGC_S_FILE && + has_privs_of_role(GetUserId(), ROLE_PG_READ_ALL_SETTINGS)) + { + values[14] = conf->sourcefile; + snprintf(buffer, sizeof(buffer), "%d", conf->sourceline); + values[15] = pstrdup(buffer); + } + else + { + values[14] = NULL; + values[15] = NULL; + } + + values[16] = (conf->status & GUC_PENDING_RESTART) ? "t" : "f"; +} + +/* + * show_config_by_name - equiv to SHOW X command but implemented as + * a function. + */ +Datum +show_config_by_name(PG_FUNCTION_ARGS) +{ + char *varname = TextDatumGetCString(PG_GETARG_DATUM(0)); + char *varval; + + /* Get the value */ + varval = GetConfigOptionByName(varname, NULL, false); + + /* Convert to text */ + PG_RETURN_TEXT_P(cstring_to_text(varval)); +} + +/* + * show_config_by_name_missing_ok - equiv to SHOW X command but implemented as + * a function. If X does not exist, suppress the error and just return NULL + * if missing_ok is true. + */ +Datum +show_config_by_name_missing_ok(PG_FUNCTION_ARGS) +{ + char *varname = TextDatumGetCString(PG_GETARG_DATUM(0)); + bool missing_ok = PG_GETARG_BOOL(1); + char *varval; + + /* Get the value */ + varval = GetConfigOptionByName(varname, NULL, missing_ok); + + /* return NULL if no such variable */ + if (varval == NULL) + PG_RETURN_NULL(); + + /* Convert to text */ + PG_RETURN_TEXT_P(cstring_to_text(varval)); +} + +/* + * show_all_settings - equiv to SHOW ALL command but implemented as + * a Table Function. + */ +#define NUM_PG_SETTINGS_ATTS 17 + +Datum +show_all_settings(PG_FUNCTION_ARGS) +{ + FuncCallContext *funcctx; + TupleDesc tupdesc; + int call_cntr; + int max_calls; + AttInMetadata *attinmeta; + MemoryContext oldcontext; + + /* stuff done only on the first call of the function */ + if (SRF_IS_FIRSTCALL()) + { + /* create a function context for cross-call persistence */ + funcctx = SRF_FIRSTCALL_INIT(); + + /* + * switch to memory context appropriate for multiple function calls + */ + oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx); + + /* + * need a tuple descriptor representing NUM_PG_SETTINGS_ATTS columns + * of the appropriate types + */ + tupdesc = CreateTemplateTupleDesc(NUM_PG_SETTINGS_ATTS); + TupleDescInitEntry(tupdesc, (AttrNumber) 1, "name", + TEXTOID, -1, 0); + TupleDescInitEntry(tupdesc, (AttrNumber) 2, "setting", + TEXTOID, -1, 0); + TupleDescInitEntry(tupdesc, (AttrNumber) 3, "unit", + TEXTOID, -1, 0); + TupleDescInitEntry(tupdesc, (AttrNumber) 4, "category", + TEXTOID, -1, 0); + TupleDescInitEntry(tupdesc, (AttrNumber) 5, "short_desc", + TEXTOID, -1, 0); + TupleDescInitEntry(tupdesc, (AttrNumber) 6, "extra_desc", + TEXTOID, -1, 0); + TupleDescInitEntry(tupdesc, (AttrNumber) 7, "context", + TEXTOID, -1, 0); + TupleDescInitEntry(tupdesc, (AttrNumber) 8, "vartype", + TEXTOID, -1, 0); + TupleDescInitEntry(tupdesc, (AttrNumber) 9, "source", + TEXTOID, -1, 0); + TupleDescInitEntry(tupdesc, (AttrNumber) 10, "min_val", + TEXTOID, -1, 0); + TupleDescInitEntry(tupdesc, (AttrNumber) 11, "max_val", + TEXTOID, -1, 0); + TupleDescInitEntry(tupdesc, (AttrNumber) 12, "enumvals", + TEXTARRAYOID, -1, 0); + TupleDescInitEntry(tupdesc, (AttrNumber) 13, "boot_val", + TEXTOID, -1, 0); + TupleDescInitEntry(tupdesc, (AttrNumber) 14, "reset_val", + TEXTOID, -1, 0); + TupleDescInitEntry(tupdesc, (AttrNumber) 15, "sourcefile", + TEXTOID, -1, 0); + TupleDescInitEntry(tupdesc, (AttrNumber) 16, "sourceline", + INT4OID, -1, 0); + TupleDescInitEntry(tupdesc, (AttrNumber) 17, "pending_restart", + BOOLOID, -1, 0); + + /* + * Generate attribute metadata needed later to produce tuples from raw + * C strings + */ + attinmeta = TupleDescGetAttInMetadata(tupdesc); + funcctx->attinmeta = attinmeta; + + /* total number of tuples to be returned */ + funcctx->max_calls = GetNumConfigOptions(); + + MemoryContextSwitchTo(oldcontext); + } + + /* stuff done on every call of the function */ + funcctx = SRF_PERCALL_SETUP(); + + call_cntr = funcctx->call_cntr; + max_calls = funcctx->max_calls; + attinmeta = funcctx->attinmeta; + + if (call_cntr < max_calls) /* do when there is more left to send */ + { + char *values[NUM_PG_SETTINGS_ATTS]; + bool noshow; + HeapTuple tuple; + Datum result; + + /* + * Get the next visible GUC variable name and value + */ + do + { + GetConfigOptionByNum(call_cntr, (const char **) values, &noshow); + if (noshow) + { + /* bump the counter and get the next config setting */ + call_cntr = ++funcctx->call_cntr; + + /* make sure we haven't gone too far now */ + if (call_cntr >= max_calls) + SRF_RETURN_DONE(funcctx); + } + } while (noshow); + + /* build a tuple */ + tuple = BuildTupleFromCStrings(attinmeta, values); + + /* make the tuple into a datum */ + result = HeapTupleGetDatum(tuple); + + SRF_RETURN_NEXT(funcctx, result); + } + else + { + /* do when there is no more left */ + SRF_RETURN_DONE(funcctx); + } +} + +/* + * show_all_file_settings + * + * Returns a table of all parameter settings in all configuration files + * which includes the config file pathname, the line number, a sequence number + * indicating the order in which the settings were encountered, the parameter + * name and value, a bool showing if the value could be applied, and possibly + * an associated error message. (For problems such as syntax errors, the + * parameter name/value might be NULL.) + * + * Note: no filtering is done here, instead we depend on the GRANT system + * to prevent unprivileged users from accessing this function or the view + * built on top of it. + */ +Datum +show_all_file_settings(PG_FUNCTION_ARGS) +{ +#define NUM_PG_FILE_SETTINGS_ATTS 7 + ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo; + ConfigVariable *conf; + int seqno; + + /* Scan the config files using current context as workspace */ + conf = ProcessConfigFileInternal(PGC_SIGHUP, false, DEBUG3); + + /* Build a tuplestore to return our results in */ + SetSingleFuncCall(fcinfo, 0); + + /* Process the results and create a tuplestore */ + for (seqno = 1; conf != NULL; conf = conf->next, seqno++) + { + Datum values[NUM_PG_FILE_SETTINGS_ATTS]; + bool nulls[NUM_PG_FILE_SETTINGS_ATTS]; + + memset(values, 0, sizeof(values)); + memset(nulls, 0, sizeof(nulls)); + + /* sourcefile */ + if (conf->filename) + values[0] = PointerGetDatum(cstring_to_text(conf->filename)); + else + nulls[0] = true; + + /* sourceline (not meaningful if no sourcefile) */ + if (conf->filename) + values[1] = Int32GetDatum(conf->sourceline); + else + nulls[1] = true; + + /* seqno */ + values[2] = Int32GetDatum(seqno); + + /* name */ + if (conf->name) + values[3] = PointerGetDatum(cstring_to_text(conf->name)); + else + nulls[3] = true; + + /* setting */ + if (conf->value) + values[4] = PointerGetDatum(cstring_to_text(conf->value)); + else + nulls[4] = true; + + /* applied */ + values[5] = BoolGetDatum(conf->applied); + + /* error */ + if (conf->errmsg) + values[6] = PointerGetDatum(cstring_to_text(conf->errmsg)); + else + nulls[6] = true; + + /* shove row into tuplestore */ + tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc, values, nulls); + } + + return (Datum) 0; +} diff --git a/src/backend/utils/misc/guc_tables.c b/src/backend/utils/misc/guc_tables.c new file mode 100644 index 0000000000..87e625aa7a --- /dev/null +++ b/src/backend/utils/misc/guc_tables.c @@ -0,0 +1,4875 @@ +/*-------------------------------------------------------------------- + * + * guc_tables.c + * + * Static tables for the Grand Unified Configuration scheme. + * + * Many of these tables are const. However, ConfigureNamesBool[] + * and so on are not, because the structs in those arrays are actually + * the live per-variable state data that guc.c manipulates. While many of + * their fields are intended to be constant, some fields change at runtime. + * + * + * Copyright (c) 2000-2022, PostgreSQL Global Development Group + * Written by Peter Eisentraut . + * + * IDENTIFICATION + * src/backend/utils/misc/guc_tables.c + * + *-------------------------------------------------------------------- + */ +#include "postgres.h" + +#include +#include +#ifdef HAVE_SYSLOG +#include +#endif + +#include "access/commit_ts.h" +#include "access/gin.h" +#include "access/toast_compression.h" +#include "access/twophase.h" +#include "access/xlog_internal.h" +#include "access/xlogprefetcher.h" +#include "access/xlogrecovery.h" +#include "catalog/namespace.h" +#include "catalog/storage.h" +#include "commands/async.h" +#include "commands/tablespace.h" +#include "commands/trigger.h" +#include "commands/user.h" +#include "commands/vacuum.h" +#include "jit/jit.h" +#include "libpq/auth.h" +#include "libpq/libpq.h" +#include "optimizer/cost.h" +#include "optimizer/geqo.h" +#include "optimizer/optimizer.h" +#include "optimizer/paths.h" +#include "optimizer/planmain.h" +#include "parser/parse_expr.h" +#include "parser/parser.h" +#include "pgstat.h" +#include "postmaster/autovacuum.h" +#include "postmaster/bgworker_internals.h" +#include "postmaster/bgwriter.h" +#include "postmaster/postmaster.h" +#include "postmaster/startup.h" +#include "postmaster/syslogger.h" +#include "postmaster/walwriter.h" +#include "replication/logicallauncher.h" +#include "replication/slot.h" +#include "replication/syncrep.h" +#include "storage/bufmgr.h" +#include "storage/large_object.h" +#include "storage/pg_shmem.h" +#include "storage/predicate.h" +#include "storage/standby.h" +#include "tcop/tcopprot.h" +#include "tsearch/ts_cache.h" +#include "utils/builtins.h" +#include "utils/bytea.h" +#include "utils/float.h" +#include "utils/guc_hooks.h" +#include "utils/guc_tables.h" +#include "utils/memutils.h" +#include "utils/pg_locale.h" +#include "utils/portal.h" +#include "utils/ps_status.h" +#include "utils/queryjumble.h" +#include "utils/inval.h" +#include "utils/xml.h" + +/* This value is normally passed in from the Makefile */ +#ifndef PG_KRB_SRVTAB +#define PG_KRB_SRVTAB "" +#endif + +/* XXX these should appear in other modules' header files */ +extern bool Log_disconnections; +extern int CommitDelay; +extern int CommitSiblings; +extern char *default_tablespace; +extern char *temp_tablespaces; +extern bool ignore_checksum_failure; +extern bool ignore_invalid_pages; +extern bool synchronize_seqscans; + +#ifdef TRACE_SYNCSCAN +extern bool trace_syncscan; +#endif +#ifdef DEBUG_BOUNDED_SORT +extern bool optimize_bounded_sort; +#endif + +/* + * Options for enum values defined in this module. + * + * NOTE! Option values may not contain double quotes! + */ + +static const struct config_enum_entry bytea_output_options[] = { + {"escape", BYTEA_OUTPUT_ESCAPE, false}, + {"hex", BYTEA_OUTPUT_HEX, false}, + {NULL, 0, false} +}; + +StaticAssertDecl(lengthof(bytea_output_options) == (BYTEA_OUTPUT_HEX + 2), + "array length mismatch"); + +/* + * We have different sets for client and server message level options because + * they sort slightly different (see "log" level), and because "fatal"/"panic" + * aren't sensible for client_min_messages. + */ +static const struct config_enum_entry client_message_level_options[] = { + {"debug5", DEBUG5, false}, + {"debug4", DEBUG4, false}, + {"debug3", DEBUG3, false}, + {"debug2", DEBUG2, false}, + {"debug1", DEBUG1, false}, + {"debug", DEBUG2, true}, + {"log", LOG, false}, + {"info", INFO, true}, + {"notice", NOTICE, false}, + {"warning", WARNING, false}, + {"error", ERROR, false}, + {NULL, 0, false} +}; + +static const struct config_enum_entry server_message_level_options[] = { + {"debug5", DEBUG5, false}, + {"debug4", DEBUG4, false}, + {"debug3", DEBUG3, false}, + {"debug2", DEBUG2, false}, + {"debug1", DEBUG1, false}, + {"debug", DEBUG2, true}, + {"info", INFO, false}, + {"notice", NOTICE, false}, + {"warning", WARNING, false}, + {"error", ERROR, false}, + {"log", LOG, false}, + {"fatal", FATAL, false}, + {"panic", PANIC, false}, + {NULL, 0, false} +}; + +static const struct config_enum_entry intervalstyle_options[] = { + {"postgres", INTSTYLE_POSTGRES, false}, + {"postgres_verbose", INTSTYLE_POSTGRES_VERBOSE, false}, + {"sql_standard", INTSTYLE_SQL_STANDARD, false}, + {"iso_8601", INTSTYLE_ISO_8601, false}, + {NULL, 0, false} +}; + +StaticAssertDecl(lengthof(intervalstyle_options) == (INTSTYLE_ISO_8601 + 2), + "array length mismatch"); + +static const struct config_enum_entry log_error_verbosity_options[] = { + {"terse", PGERROR_TERSE, false}, + {"default", PGERROR_DEFAULT, false}, + {"verbose", PGERROR_VERBOSE, false}, + {NULL, 0, false} +}; + +StaticAssertDecl(lengthof(log_error_verbosity_options) == (PGERROR_VERBOSE + 2), + "array length mismatch"); + +static const struct config_enum_entry log_statement_options[] = { + {"none", LOGSTMT_NONE, false}, + {"ddl", LOGSTMT_DDL, false}, + {"mod", LOGSTMT_MOD, false}, + {"all", LOGSTMT_ALL, false}, + {NULL, 0, false} +}; + +StaticAssertDecl(lengthof(log_statement_options) == (LOGSTMT_ALL + 2), + "array length mismatch"); + +static const struct config_enum_entry isolation_level_options[] = { + {"serializable", XACT_SERIALIZABLE, false}, + {"repeatable read", XACT_REPEATABLE_READ, false}, + {"read committed", XACT_READ_COMMITTED, false}, + {"read uncommitted", XACT_READ_UNCOMMITTED, false}, + {NULL, 0} +}; + +static const struct config_enum_entry session_replication_role_options[] = { + {"origin", SESSION_REPLICATION_ROLE_ORIGIN, false}, + {"replica", SESSION_REPLICATION_ROLE_REPLICA, false}, + {"local", SESSION_REPLICATION_ROLE_LOCAL, false}, + {NULL, 0, false} +}; + +StaticAssertDecl(lengthof(session_replication_role_options) == (SESSION_REPLICATION_ROLE_LOCAL + 2), + "array length mismatch"); + +static const struct config_enum_entry syslog_facility_options[] = { +#ifdef HAVE_SYSLOG + {"local0", LOG_LOCAL0, false}, + {"local1", LOG_LOCAL1, false}, + {"local2", LOG_LOCAL2, false}, + {"local3", LOG_LOCAL3, false}, + {"local4", LOG_LOCAL4, false}, + {"local5", LOG_LOCAL5, false}, + {"local6", LOG_LOCAL6, false}, + {"local7", LOG_LOCAL7, false}, +#else + {"none", 0, false}, +#endif + {NULL, 0} +}; + +static const struct config_enum_entry track_function_options[] = { + {"none", TRACK_FUNC_OFF, false}, + {"pl", TRACK_FUNC_PL, false}, + {"all", TRACK_FUNC_ALL, false}, + {NULL, 0, false} +}; + +StaticAssertDecl(lengthof(track_function_options) == (TRACK_FUNC_ALL + 2), + "array length mismatch"); + +static const struct config_enum_entry stats_fetch_consistency[] = { + {"none", PGSTAT_FETCH_CONSISTENCY_NONE, false}, + {"cache", PGSTAT_FETCH_CONSISTENCY_CACHE, false}, + {"snapshot", PGSTAT_FETCH_CONSISTENCY_SNAPSHOT, false}, + {NULL, 0, false} +}; + +StaticAssertDecl(lengthof(stats_fetch_consistency) == (PGSTAT_FETCH_CONSISTENCY_SNAPSHOT + 2), + "array length mismatch"); + +static const struct config_enum_entry xmlbinary_options[] = { + {"base64", XMLBINARY_BASE64, false}, + {"hex", XMLBINARY_HEX, false}, + {NULL, 0, false} +}; + +StaticAssertDecl(lengthof(xmlbinary_options) == (XMLBINARY_HEX + 2), + "array length mismatch"); + +static const struct config_enum_entry xmloption_options[] = { + {"content", XMLOPTION_CONTENT, false}, + {"document", XMLOPTION_DOCUMENT, false}, + {NULL, 0, false} +}; + +StaticAssertDecl(lengthof(xmloption_options) == (XMLOPTION_CONTENT + 2), + "array length mismatch"); + +/* + * Although only "on", "off", and "safe_encoding" are documented, we + * accept all the likely variants of "on" and "off". + */ +static const struct config_enum_entry backslash_quote_options[] = { + {"safe_encoding", BACKSLASH_QUOTE_SAFE_ENCODING, false}, + {"on", BACKSLASH_QUOTE_ON, false}, + {"off", BACKSLASH_QUOTE_OFF, false}, + {"true", BACKSLASH_QUOTE_ON, true}, + {"false", BACKSLASH_QUOTE_OFF, true}, + {"yes", BACKSLASH_QUOTE_ON, true}, + {"no", BACKSLASH_QUOTE_OFF, true}, + {"1", BACKSLASH_QUOTE_ON, true}, + {"0", BACKSLASH_QUOTE_OFF, true}, + {NULL, 0, false} +}; + +/* + * Although only "on", "off", and "auto" are documented, we accept + * all the likely variants of "on" and "off". + */ +static const struct config_enum_entry compute_query_id_options[] = { + {"auto", COMPUTE_QUERY_ID_AUTO, false}, + {"regress", COMPUTE_QUERY_ID_REGRESS, false}, + {"on", COMPUTE_QUERY_ID_ON, false}, + {"off", COMPUTE_QUERY_ID_OFF, false}, + {"true", COMPUTE_QUERY_ID_ON, true}, + {"false", COMPUTE_QUERY_ID_OFF, true}, + {"yes", COMPUTE_QUERY_ID_ON, true}, + {"no", COMPUTE_QUERY_ID_OFF, true}, + {"1", COMPUTE_QUERY_ID_ON, true}, + {"0", COMPUTE_QUERY_ID_OFF, true}, + {NULL, 0, false} +}; + +/* + * Although only "on", "off", and "partition" are documented, we + * accept all the likely variants of "on" and "off". + */ +static const struct config_enum_entry constraint_exclusion_options[] = { + {"partition", CONSTRAINT_EXCLUSION_PARTITION, false}, + {"on", CONSTRAINT_EXCLUSION_ON, false}, + {"off", CONSTRAINT_EXCLUSION_OFF, false}, + {"true", CONSTRAINT_EXCLUSION_ON, true}, + {"false", CONSTRAINT_EXCLUSION_OFF, true}, + {"yes", CONSTRAINT_EXCLUSION_ON, true}, + {"no", CONSTRAINT_EXCLUSION_OFF, true}, + {"1", CONSTRAINT_EXCLUSION_ON, true}, + {"0", CONSTRAINT_EXCLUSION_OFF, true}, + {NULL, 0, false} +}; + +/* + * Although only "on", "off", "remote_apply", "remote_write", and "local" are + * documented, we accept all the likely variants of "on" and "off". + */ +static const struct config_enum_entry synchronous_commit_options[] = { + {"local", SYNCHRONOUS_COMMIT_LOCAL_FLUSH, false}, + {"remote_write", SYNCHRONOUS_COMMIT_REMOTE_WRITE, false}, + {"remote_apply", SYNCHRONOUS_COMMIT_REMOTE_APPLY, false}, + {"on", SYNCHRONOUS_COMMIT_ON, false}, + {"off", SYNCHRONOUS_COMMIT_OFF, false}, + {"true", SYNCHRONOUS_COMMIT_ON, true}, + {"false", SYNCHRONOUS_COMMIT_OFF, true}, + {"yes", SYNCHRONOUS_COMMIT_ON, true}, + {"no", SYNCHRONOUS_COMMIT_OFF, true}, + {"1", SYNCHRONOUS_COMMIT_ON, true}, + {"0", SYNCHRONOUS_COMMIT_OFF, true}, + {NULL, 0, false} +}; + +/* + * Although only "on", "off", "try" are documented, we accept all the likely + * variants of "on" and "off". + */ +static const struct config_enum_entry huge_pages_options[] = { + {"off", HUGE_PAGES_OFF, false}, + {"on", HUGE_PAGES_ON, false}, + {"try", HUGE_PAGES_TRY, false}, + {"true", HUGE_PAGES_ON, true}, + {"false", HUGE_PAGES_OFF, true}, + {"yes", HUGE_PAGES_ON, true}, + {"no", HUGE_PAGES_OFF, true}, + {"1", HUGE_PAGES_ON, true}, + {"0", HUGE_PAGES_OFF, true}, + {NULL, 0, false} +}; + +static const struct config_enum_entry recovery_prefetch_options[] = { + {"off", RECOVERY_PREFETCH_OFF, false}, + {"on", RECOVERY_PREFETCH_ON, false}, + {"try", RECOVERY_PREFETCH_TRY, false}, + {"true", RECOVERY_PREFETCH_ON, true}, + {"false", RECOVERY_PREFETCH_OFF, true}, + {"yes", RECOVERY_PREFETCH_ON, true}, + {"no", RECOVERY_PREFETCH_OFF, true}, + {"1", RECOVERY_PREFETCH_ON, true}, + {"0", RECOVERY_PREFETCH_OFF, true}, + {NULL, 0, false} +}; + +static const struct config_enum_entry force_parallel_mode_options[] = { + {"off", FORCE_PARALLEL_OFF, false}, + {"on", FORCE_PARALLEL_ON, false}, + {"regress", FORCE_PARALLEL_REGRESS, false}, + {"true", FORCE_PARALLEL_ON, true}, + {"false", FORCE_PARALLEL_OFF, true}, + {"yes", FORCE_PARALLEL_ON, true}, + {"no", FORCE_PARALLEL_OFF, true}, + {"1", FORCE_PARALLEL_ON, true}, + {"0", FORCE_PARALLEL_OFF, true}, + {NULL, 0, false} +}; + +static const struct config_enum_entry plan_cache_mode_options[] = { + {"auto", PLAN_CACHE_MODE_AUTO, false}, + {"force_generic_plan", PLAN_CACHE_MODE_FORCE_GENERIC_PLAN, false}, + {"force_custom_plan", PLAN_CACHE_MODE_FORCE_CUSTOM_PLAN, false}, + {NULL, 0, false} +}; + +static const struct config_enum_entry password_encryption_options[] = { + {"md5", PASSWORD_TYPE_MD5, false}, + {"scram-sha-256", PASSWORD_TYPE_SCRAM_SHA_256, false}, + {NULL, 0, false} +}; + +static const struct config_enum_entry ssl_protocol_versions_info[] = { + {"", PG_TLS_ANY, false}, + {"TLSv1", PG_TLS1_VERSION, false}, + {"TLSv1.1", PG_TLS1_1_VERSION, false}, + {"TLSv1.2", PG_TLS1_2_VERSION, false}, + {"TLSv1.3", PG_TLS1_3_VERSION, false}, + {NULL, 0, false} +}; + +StaticAssertDecl(lengthof(ssl_protocol_versions_info) == (PG_TLS1_3_VERSION + 2), + "array length mismatch"); + +static const struct config_enum_entry recovery_init_sync_method_options[] = { + {"fsync", RECOVERY_INIT_SYNC_METHOD_FSYNC, false}, +#ifdef HAVE_SYNCFS + {"syncfs", RECOVERY_INIT_SYNC_METHOD_SYNCFS, false}, +#endif + {NULL, 0, false} +}; + +static const struct config_enum_entry shared_memory_options[] = { +#ifndef WIN32 + {"sysv", SHMEM_TYPE_SYSV, false}, +#endif +#ifndef EXEC_BACKEND + {"mmap", SHMEM_TYPE_MMAP, false}, +#endif +#ifdef WIN32 + {"windows", SHMEM_TYPE_WINDOWS, false}, +#endif + {NULL, 0, false} +}; + +static const struct config_enum_entry default_toast_compression_options[] = { + {"pglz", TOAST_PGLZ_COMPRESSION, false}, +#ifdef USE_LZ4 + {"lz4", TOAST_LZ4_COMPRESSION, false}, +#endif + {NULL, 0, false} +}; + +static const struct config_enum_entry wal_compression_options[] = { + {"pglz", WAL_COMPRESSION_PGLZ, false}, +#ifdef USE_LZ4 + {"lz4", WAL_COMPRESSION_LZ4, false}, +#endif +#ifdef USE_ZSTD + {"zstd", WAL_COMPRESSION_ZSTD, false}, +#endif + {"on", WAL_COMPRESSION_PGLZ, false}, + {"off", WAL_COMPRESSION_NONE, false}, + {"true", WAL_COMPRESSION_PGLZ, true}, + {"false", WAL_COMPRESSION_NONE, true}, + {"yes", WAL_COMPRESSION_PGLZ, true}, + {"no", WAL_COMPRESSION_NONE, true}, + {"1", WAL_COMPRESSION_PGLZ, true}, + {"0", WAL_COMPRESSION_NONE, true}, + {NULL, 0, false} +}; + +/* + * Options for enum values stored in other modules + */ +extern const struct config_enum_entry wal_level_options[]; +extern const struct config_enum_entry archive_mode_options[]; +extern const struct config_enum_entry recovery_target_action_options[]; +extern const struct config_enum_entry sync_method_options[]; +extern const struct config_enum_entry dynamic_shared_memory_options[]; + +/* + * GUC option variables that are exported from this module + */ +bool log_duration = false; +bool Debug_print_plan = false; +bool Debug_print_parse = false; +bool Debug_print_rewritten = false; +bool Debug_pretty_print = true; + +bool log_parser_stats = false; +bool log_planner_stats = false; +bool log_executor_stats = false; +bool log_statement_stats = false; /* this is sort of all three above + * together */ +bool log_btree_build_stats = false; +char *event_source; + +bool row_security; +bool check_function_bodies = true; + +/* + * This GUC exists solely for backward compatibility, check its definition for + * details. + */ +bool default_with_oids = false; +bool session_auth_is_superuser; + +int log_min_error_statement = ERROR; +int log_min_messages = WARNING; +int client_min_messages = NOTICE; +int log_min_duration_sample = -1; +int log_min_duration_statement = -1; +int log_parameter_max_length = -1; +int log_parameter_max_length_on_error = 0; +int log_temp_files = -1; +double log_statement_sample_rate = 1.0; +double log_xact_sample_rate = 0; +int trace_recovery_messages = LOG; +char *backtrace_functions; + +int temp_file_limit = -1; + +int num_temp_buffers = 1024; + +char *cluster_name = ""; +char *ConfigFileName; +char *HbaFileName; +char *IdentFileName; +char *external_pid_file; + +char *pgstat_temp_directory; + +char *application_name; + +int tcp_keepalives_idle; +int tcp_keepalives_interval; +int tcp_keepalives_count; +int tcp_user_timeout; + +/* + * SSL renegotiation was been removed in PostgreSQL 9.5, but we tolerate it + * being set to zero (meaning never renegotiate) for backward compatibility. + * This avoids breaking compatibility with clients that have never supported + * renegotiation and therefore always try to zero it. + */ +int ssl_renegotiation_limit; + +/* + * This really belongs in pg_shmem.c, but is defined here so that it doesn't + * need to be duplicated in all the different implementations of pg_shmem.c. + */ +int huge_pages; +int huge_page_size; + +/* + * These variables are all dummies that don't do anything, except in some + * cases provide the value for SHOW to display. The real state is elsewhere + * and is kept in sync by assign_hooks. + */ +static char *syslog_ident_str; +static double phony_random_seed; +static char *client_encoding_string; +static char *datestyle_string; +static char *locale_collate; +static char *locale_ctype; +static char *server_encoding_string; +static char *server_version_string; +static int server_version_num; +static int syslog_facility; +static char *timezone_string; +static char *log_timezone_string; +static char *timezone_abbreviations_string; +static char *data_directory; +static char *session_authorization_string; +static int max_function_args; +static int max_index_keys; +static int max_identifier_length; +static int block_size; +static int segment_size; +static int shared_memory_size_mb; +static int shared_memory_size_in_huge_pages; +static int wal_block_size; +static bool data_checksums; +static bool integer_datetimes; +static bool assert_enabled; +static char *recovery_target_timeline_string; +static char *recovery_target_string; +static char *recovery_target_xid_string; +static char *recovery_target_name_string; +static char *recovery_target_lsn_string; + +/* should be static, but commands/variable.c needs to get at this */ +char *role_string; + +/* should be static, but guc.c needs to get at this */ +bool in_hot_standby_guc; + + +/* + * Displayable names for context types (enum GucContext) + * + * Note: these strings are deliberately not localized. + */ +const char *const GucContext_Names[] = +{ + /* PGC_INTERNAL */ "internal", + /* PGC_POSTMASTER */ "postmaster", + /* PGC_SIGHUP */ "sighup", + /* PGC_SU_BACKEND */ "superuser-backend", + /* PGC_BACKEND */ "backend", + /* PGC_SUSET */ "superuser", + /* PGC_USERSET */ "user" +}; + +StaticAssertDecl(lengthof(GucContext_Names) == (PGC_USERSET + 1), + "array length mismatch"); + +/* + * Displayable names for source types (enum GucSource) + * + * Note: these strings are deliberately not localized. + */ +const char *const GucSource_Names[] = +{ + /* PGC_S_DEFAULT */ "default", + /* PGC_S_DYNAMIC_DEFAULT */ "default", + /* PGC_S_ENV_VAR */ "environment variable", + /* PGC_S_FILE */ "configuration file", + /* PGC_S_ARGV */ "command line", + /* PGC_S_GLOBAL */ "global", + /* PGC_S_DATABASE */ "database", + /* PGC_S_USER */ "user", + /* PGC_S_DATABASE_USER */ "database user", + /* PGC_S_CLIENT */ "client", + /* PGC_S_OVERRIDE */ "override", + /* PGC_S_INTERACTIVE */ "interactive", + /* PGC_S_TEST */ "test", + /* PGC_S_SESSION */ "session" +}; + +StaticAssertDecl(lengthof(GucSource_Names) == (PGC_S_SESSION + 1), + "array length mismatch"); + +/* + * Displayable names for the groupings defined in enum config_group + */ +const char *const config_group_names[] = +{ + /* UNGROUPED */ + gettext_noop("Ungrouped"), + /* FILE_LOCATIONS */ + gettext_noop("File Locations"), + /* CONN_AUTH_SETTINGS */ + gettext_noop("Connections and Authentication / Connection Settings"), + /* CONN_AUTH_TCP */ + gettext_noop("Connections and Authentication / TCP Settings"), + /* CONN_AUTH_AUTH */ + gettext_noop("Connections and Authentication / Authentication"), + /* CONN_AUTH_SSL */ + gettext_noop("Connections and Authentication / SSL"), + /* RESOURCES_MEM */ + gettext_noop("Resource Usage / Memory"), + /* RESOURCES_DISK */ + gettext_noop("Resource Usage / Disk"), + /* RESOURCES_KERNEL */ + gettext_noop("Resource Usage / Kernel Resources"), + /* RESOURCES_VACUUM_DELAY */ + gettext_noop("Resource Usage / Cost-Based Vacuum Delay"), + /* RESOURCES_BGWRITER */ + gettext_noop("Resource Usage / Background Writer"), + /* RESOURCES_ASYNCHRONOUS */ + gettext_noop("Resource Usage / Asynchronous Behavior"), + /* WAL_SETTINGS */ + gettext_noop("Write-Ahead Log / Settings"), + /* WAL_CHECKPOINTS */ + gettext_noop("Write-Ahead Log / Checkpoints"), + /* WAL_ARCHIVING */ + gettext_noop("Write-Ahead Log / Archiving"), + /* WAL_RECOVERY */ + gettext_noop("Write-Ahead Log / Recovery"), + /* WAL_ARCHIVE_RECOVERY */ + gettext_noop("Write-Ahead Log / Archive Recovery"), + /* WAL_RECOVERY_TARGET */ + gettext_noop("Write-Ahead Log / Recovery Target"), + /* REPLICATION_SENDING */ + gettext_noop("Replication / Sending Servers"), + /* REPLICATION_PRIMARY */ + gettext_noop("Replication / Primary Server"), + /* REPLICATION_STANDBY */ + gettext_noop("Replication / Standby Servers"), + /* REPLICATION_SUBSCRIBERS */ + gettext_noop("Replication / Subscribers"), + /* QUERY_TUNING_METHOD */ + gettext_noop("Query Tuning / Planner Method Configuration"), + /* QUERY_TUNING_COST */ + gettext_noop("Query Tuning / Planner Cost Constants"), + /* QUERY_TUNING_GEQO */ + gettext_noop("Query Tuning / Genetic Query Optimizer"), + /* QUERY_TUNING_OTHER */ + gettext_noop("Query Tuning / Other Planner Options"), + /* LOGGING_WHERE */ + gettext_noop("Reporting and Logging / Where to Log"), + /* LOGGING_WHEN */ + gettext_noop("Reporting and Logging / When to Log"), + /* LOGGING_WHAT */ + gettext_noop("Reporting and Logging / What to Log"), + /* PROCESS_TITLE */ + gettext_noop("Reporting and Logging / Process Title"), + /* STATS_MONITORING */ + gettext_noop("Statistics / Monitoring"), + /* STATS_CUMULATIVE */ + gettext_noop("Statistics / Cumulative Query and Index Statistics"), + /* AUTOVACUUM */ + gettext_noop("Autovacuum"), + /* CLIENT_CONN_STATEMENT */ + gettext_noop("Client Connection Defaults / Statement Behavior"), + /* CLIENT_CONN_LOCALE */ + gettext_noop("Client Connection Defaults / Locale and Formatting"), + /* CLIENT_CONN_PRELOAD */ + gettext_noop("Client Connection Defaults / Shared Library Preloading"), + /* CLIENT_CONN_OTHER */ + gettext_noop("Client Connection Defaults / Other Defaults"), + /* LOCK_MANAGEMENT */ + gettext_noop("Lock Management"), + /* COMPAT_OPTIONS_PREVIOUS */ + gettext_noop("Version and Platform Compatibility / Previous PostgreSQL Versions"), + /* COMPAT_OPTIONS_CLIENT */ + gettext_noop("Version and Platform Compatibility / Other Platforms and Clients"), + /* ERROR_HANDLING */ + gettext_noop("Error Handling"), + /* PRESET_OPTIONS */ + gettext_noop("Preset Options"), + /* CUSTOM_OPTIONS */ + gettext_noop("Customized Options"), + /* DEVELOPER_OPTIONS */ + gettext_noop("Developer Options"), + /* help_config wants this array to be null-terminated */ + NULL +}; + +StaticAssertDecl(lengthof(config_group_names) == (DEVELOPER_OPTIONS + 2), + "array length mismatch"); + +/* + * Displayable names for GUC variable types (enum config_type) + * + * Note: these strings are deliberately not localized. + */ +const char *const config_type_names[] = +{ + /* PGC_BOOL */ "bool", + /* PGC_INT */ "integer", + /* PGC_REAL */ "real", + /* PGC_STRING */ "string", + /* PGC_ENUM */ "enum" +}; + +StaticAssertDecl(lengthof(config_type_names) == (PGC_ENUM + 1), + "array length mismatch"); + + +/* + * Contents of GUC tables + * + * See src/backend/utils/misc/README for design notes. + * + * TO ADD AN OPTION: + * + * 1. Declare a global variable of type bool, int, double, or char* + * and make use of it. + * + * 2. Decide at what times it's safe to set the option. See guc.h for + * details. + * + * 3. Decide on a name, a default value, upper and lower bounds (if + * applicable), etc. + * + * 4. Add a record below. + * + * 5. Add it to src/backend/utils/misc/postgresql.conf.sample, if + * appropriate. + * + * 6. Don't forget to document the option (at least in config.sgml). + * + * 7. If it's a new GUC_LIST_QUOTE option, you must add it to + * variable_is_guc_list_quote() in src/bin/pg_dump/dumputils.c. + */ + +struct config_bool ConfigureNamesBool[] = +{ + { + {"enable_seqscan", PGC_USERSET, QUERY_TUNING_METHOD, + gettext_noop("Enables the planner's use of sequential-scan plans."), + NULL, + GUC_EXPLAIN + }, + &enable_seqscan, + true, + NULL, NULL, NULL + }, + { + {"enable_indexscan", PGC_USERSET, QUERY_TUNING_METHOD, + gettext_noop("Enables the planner's use of index-scan plans."), + NULL, + GUC_EXPLAIN + }, + &enable_indexscan, + true, + NULL, NULL, NULL + }, + { + {"enable_indexonlyscan", PGC_USERSET, QUERY_TUNING_METHOD, + gettext_noop("Enables the planner's use of index-only-scan plans."), + NULL, + GUC_EXPLAIN + }, + &enable_indexonlyscan, + true, + NULL, NULL, NULL + }, + { + {"enable_bitmapscan", PGC_USERSET, QUERY_TUNING_METHOD, + gettext_noop("Enables the planner's use of bitmap-scan plans."), + NULL, + GUC_EXPLAIN + }, + &enable_bitmapscan, + true, + NULL, NULL, NULL + }, + { + {"enable_tidscan", PGC_USERSET, QUERY_TUNING_METHOD, + gettext_noop("Enables the planner's use of TID scan plans."), + NULL, + GUC_EXPLAIN + }, + &enable_tidscan, + true, + NULL, NULL, NULL + }, + { + {"enable_sort", PGC_USERSET, QUERY_TUNING_METHOD, + gettext_noop("Enables the planner's use of explicit sort steps."), + NULL, + GUC_EXPLAIN + }, + &enable_sort, + true, + NULL, NULL, NULL + }, + { + {"enable_incremental_sort", PGC_USERSET, QUERY_TUNING_METHOD, + gettext_noop("Enables the planner's use of incremental sort steps."), + NULL, + GUC_EXPLAIN + }, + &enable_incremental_sort, + true, + NULL, NULL, NULL + }, + { + {"enable_hashagg", PGC_USERSET, QUERY_TUNING_METHOD, + gettext_noop("Enables the planner's use of hashed aggregation plans."), + NULL, + GUC_EXPLAIN + }, + &enable_hashagg, + true, + NULL, NULL, NULL + }, + { + {"enable_material", PGC_USERSET, QUERY_TUNING_METHOD, + gettext_noop("Enables the planner's use of materialization."), + NULL, + GUC_EXPLAIN + }, + &enable_material, + true, + NULL, NULL, NULL + }, + { + {"enable_memoize", PGC_USERSET, QUERY_TUNING_METHOD, + gettext_noop("Enables the planner's use of memoization."), + NULL, + GUC_EXPLAIN + }, + &enable_memoize, + true, + NULL, NULL, NULL + }, + { + {"enable_nestloop", PGC_USERSET, QUERY_TUNING_METHOD, + gettext_noop("Enables the planner's use of nested-loop join plans."), + NULL, + GUC_EXPLAIN + }, + &enable_nestloop, + true, + NULL, NULL, NULL + }, + { + {"enable_mergejoin", PGC_USERSET, QUERY_TUNING_METHOD, + gettext_noop("Enables the planner's use of merge join plans."), + NULL, + GUC_EXPLAIN + }, + &enable_mergejoin, + true, + NULL, NULL, NULL + }, + { + {"enable_hashjoin", PGC_USERSET, QUERY_TUNING_METHOD, + gettext_noop("Enables the planner's use of hash join plans."), + NULL, + GUC_EXPLAIN + }, + &enable_hashjoin, + true, + NULL, NULL, NULL + }, + { + {"enable_gathermerge", PGC_USERSET, QUERY_TUNING_METHOD, + gettext_noop("Enables the planner's use of gather merge plans."), + NULL, + GUC_EXPLAIN + }, + &enable_gathermerge, + true, + NULL, NULL, NULL + }, + { + {"enable_partitionwise_join", PGC_USERSET, QUERY_TUNING_METHOD, + gettext_noop("Enables partitionwise join."), + NULL, + GUC_EXPLAIN + }, + &enable_partitionwise_join, + false, + NULL, NULL, NULL + }, + { + {"enable_partitionwise_aggregate", PGC_USERSET, QUERY_TUNING_METHOD, + gettext_noop("Enables partitionwise aggregation and grouping."), + NULL, + GUC_EXPLAIN + }, + &enable_partitionwise_aggregate, + false, + NULL, NULL, NULL + }, + { + {"enable_parallel_append", PGC_USERSET, QUERY_TUNING_METHOD, + gettext_noop("Enables the planner's use of parallel append plans."), + NULL, + GUC_EXPLAIN + }, + &enable_parallel_append, + true, + NULL, NULL, NULL + }, + { + {"enable_parallel_hash", PGC_USERSET, QUERY_TUNING_METHOD, + gettext_noop("Enables the planner's use of parallel hash plans."), + NULL, + GUC_EXPLAIN + }, + &enable_parallel_hash, + true, + NULL, NULL, NULL + }, + { + {"enable_partition_pruning", PGC_USERSET, QUERY_TUNING_METHOD, + gettext_noop("Enables plan-time and execution-time partition pruning."), + gettext_noop("Allows the query planner and executor to compare partition " + "bounds to conditions in the query to determine which " + "partitions must be scanned."), + GUC_EXPLAIN + }, + &enable_partition_pruning, + true, + NULL, NULL, NULL + }, + { + {"enable_async_append", PGC_USERSET, QUERY_TUNING_METHOD, + gettext_noop("Enables the planner's use of async append plans."), + NULL, + GUC_EXPLAIN + }, + &enable_async_append, + true, + NULL, NULL, NULL + }, + { + {"enable_group_by_reordering", PGC_USERSET, QUERY_TUNING_METHOD, + gettext_noop("Enable reordering of GROUP BY key."), + NULL, + GUC_EXPLAIN + }, + &enable_group_by_reordering, + true, + NULL, NULL, NULL + }, + { + {"geqo", PGC_USERSET, QUERY_TUNING_GEQO, + gettext_noop("Enables genetic query optimization."), + gettext_noop("This algorithm attempts to do planning without " + "exhaustive searching."), + GUC_EXPLAIN + }, + &enable_geqo, + true, + NULL, NULL, NULL + }, + { + /* Not for general use --- used by SET SESSION AUTHORIZATION */ + {"is_superuser", PGC_INTERNAL, UNGROUPED, + gettext_noop("Shows whether the current user is a superuser."), + NULL, + GUC_REPORT | GUC_NO_SHOW_ALL | GUC_NO_RESET_ALL | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE + }, + &session_auth_is_superuser, + false, + NULL, NULL, NULL + }, + { + {"bonjour", PGC_POSTMASTER, CONN_AUTH_SETTINGS, + gettext_noop("Enables advertising the server via Bonjour."), + NULL + }, + &enable_bonjour, + false, + check_bonjour, NULL, NULL + }, + { + {"track_commit_timestamp", PGC_POSTMASTER, REPLICATION_SENDING, + gettext_noop("Collects transaction commit time."), + NULL + }, + &track_commit_timestamp, + false, + NULL, NULL, NULL + }, + { + {"ssl", PGC_SIGHUP, CONN_AUTH_SSL, + gettext_noop("Enables SSL connections."), + NULL + }, + &EnableSSL, + false, + check_ssl, NULL, NULL + }, + { + {"ssl_passphrase_command_supports_reload", PGC_SIGHUP, CONN_AUTH_SSL, + gettext_noop("Controls whether ssl_passphrase_command is called during server reload."), + NULL + }, + &ssl_passphrase_command_supports_reload, + false, + NULL, NULL, NULL + }, + { + {"ssl_prefer_server_ciphers", PGC_SIGHUP, CONN_AUTH_SSL, + gettext_noop("Give priority to server ciphersuite order."), + NULL + }, + &SSLPreferServerCiphers, + true, + NULL, NULL, NULL + }, + { + {"fsync", PGC_SIGHUP, WAL_SETTINGS, + gettext_noop("Forces synchronization of updates to disk."), + gettext_noop("The server will use the fsync() system call in several places to make " + "sure that updates are physically written to disk. This insures " + "that a database cluster will recover to a consistent state after " + "an operating system or hardware crash.") + }, + &enableFsync, + true, + NULL, NULL, NULL + }, + { + {"ignore_checksum_failure", PGC_SUSET, DEVELOPER_OPTIONS, + gettext_noop("Continues processing after a checksum failure."), + gettext_noop("Detection of a checksum failure normally causes PostgreSQL to " + "report an error, aborting the current transaction. Setting " + "ignore_checksum_failure to true causes the system to ignore the failure " + "(but still report a warning), and continue processing. This " + "behavior could cause crashes or other serious problems. Only " + "has an effect if checksums are enabled."), + GUC_NOT_IN_SAMPLE + }, + &ignore_checksum_failure, + false, + NULL, NULL, NULL + }, + { + {"zero_damaged_pages", PGC_SUSET, DEVELOPER_OPTIONS, + gettext_noop("Continues processing past damaged page headers."), + gettext_noop("Detection of a damaged page header normally causes PostgreSQL to " + "report an error, aborting the current transaction. Setting " + "zero_damaged_pages to true causes the system to instead report a " + "warning, zero out the damaged page, and continue processing. This " + "behavior will destroy data, namely all the rows on the damaged page."), + GUC_NOT_IN_SAMPLE + }, + &zero_damaged_pages, + false, + NULL, NULL, NULL + }, + { + {"ignore_invalid_pages", PGC_POSTMASTER, DEVELOPER_OPTIONS, + gettext_noop("Continues recovery after an invalid pages failure."), + gettext_noop("Detection of WAL records having references to " + "invalid pages during recovery causes PostgreSQL to " + "raise a PANIC-level error, aborting the recovery. " + "Setting ignore_invalid_pages to true causes " + "the system to ignore invalid page references " + "in WAL records (but still report a warning), " + "and continue recovery. This behavior may cause " + "crashes, data loss, propagate or hide corruption, " + "or other serious problems. Only has an effect " + "during recovery or in standby mode."), + GUC_NOT_IN_SAMPLE + }, + &ignore_invalid_pages, + false, + NULL, NULL, NULL + }, + { + {"full_page_writes", PGC_SIGHUP, WAL_SETTINGS, + gettext_noop("Writes full pages to WAL when first modified after a checkpoint."), + gettext_noop("A page write in process during an operating system crash might be " + "only partially written to disk. During recovery, the row changes " + "stored in WAL are not enough to recover. This option writes " + "pages when first modified after a checkpoint to WAL so full recovery " + "is possible.") + }, + &fullPageWrites, + true, + NULL, NULL, NULL + }, + + { + {"wal_log_hints", PGC_POSTMASTER, WAL_SETTINGS, + gettext_noop("Writes full pages to WAL when first modified after a checkpoint, even for a non-critical modification."), + NULL + }, + &wal_log_hints, + false, + NULL, NULL, NULL + }, + + { + {"wal_init_zero", PGC_SUSET, WAL_SETTINGS, + gettext_noop("Writes zeroes to new WAL files before first use."), + NULL + }, + &wal_init_zero, + true, + NULL, NULL, NULL + }, + + { + {"wal_recycle", PGC_SUSET, WAL_SETTINGS, + gettext_noop("Recycles WAL files by renaming them."), + NULL + }, + &wal_recycle, + true, + NULL, NULL, NULL + }, + + { + {"log_checkpoints", PGC_SIGHUP, LOGGING_WHAT, + gettext_noop("Logs each checkpoint."), + NULL + }, + &log_checkpoints, + true, + NULL, NULL, NULL + }, + { + {"log_connections", PGC_SU_BACKEND, LOGGING_WHAT, + gettext_noop("Logs each successful connection."), + NULL + }, + &Log_connections, + false, + NULL, NULL, NULL + }, + { + {"log_disconnections", PGC_SU_BACKEND, LOGGING_WHAT, + gettext_noop("Logs end of a session, including duration."), + NULL + }, + &Log_disconnections, + false, + NULL, NULL, NULL + }, + { + {"log_replication_commands", PGC_SUSET, LOGGING_WHAT, + gettext_noop("Logs each replication command."), + NULL + }, + &log_replication_commands, + false, + NULL, NULL, NULL + }, + { + {"debug_assertions", PGC_INTERNAL, PRESET_OPTIONS, + gettext_noop("Shows whether the running server has assertion checks enabled."), + NULL, + GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE + }, + &assert_enabled, +#ifdef USE_ASSERT_CHECKING + true, +#else + false, +#endif + NULL, NULL, NULL + }, + + { + {"exit_on_error", PGC_USERSET, ERROR_HANDLING_OPTIONS, + gettext_noop("Terminate session on any error."), + NULL + }, + &ExitOnAnyError, + false, + NULL, NULL, NULL + }, + { + {"restart_after_crash", PGC_SIGHUP, ERROR_HANDLING_OPTIONS, + gettext_noop("Reinitialize server after backend crash."), + NULL + }, + &restart_after_crash, + true, + NULL, NULL, NULL + }, + { + {"remove_temp_files_after_crash", PGC_SIGHUP, DEVELOPER_OPTIONS, + gettext_noop("Remove temporary files after backend crash."), + NULL, + GUC_NOT_IN_SAMPLE + }, + &remove_temp_files_after_crash, + true, + NULL, NULL, NULL + }, + + { + {"log_duration", PGC_SUSET, LOGGING_WHAT, + gettext_noop("Logs the duration of each completed SQL statement."), + NULL + }, + &log_duration, + false, + NULL, NULL, NULL + }, + { + {"debug_print_parse", PGC_USERSET, LOGGING_WHAT, + gettext_noop("Logs each query's parse tree."), + NULL + }, + &Debug_print_parse, + false, + NULL, NULL, NULL + }, + { + {"debug_print_rewritten", PGC_USERSET, LOGGING_WHAT, + gettext_noop("Logs each query's rewritten parse tree."), + NULL + }, + &Debug_print_rewritten, + false, + NULL, NULL, NULL + }, + { + {"debug_print_plan", PGC_USERSET, LOGGING_WHAT, + gettext_noop("Logs each query's execution plan."), + NULL + }, + &Debug_print_plan, + false, + NULL, NULL, NULL + }, + { + {"debug_pretty_print", PGC_USERSET, LOGGING_WHAT, + gettext_noop("Indents parse and plan tree displays."), + NULL + }, + &Debug_pretty_print, + true, + NULL, NULL, NULL + }, + { + {"log_parser_stats", PGC_SUSET, STATS_MONITORING, + gettext_noop("Writes parser performance statistics to the server log."), + NULL + }, + &log_parser_stats, + false, + check_stage_log_stats, NULL, NULL + }, + { + {"log_planner_stats", PGC_SUSET, STATS_MONITORING, + gettext_noop("Writes planner performance statistics to the server log."), + NULL + }, + &log_planner_stats, + false, + check_stage_log_stats, NULL, NULL + }, + { + {"log_executor_stats", PGC_SUSET, STATS_MONITORING, + gettext_noop("Writes executor performance statistics to the server log."), + NULL + }, + &log_executor_stats, + false, + check_stage_log_stats, NULL, NULL + }, + { + {"log_statement_stats", PGC_SUSET, STATS_MONITORING, + gettext_noop("Writes cumulative performance statistics to the server log."), + NULL + }, + &log_statement_stats, + false, + check_log_stats, NULL, NULL + }, +#ifdef BTREE_BUILD_STATS + { + {"log_btree_build_stats", PGC_SUSET, DEVELOPER_OPTIONS, + gettext_noop("Logs system resource usage statistics (memory and CPU) on various B-tree operations."), + NULL, + GUC_NOT_IN_SAMPLE + }, + &log_btree_build_stats, + false, + NULL, NULL, NULL + }, +#endif + + { + {"track_activities", PGC_SUSET, STATS_CUMULATIVE, + gettext_noop("Collects information about executing commands."), + gettext_noop("Enables the collection of information on the currently " + "executing command of each session, along with " + "the time at which that command began execution.") + }, + &pgstat_track_activities, + true, + NULL, NULL, NULL + }, + { + {"track_counts", PGC_SUSET, STATS_CUMULATIVE, + gettext_noop("Collects statistics on database activity."), + NULL + }, + &pgstat_track_counts, + true, + NULL, NULL, NULL + }, + { + {"track_io_timing", PGC_SUSET, STATS_CUMULATIVE, + gettext_noop("Collects timing statistics for database I/O activity."), + NULL + }, + &track_io_timing, + false, + NULL, NULL, NULL + }, + { + {"track_wal_io_timing", PGC_SUSET, STATS_CUMULATIVE, + gettext_noop("Collects timing statistics for WAL I/O activity."), + NULL + }, + &track_wal_io_timing, + false, + NULL, NULL, NULL + }, + + { + {"update_process_title", PGC_SUSET, PROCESS_TITLE, + gettext_noop("Updates the process title to show the active SQL command."), + gettext_noop("Enables updating of the process title every time a new SQL command is received by the server.") + }, + &update_process_title, +#ifdef WIN32 + false, +#else + true, +#endif + NULL, NULL, NULL + }, + + { + {"autovacuum", PGC_SIGHUP, AUTOVACUUM, + gettext_noop("Starts the autovacuum subprocess."), + NULL + }, + &autovacuum_start_daemon, + true, + NULL, NULL, NULL + }, + + { + {"trace_notify", PGC_USERSET, DEVELOPER_OPTIONS, + gettext_noop("Generates debugging output for LISTEN and NOTIFY."), + NULL, + GUC_NOT_IN_SAMPLE + }, + &Trace_notify, + false, + NULL, NULL, NULL + }, + +#ifdef LOCK_DEBUG + { + {"trace_locks", PGC_SUSET, DEVELOPER_OPTIONS, + gettext_noop("Emits information about lock usage."), + NULL, + GUC_NOT_IN_SAMPLE + }, + &Trace_locks, + false, + NULL, NULL, NULL + }, + { + {"trace_userlocks", PGC_SUSET, DEVELOPER_OPTIONS, + gettext_noop("Emits information about user lock usage."), + NULL, + GUC_NOT_IN_SAMPLE + }, + &Trace_userlocks, + false, + NULL, NULL, NULL + }, + { + {"trace_lwlocks", PGC_SUSET, DEVELOPER_OPTIONS, + gettext_noop("Emits information about lightweight lock usage."), + NULL, + GUC_NOT_IN_SAMPLE + }, + &Trace_lwlocks, + false, + NULL, NULL, NULL + }, + { + {"debug_deadlocks", PGC_SUSET, DEVELOPER_OPTIONS, + gettext_noop("Dumps information about all current locks when a deadlock timeout occurs."), + NULL, + GUC_NOT_IN_SAMPLE + }, + &Debug_deadlocks, + false, + NULL, NULL, NULL + }, +#endif + + { + {"log_lock_waits", PGC_SUSET, LOGGING_WHAT, + gettext_noop("Logs long lock waits."), + NULL + }, + &log_lock_waits, + false, + NULL, NULL, NULL + }, + { + {"log_recovery_conflict_waits", PGC_SIGHUP, LOGGING_WHAT, + gettext_noop("Logs standby recovery conflict waits."), + NULL + }, + &log_recovery_conflict_waits, + false, + NULL, NULL, NULL + }, + { + {"log_hostname", PGC_SIGHUP, LOGGING_WHAT, + gettext_noop("Logs the host name in the connection logs."), + gettext_noop("By default, connection logs only show the IP address " + "of the connecting host. If you want them to show the host name you " + "can turn this on, but depending on your host name resolution " + "setup it might impose a non-negligible performance penalty.") + }, + &log_hostname, + false, + NULL, NULL, NULL + }, + { + {"transform_null_equals", PGC_USERSET, COMPAT_OPTIONS_CLIENT, + gettext_noop("Treats \"expr=NULL\" as \"expr IS NULL\"."), + gettext_noop("When turned on, expressions of the form expr = NULL " + "(or NULL = expr) are treated as expr IS NULL, that is, they " + "return true if expr evaluates to the null value, and false " + "otherwise. The correct behavior of expr = NULL is to always " + "return null (unknown).") + }, + &Transform_null_equals, + false, + NULL, NULL, NULL + }, + { + {"db_user_namespace", PGC_SIGHUP, CONN_AUTH_AUTH, + gettext_noop("Enables per-database user names."), + NULL + }, + &Db_user_namespace, + false, + NULL, NULL, NULL + }, + { + {"default_transaction_read_only", PGC_USERSET, CLIENT_CONN_STATEMENT, + gettext_noop("Sets the default read-only status of new transactions."), + NULL, + GUC_REPORT + }, + &DefaultXactReadOnly, + false, + NULL, NULL, NULL + }, + { + {"transaction_read_only", PGC_USERSET, CLIENT_CONN_STATEMENT, + gettext_noop("Sets the current transaction's read-only status."), + NULL, + GUC_NO_RESET_ALL | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE + }, + &XactReadOnly, + false, + check_transaction_read_only, NULL, NULL + }, + { + {"default_transaction_deferrable", PGC_USERSET, CLIENT_CONN_STATEMENT, + gettext_noop("Sets the default deferrable status of new transactions."), + NULL + }, + &DefaultXactDeferrable, + false, + NULL, NULL, NULL + }, + { + {"transaction_deferrable", PGC_USERSET, CLIENT_CONN_STATEMENT, + gettext_noop("Whether to defer a read-only serializable transaction until it can be executed with no possible serialization failures."), + NULL, + GUC_NO_RESET_ALL | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE + }, + &XactDeferrable, + false, + check_transaction_deferrable, NULL, NULL + }, + { + {"row_security", PGC_USERSET, CLIENT_CONN_STATEMENT, + gettext_noop("Enable row security."), + gettext_noop("When enabled, row security will be applied to all users.") + }, + &row_security, + true, + NULL, NULL, NULL + }, + { + {"check_function_bodies", PGC_USERSET, CLIENT_CONN_STATEMENT, + gettext_noop("Check routine bodies during CREATE FUNCTION and CREATE PROCEDURE."), + NULL + }, + &check_function_bodies, + true, + NULL, NULL, NULL + }, + { + {"array_nulls", PGC_USERSET, COMPAT_OPTIONS_PREVIOUS, + gettext_noop("Enable input of NULL elements in arrays."), + gettext_noop("When turned on, unquoted NULL in an array input " + "value means a null value; " + "otherwise it is taken literally.") + }, + &Array_nulls, + true, + NULL, NULL, NULL + }, + + /* + * WITH OIDS support, and consequently default_with_oids, was removed in + * PostgreSQL 12, but we tolerate the parameter being set to false to + * avoid unnecessarily breaking older dump files. + */ + { + {"default_with_oids", PGC_USERSET, COMPAT_OPTIONS_PREVIOUS, + gettext_noop("WITH OIDS is no longer supported; this can only be false."), + NULL, + GUC_NO_SHOW_ALL | GUC_NOT_IN_SAMPLE + }, + &default_with_oids, + false, + check_default_with_oids, NULL, NULL + }, + { + {"logging_collector", PGC_POSTMASTER, LOGGING_WHERE, + gettext_noop("Start a subprocess to capture stderr output and/or csvlogs into log files."), + NULL + }, + &Logging_collector, + false, + NULL, NULL, NULL + }, + { + {"log_truncate_on_rotation", PGC_SIGHUP, LOGGING_WHERE, + gettext_noop("Truncate existing log files of same name during log rotation."), + NULL + }, + &Log_truncate_on_rotation, + false, + NULL, NULL, NULL + }, + +#ifdef TRACE_SORT + { + {"trace_sort", PGC_USERSET, DEVELOPER_OPTIONS, + gettext_noop("Emit information about resource usage in sorting."), + NULL, + GUC_NOT_IN_SAMPLE + }, + &trace_sort, + false, + NULL, NULL, NULL + }, +#endif + +#ifdef TRACE_SYNCSCAN + /* this is undocumented because not exposed in a standard build */ + { + {"trace_syncscan", PGC_USERSET, DEVELOPER_OPTIONS, + gettext_noop("Generate debugging output for synchronized scanning."), + NULL, + GUC_NOT_IN_SAMPLE + }, + &trace_syncscan, + false, + NULL, NULL, NULL + }, +#endif + +#ifdef DEBUG_BOUNDED_SORT + /* this is undocumented because not exposed in a standard build */ + { + { + "optimize_bounded_sort", PGC_USERSET, QUERY_TUNING_METHOD, + gettext_noop("Enable bounded sorting using heap sort."), + NULL, + GUC_NOT_IN_SAMPLE | GUC_EXPLAIN + }, + &optimize_bounded_sort, + true, + NULL, NULL, NULL + }, +#endif + +#ifdef WAL_DEBUG + { + {"wal_debug", PGC_SUSET, DEVELOPER_OPTIONS, + gettext_noop("Emit WAL-related debugging output."), + NULL, + GUC_NOT_IN_SAMPLE + }, + &XLOG_DEBUG, + false, + NULL, NULL, NULL + }, +#endif + + { + {"integer_datetimes", PGC_INTERNAL, PRESET_OPTIONS, + gettext_noop("Shows whether datetimes are integer based."), + NULL, + GUC_REPORT | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE + }, + &integer_datetimes, + true, + NULL, NULL, NULL + }, + + { + {"krb_caseins_users", PGC_SIGHUP, CONN_AUTH_AUTH, + gettext_noop("Sets whether Kerberos and GSSAPI user names should be treated as case-insensitive."), + NULL + }, + &pg_krb_caseins_users, + false, + NULL, NULL, NULL + }, + + { + {"escape_string_warning", PGC_USERSET, COMPAT_OPTIONS_PREVIOUS, + gettext_noop("Warn about backslash escapes in ordinary string literals."), + NULL + }, + &escape_string_warning, + true, + NULL, NULL, NULL + }, + + { + {"standard_conforming_strings", PGC_USERSET, COMPAT_OPTIONS_PREVIOUS, + gettext_noop("Causes '...' strings to treat backslashes literally."), + NULL, + GUC_REPORT + }, + &standard_conforming_strings, + true, + NULL, NULL, NULL + }, + + { + {"synchronize_seqscans", PGC_USERSET, COMPAT_OPTIONS_PREVIOUS, + gettext_noop("Enable synchronized sequential scans."), + NULL + }, + &synchronize_seqscans, + true, + NULL, NULL, NULL + }, + + { + {"recovery_target_inclusive", PGC_POSTMASTER, WAL_RECOVERY_TARGET, + gettext_noop("Sets whether to include or exclude transaction with recovery target."), + NULL + }, + &recoveryTargetInclusive, + true, + NULL, NULL, NULL + }, + + { + {"hot_standby", PGC_POSTMASTER, REPLICATION_STANDBY, + gettext_noop("Allows connections and queries during recovery."), + NULL + }, + &EnableHotStandby, + true, + NULL, NULL, NULL + }, + + { + {"hot_standby_feedback", PGC_SIGHUP, REPLICATION_STANDBY, + gettext_noop("Allows feedback from a hot standby to the primary that will avoid query conflicts."), + NULL + }, + &hot_standby_feedback, + false, + NULL, NULL, NULL + }, + + { + {"in_hot_standby", PGC_INTERNAL, PRESET_OPTIONS, + gettext_noop("Shows whether hot standby is currently active."), + NULL, + GUC_REPORT | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE + }, + &in_hot_standby_guc, + false, + NULL, NULL, show_in_hot_standby + }, + + { + {"allow_system_table_mods", PGC_SUSET, DEVELOPER_OPTIONS, + gettext_noop("Allows modifications of the structure of system tables."), + NULL, + GUC_NOT_IN_SAMPLE + }, + &allowSystemTableMods, + false, + NULL, NULL, NULL + }, + + { + {"ignore_system_indexes", PGC_BACKEND, DEVELOPER_OPTIONS, + gettext_noop("Disables reading from system indexes."), + gettext_noop("It does not prevent updating the indexes, so it is safe " + "to use. The worst consequence is slowness."), + GUC_NOT_IN_SAMPLE + }, + &IgnoreSystemIndexes, + false, + NULL, NULL, NULL + }, + + { + {"allow_in_place_tablespaces", PGC_SUSET, DEVELOPER_OPTIONS, + gettext_noop("Allows tablespaces directly inside pg_tblspc, for testing."), + NULL, + GUC_NOT_IN_SAMPLE + }, + &allow_in_place_tablespaces, + false, + NULL, NULL, NULL + }, + + { + {"lo_compat_privileges", PGC_SUSET, COMPAT_OPTIONS_PREVIOUS, + gettext_noop("Enables backward compatibility mode for privilege checks on large objects."), + gettext_noop("Skips privilege checks when reading or modifying large objects, " + "for compatibility with PostgreSQL releases prior to 9.0.") + }, + &lo_compat_privileges, + false, + NULL, NULL, NULL + }, + + { + {"quote_all_identifiers", PGC_USERSET, COMPAT_OPTIONS_PREVIOUS, + gettext_noop("When generating SQL fragments, quote all identifiers."), + NULL, + }, + "e_all_identifiers, + false, + NULL, NULL, NULL + }, + + { + {"data_checksums", PGC_INTERNAL, PRESET_OPTIONS, + gettext_noop("Shows whether data checksums are turned on for this cluster."), + NULL, + GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE | GUC_RUNTIME_COMPUTED + }, + &data_checksums, + false, + NULL, NULL, NULL + }, + + { + {"syslog_sequence_numbers", PGC_SIGHUP, LOGGING_WHERE, + gettext_noop("Add sequence number to syslog messages to avoid duplicate suppression."), + NULL + }, + &syslog_sequence_numbers, + true, + NULL, NULL, NULL + }, + + { + {"syslog_split_messages", PGC_SIGHUP, LOGGING_WHERE, + gettext_noop("Split messages sent to syslog by lines and to fit into 1024 bytes."), + NULL + }, + &syslog_split_messages, + true, + NULL, NULL, NULL + }, + + { + {"parallel_leader_participation", PGC_USERSET, RESOURCES_ASYNCHRONOUS, + gettext_noop("Controls whether Gather and Gather Merge also run subplans."), + gettext_noop("Should gather nodes also run subplans or just gather tuples?"), + GUC_EXPLAIN + }, + ¶llel_leader_participation, + true, + NULL, NULL, NULL + }, + + { + {"jit", PGC_USERSET, QUERY_TUNING_OTHER, + gettext_noop("Allow JIT compilation."), + NULL, + GUC_EXPLAIN + }, + &jit_enabled, + true, + NULL, NULL, NULL + }, + + { + {"jit_debugging_support", PGC_SU_BACKEND, DEVELOPER_OPTIONS, + gettext_noop("Register JIT-compiled functions with debugger."), + NULL, + GUC_NOT_IN_SAMPLE + }, + &jit_debugging_support, + false, + + /* + * This is not guaranteed to be available, but given it's a developer + * oriented option, it doesn't seem worth adding code checking + * availability. + */ + NULL, NULL, NULL + }, + + { + {"jit_dump_bitcode", PGC_SUSET, DEVELOPER_OPTIONS, + gettext_noop("Write out LLVM bitcode to facilitate JIT debugging."), + NULL, + GUC_NOT_IN_SAMPLE + }, + &jit_dump_bitcode, + false, + NULL, NULL, NULL + }, + + { + {"jit_expressions", PGC_USERSET, DEVELOPER_OPTIONS, + gettext_noop("Allow JIT compilation of expressions."), + NULL, + GUC_NOT_IN_SAMPLE + }, + &jit_expressions, + true, + NULL, NULL, NULL + }, + + { + {"jit_profiling_support", PGC_SU_BACKEND, DEVELOPER_OPTIONS, + gettext_noop("Register JIT-compiled functions with perf profiler."), + NULL, + GUC_NOT_IN_SAMPLE + }, + &jit_profiling_support, + false, + + /* + * This is not guaranteed to be available, but given it's a developer + * oriented option, it doesn't seem worth adding code checking + * availability. + */ + NULL, NULL, NULL + }, + + { + {"jit_tuple_deforming", PGC_USERSET, DEVELOPER_OPTIONS, + gettext_noop("Allow JIT compilation of tuple deforming."), + NULL, + GUC_NOT_IN_SAMPLE + }, + &jit_tuple_deforming, + true, + NULL, NULL, NULL + }, + + { + {"data_sync_retry", PGC_POSTMASTER, ERROR_HANDLING_OPTIONS, + gettext_noop("Whether to continue running after a failure to sync data files."), + }, + &data_sync_retry, + false, + NULL, NULL, NULL + }, + + { + {"wal_receiver_create_temp_slot", PGC_SIGHUP, REPLICATION_STANDBY, + gettext_noop("Sets whether a WAL receiver should create a temporary replication slot if no permanent slot is configured."), + }, + &wal_receiver_create_temp_slot, + false, + NULL, NULL, NULL + }, + + /* End-of-list marker */ + { + {NULL, 0, 0, NULL, NULL}, NULL, false, NULL, NULL, NULL + } +}; + + +struct config_int ConfigureNamesInt[] = +{ + { + {"archive_timeout", PGC_SIGHUP, WAL_ARCHIVING, + gettext_noop("Sets the amount of time to wait before forcing a " + "switch to the next WAL file."), + NULL, + GUC_UNIT_S + }, + &XLogArchiveTimeout, + 0, 0, INT_MAX / 2, + NULL, NULL, NULL + }, + { + {"post_auth_delay", PGC_BACKEND, DEVELOPER_OPTIONS, + gettext_noop("Sets the amount of time to wait after " + "authentication on connection startup."), + gettext_noop("This allows attaching a debugger to the process."), + GUC_NOT_IN_SAMPLE | GUC_UNIT_S + }, + &PostAuthDelay, + 0, 0, INT_MAX / 1000000, + NULL, NULL, NULL + }, + { + {"default_statistics_target", PGC_USERSET, QUERY_TUNING_OTHER, + gettext_noop("Sets the default statistics target."), + gettext_noop("This applies to table columns that have not had a " + "column-specific target set via ALTER TABLE SET STATISTICS.") + }, + &default_statistics_target, + 100, 1, 10000, + NULL, NULL, NULL + }, + { + {"from_collapse_limit", PGC_USERSET, QUERY_TUNING_OTHER, + gettext_noop("Sets the FROM-list size beyond which subqueries " + "are not collapsed."), + gettext_noop("The planner will merge subqueries into upper " + "queries if the resulting FROM list would have no more than " + "this many items."), + GUC_EXPLAIN + }, + &from_collapse_limit, + 8, 1, INT_MAX, + NULL, NULL, NULL + }, + { + {"join_collapse_limit", PGC_USERSET, QUERY_TUNING_OTHER, + gettext_noop("Sets the FROM-list size beyond which JOIN " + "constructs are not flattened."), + gettext_noop("The planner will flatten explicit JOIN " + "constructs into lists of FROM items whenever a " + "list of no more than this many items would result."), + GUC_EXPLAIN + }, + &join_collapse_limit, + 8, 1, INT_MAX, + NULL, NULL, NULL + }, + { + {"geqo_threshold", PGC_USERSET, QUERY_TUNING_GEQO, + gettext_noop("Sets the threshold of FROM items beyond which GEQO is used."), + NULL, + GUC_EXPLAIN + }, + &geqo_threshold, + 12, 2, INT_MAX, + NULL, NULL, NULL + }, + { + {"geqo_effort", PGC_USERSET, QUERY_TUNING_GEQO, + gettext_noop("GEQO: effort is used to set the default for other GEQO parameters."), + NULL, + GUC_EXPLAIN + }, + &Geqo_effort, + DEFAULT_GEQO_EFFORT, MIN_GEQO_EFFORT, MAX_GEQO_EFFORT, + NULL, NULL, NULL + }, + { + {"geqo_pool_size", PGC_USERSET, QUERY_TUNING_GEQO, + gettext_noop("GEQO: number of individuals in the population."), + gettext_noop("Zero selects a suitable default value."), + GUC_EXPLAIN + }, + &Geqo_pool_size, + 0, 0, INT_MAX, + NULL, NULL, NULL + }, + { + {"geqo_generations", PGC_USERSET, QUERY_TUNING_GEQO, + gettext_noop("GEQO: number of iterations of the algorithm."), + gettext_noop("Zero selects a suitable default value."), + GUC_EXPLAIN + }, + &Geqo_generations, + 0, 0, INT_MAX, + NULL, NULL, NULL + }, + + { + /* This is PGC_SUSET to prevent hiding from log_lock_waits. */ + {"deadlock_timeout", PGC_SUSET, LOCK_MANAGEMENT, + gettext_noop("Sets the time to wait on a lock before checking for deadlock."), + NULL, + GUC_UNIT_MS + }, + &DeadlockTimeout, + 1000, 1, INT_MAX, + NULL, NULL, NULL + }, + + { + {"max_standby_archive_delay", PGC_SIGHUP, REPLICATION_STANDBY, + gettext_noop("Sets the maximum delay before canceling queries when a hot standby server is processing archived WAL data."), + NULL, + GUC_UNIT_MS + }, + &max_standby_archive_delay, + 30 * 1000, -1, INT_MAX, + NULL, NULL, NULL + }, + + { + {"max_standby_streaming_delay", PGC_SIGHUP, REPLICATION_STANDBY, + gettext_noop("Sets the maximum delay before canceling queries when a hot standby server is processing streamed WAL data."), + NULL, + GUC_UNIT_MS + }, + &max_standby_streaming_delay, + 30 * 1000, -1, INT_MAX, + NULL, NULL, NULL + }, + + { + {"recovery_min_apply_delay", PGC_SIGHUP, REPLICATION_STANDBY, + gettext_noop("Sets the minimum delay for applying changes during recovery."), + NULL, + GUC_UNIT_MS + }, + &recovery_min_apply_delay, + 0, 0, INT_MAX, + NULL, NULL, NULL + }, + + { + {"wal_receiver_status_interval", PGC_SIGHUP, REPLICATION_STANDBY, + gettext_noop("Sets the maximum interval between WAL receiver status reports to the sending server."), + NULL, + GUC_UNIT_S + }, + &wal_receiver_status_interval, + 10, 0, INT_MAX / 1000, + NULL, NULL, NULL + }, + + { + {"wal_receiver_timeout", PGC_SIGHUP, REPLICATION_STANDBY, + gettext_noop("Sets the maximum wait time to receive data from the sending server."), + NULL, + GUC_UNIT_MS + }, + &wal_receiver_timeout, + 60 * 1000, 0, INT_MAX, + NULL, NULL, NULL + }, + + { + {"max_connections", PGC_POSTMASTER, CONN_AUTH_SETTINGS, + gettext_noop("Sets the maximum number of concurrent connections."), + NULL + }, + &MaxConnections, + 100, 1, MAX_BACKENDS, + check_max_connections, NULL, NULL + }, + + { + /* see max_connections */ + {"superuser_reserved_connections", PGC_POSTMASTER, CONN_AUTH_SETTINGS, + gettext_noop("Sets the number of connection slots reserved for superusers."), + NULL + }, + &ReservedBackends, + 3, 0, MAX_BACKENDS, + NULL, NULL, NULL + }, + + { + {"min_dynamic_shared_memory", PGC_POSTMASTER, RESOURCES_MEM, + gettext_noop("Amount of dynamic shared memory reserved at startup."), + NULL, + GUC_UNIT_MB + }, + &min_dynamic_shared_memory, + 0, 0, (int) Min((size_t) INT_MAX, SIZE_MAX / (1024 * 1024)), + NULL, NULL, NULL + }, + + /* + * We sometimes multiply the number of shared buffers by two without + * checking for overflow, so we mustn't allow more than INT_MAX / 2. + */ + { + {"shared_buffers", PGC_POSTMASTER, RESOURCES_MEM, + gettext_noop("Sets the number of shared memory buffers used by the server."), + NULL, + GUC_UNIT_BLOCKS + }, + &NBuffers, + 16384, 16, INT_MAX / 2, + NULL, NULL, NULL + }, + + { + {"shared_memory_size", PGC_INTERNAL, PRESET_OPTIONS, + gettext_noop("Shows the size of the server's main shared memory area (rounded up to the nearest MB)."), + NULL, + GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE | GUC_UNIT_MB | GUC_RUNTIME_COMPUTED + }, + &shared_memory_size_mb, + 0, 0, INT_MAX, + NULL, NULL, NULL + }, + + { + {"shared_memory_size_in_huge_pages", PGC_INTERNAL, PRESET_OPTIONS, + gettext_noop("Shows the number of huge pages needed for the main shared memory area."), + gettext_noop("-1 indicates that the value could not be determined."), + GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE | GUC_RUNTIME_COMPUTED + }, + &shared_memory_size_in_huge_pages, + -1, -1, INT_MAX, + NULL, NULL, NULL + }, + + { + {"temp_buffers", PGC_USERSET, RESOURCES_MEM, + gettext_noop("Sets the maximum number of temporary buffers used by each session."), + NULL, + GUC_UNIT_BLOCKS | GUC_EXPLAIN + }, + &num_temp_buffers, + 1024, 100, INT_MAX / 2, + check_temp_buffers, NULL, NULL + }, + + { + {"port", PGC_POSTMASTER, CONN_AUTH_SETTINGS, + gettext_noop("Sets the TCP port the server listens on."), + NULL + }, + &PostPortNumber, + DEF_PGPORT, 1, 65535, + NULL, NULL, NULL + }, + + { + {"unix_socket_permissions", PGC_POSTMASTER, CONN_AUTH_SETTINGS, + gettext_noop("Sets the access permissions of the Unix-domain socket."), + gettext_noop("Unix-domain sockets use the usual Unix file system " + "permission set. The parameter value is expected " + "to be a numeric mode specification in the form " + "accepted by the chmod and umask system calls. " + "(To use the customary octal format the number must " + "start with a 0 (zero).)") + }, + &Unix_socket_permissions, + 0777, 0000, 0777, + NULL, NULL, show_unix_socket_permissions + }, + + { + {"log_file_mode", PGC_SIGHUP, LOGGING_WHERE, + gettext_noop("Sets the file permissions for log files."), + gettext_noop("The parameter value is expected " + "to be a numeric mode specification in the form " + "accepted by the chmod and umask system calls. " + "(To use the customary octal format the number must " + "start with a 0 (zero).)") + }, + &Log_file_mode, + 0600, 0000, 0777, + NULL, NULL, show_log_file_mode + }, + + + { + {"data_directory_mode", PGC_INTERNAL, PRESET_OPTIONS, + gettext_noop("Shows the mode of the data directory."), + gettext_noop("The parameter value is a numeric mode specification " + "in the form accepted by the chmod and umask system " + "calls. (To use the customary octal format the number " + "must start with a 0 (zero).)"), + GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE | GUC_RUNTIME_COMPUTED + }, + &data_directory_mode, + 0700, 0000, 0777, + NULL, NULL, show_data_directory_mode + }, + + { + {"work_mem", PGC_USERSET, RESOURCES_MEM, + gettext_noop("Sets the maximum memory to be used for query workspaces."), + gettext_noop("This much memory can be used by each internal " + "sort operation and hash table before switching to " + "temporary disk files."), + GUC_UNIT_KB | GUC_EXPLAIN + }, + &work_mem, + 4096, 64, MAX_KILOBYTES, + NULL, NULL, NULL + }, + + { + {"maintenance_work_mem", PGC_USERSET, RESOURCES_MEM, + gettext_noop("Sets the maximum memory to be used for maintenance operations."), + gettext_noop("This includes operations such as VACUUM and CREATE INDEX."), + GUC_UNIT_KB + }, + &maintenance_work_mem, + 65536, 1024, MAX_KILOBYTES, + NULL, NULL, NULL + }, + + { + {"logical_decoding_work_mem", PGC_USERSET, RESOURCES_MEM, + gettext_noop("Sets the maximum memory to be used for logical decoding."), + gettext_noop("This much memory can be used by each internal " + "reorder buffer before spilling to disk."), + GUC_UNIT_KB + }, + &logical_decoding_work_mem, + 65536, 64, MAX_KILOBYTES, + NULL, NULL, NULL + }, + + /* + * We use the hopefully-safely-small value of 100kB as the compiled-in + * default for max_stack_depth. InitializeGUCOptions will increase it if + * possible, depending on the actual platform-specific stack limit. + */ + { + {"max_stack_depth", PGC_SUSET, RESOURCES_MEM, + gettext_noop("Sets the maximum stack depth, in kilobytes."), + NULL, + GUC_UNIT_KB + }, + &max_stack_depth, + 100, 100, MAX_KILOBYTES, + check_max_stack_depth, assign_max_stack_depth, NULL + }, + + { + {"temp_file_limit", PGC_SUSET, RESOURCES_DISK, + gettext_noop("Limits the total size of all temporary files used by each process."), + gettext_noop("-1 means no limit."), + GUC_UNIT_KB + }, + &temp_file_limit, + -1, -1, INT_MAX, + NULL, NULL, NULL + }, + + { + {"vacuum_cost_page_hit", PGC_USERSET, RESOURCES_VACUUM_DELAY, + gettext_noop("Vacuum cost for a page found in the buffer cache."), + NULL + }, + &VacuumCostPageHit, + 1, 0, 10000, + NULL, NULL, NULL + }, + + { + {"vacuum_cost_page_miss", PGC_USERSET, RESOURCES_VACUUM_DELAY, + gettext_noop("Vacuum cost for a page not found in the buffer cache."), + NULL + }, + &VacuumCostPageMiss, + 2, 0, 10000, + NULL, NULL, NULL + }, + + { + {"vacuum_cost_page_dirty", PGC_USERSET, RESOURCES_VACUUM_DELAY, + gettext_noop("Vacuum cost for a page dirtied by vacuum."), + NULL + }, + &VacuumCostPageDirty, + 20, 0, 10000, + NULL, NULL, NULL + }, + + { + {"vacuum_cost_limit", PGC_USERSET, RESOURCES_VACUUM_DELAY, + gettext_noop("Vacuum cost amount available before napping."), + NULL + }, + &VacuumCostLimit, + 200, 1, 10000, + NULL, NULL, NULL + }, + + { + {"autovacuum_vacuum_cost_limit", PGC_SIGHUP, AUTOVACUUM, + gettext_noop("Vacuum cost amount available before napping, for autovacuum."), + NULL + }, + &autovacuum_vac_cost_limit, + -1, -1, 10000, + NULL, NULL, NULL + }, + + { + {"max_files_per_process", PGC_POSTMASTER, RESOURCES_KERNEL, + gettext_noop("Sets the maximum number of simultaneously open files for each server process."), + NULL + }, + &max_files_per_process, + 1000, 64, INT_MAX, + NULL, NULL, NULL + }, + + /* + * See also CheckRequiredParameterValues() if this parameter changes + */ + { + {"max_prepared_transactions", PGC_POSTMASTER, RESOURCES_MEM, + gettext_noop("Sets the maximum number of simultaneously prepared transactions."), + NULL + }, + &max_prepared_xacts, + 0, 0, MAX_BACKENDS, + NULL, NULL, NULL + }, + +#ifdef LOCK_DEBUG + { + {"trace_lock_oidmin", PGC_SUSET, DEVELOPER_OPTIONS, + gettext_noop("Sets the minimum OID of tables for tracking locks."), + gettext_noop("Is used to avoid output on system tables."), + GUC_NOT_IN_SAMPLE + }, + &Trace_lock_oidmin, + FirstNormalObjectId, 0, INT_MAX, + NULL, NULL, NULL + }, + { + {"trace_lock_table", PGC_SUSET, DEVELOPER_OPTIONS, + gettext_noop("Sets the OID of the table with unconditionally lock tracing."), + NULL, + GUC_NOT_IN_SAMPLE + }, + &Trace_lock_table, + 0, 0, INT_MAX, + NULL, NULL, NULL + }, +#endif + + { + {"statement_timeout", PGC_USERSET, CLIENT_CONN_STATEMENT, + gettext_noop("Sets the maximum allowed duration of any statement."), + gettext_noop("A value of 0 turns off the timeout."), + GUC_UNIT_MS + }, + &StatementTimeout, + 0, 0, INT_MAX, + NULL, NULL, NULL + }, + + { + {"lock_timeout", PGC_USERSET, CLIENT_CONN_STATEMENT, + gettext_noop("Sets the maximum allowed duration of any wait for a lock."), + gettext_noop("A value of 0 turns off the timeout."), + GUC_UNIT_MS + }, + &LockTimeout, + 0, 0, INT_MAX, + NULL, NULL, NULL + }, + + { + {"idle_in_transaction_session_timeout", PGC_USERSET, CLIENT_CONN_STATEMENT, + gettext_noop("Sets the maximum allowed idle time between queries, when in a transaction."), + gettext_noop("A value of 0 turns off the timeout."), + GUC_UNIT_MS + }, + &IdleInTransactionSessionTimeout, + 0, 0, INT_MAX, + NULL, NULL, NULL + }, + + { + {"idle_session_timeout", PGC_USERSET, CLIENT_CONN_STATEMENT, + gettext_noop("Sets the maximum allowed idle time between queries, when not in a transaction."), + gettext_noop("A value of 0 turns off the timeout."), + GUC_UNIT_MS + }, + &IdleSessionTimeout, + 0, 0, INT_MAX, + NULL, NULL, NULL + }, + + { + {"vacuum_freeze_min_age", PGC_USERSET, CLIENT_CONN_STATEMENT, + gettext_noop("Minimum age at which VACUUM should freeze a table row."), + NULL + }, + &vacuum_freeze_min_age, + 50000000, 0, 1000000000, + NULL, NULL, NULL + }, + + { + {"vacuum_freeze_table_age", PGC_USERSET, CLIENT_CONN_STATEMENT, + gettext_noop("Age at which VACUUM should scan whole table to freeze tuples."), + NULL + }, + &vacuum_freeze_table_age, + 150000000, 0, 2000000000, + NULL, NULL, NULL + }, + + { + {"vacuum_multixact_freeze_min_age", PGC_USERSET, CLIENT_CONN_STATEMENT, + gettext_noop("Minimum age at which VACUUM should freeze a MultiXactId in a table row."), + NULL + }, + &vacuum_multixact_freeze_min_age, + 5000000, 0, 1000000000, + NULL, NULL, NULL + }, + + { + {"vacuum_multixact_freeze_table_age", PGC_USERSET, CLIENT_CONN_STATEMENT, + gettext_noop("Multixact age at which VACUUM should scan whole table to freeze tuples."), + NULL + }, + &vacuum_multixact_freeze_table_age, + 150000000, 0, 2000000000, + NULL, NULL, NULL + }, + + { + {"vacuum_defer_cleanup_age", PGC_SIGHUP, REPLICATION_PRIMARY, + gettext_noop("Number of transactions by which VACUUM and HOT cleanup should be deferred, if any."), + NULL + }, + &vacuum_defer_cleanup_age, + 0, 0, 1000000, /* see ComputeXidHorizons */ + NULL, NULL, NULL + }, + { + {"vacuum_failsafe_age", PGC_USERSET, CLIENT_CONN_STATEMENT, + gettext_noop("Age at which VACUUM should trigger failsafe to avoid a wraparound outage."), + NULL + }, + &vacuum_failsafe_age, + 1600000000, 0, 2100000000, + NULL, NULL, NULL + }, + { + {"vacuum_multixact_failsafe_age", PGC_USERSET, CLIENT_CONN_STATEMENT, + gettext_noop("Multixact age at which VACUUM should trigger failsafe to avoid a wraparound outage."), + NULL + }, + &vacuum_multixact_failsafe_age, + 1600000000, 0, 2100000000, + NULL, NULL, NULL + }, + + /* + * See also CheckRequiredParameterValues() if this parameter changes + */ + { + {"max_locks_per_transaction", PGC_POSTMASTER, LOCK_MANAGEMENT, + gettext_noop("Sets the maximum number of locks per transaction."), + gettext_noop("The shared lock table is sized on the assumption that " + "at most max_locks_per_transaction * max_connections distinct " + "objects will need to be locked at any one time.") + }, + &max_locks_per_xact, + 64, 10, INT_MAX, + NULL, NULL, NULL + }, + + { + {"max_pred_locks_per_transaction", PGC_POSTMASTER, LOCK_MANAGEMENT, + gettext_noop("Sets the maximum number of predicate locks per transaction."), + gettext_noop("The shared predicate lock table is sized on the assumption that " + "at most max_pred_locks_per_transaction * max_connections distinct " + "objects will need to be locked at any one time.") + }, + &max_predicate_locks_per_xact, + 64, 10, INT_MAX, + NULL, NULL, NULL + }, + + { + {"max_pred_locks_per_relation", PGC_SIGHUP, LOCK_MANAGEMENT, + gettext_noop("Sets the maximum number of predicate-locked pages and tuples per relation."), + gettext_noop("If more than this total of pages and tuples in the same relation are locked " + "by a connection, those locks are replaced by a relation-level lock.") + }, + &max_predicate_locks_per_relation, + -2, INT_MIN, INT_MAX, + NULL, NULL, NULL + }, + + { + {"max_pred_locks_per_page", PGC_SIGHUP, LOCK_MANAGEMENT, + gettext_noop("Sets the maximum number of predicate-locked tuples per page."), + gettext_noop("If more than this number of tuples on the same page are locked " + "by a connection, those locks are replaced by a page-level lock.") + }, + &max_predicate_locks_per_page, + 2, 0, INT_MAX, + NULL, NULL, NULL + }, + + { + {"authentication_timeout", PGC_SIGHUP, CONN_AUTH_AUTH, + gettext_noop("Sets the maximum allowed time to complete client authentication."), + NULL, + GUC_UNIT_S + }, + &AuthenticationTimeout, + 60, 1, 600, + NULL, NULL, NULL + }, + + { + /* Not for general use */ + {"pre_auth_delay", PGC_SIGHUP, DEVELOPER_OPTIONS, + gettext_noop("Sets the amount of time to wait before " + "authentication on connection startup."), + gettext_noop("This allows attaching a debugger to the process."), + GUC_NOT_IN_SAMPLE | GUC_UNIT_S + }, + &PreAuthDelay, + 0, 0, 60, + NULL, NULL, NULL + }, + + { + {"wal_decode_buffer_size", PGC_POSTMASTER, WAL_RECOVERY, + gettext_noop("Buffer size for reading ahead in the WAL during recovery."), + gettext_noop("This controls the maximum distance we can read ahead in the WAL to prefetch referenced data blocks."), + GUC_UNIT_BYTE + }, + &wal_decode_buffer_size, + 512 * 1024, 64 * 1024, MaxAllocSize, + NULL, NULL, NULL + }, + + { + {"wal_keep_size", PGC_SIGHUP, REPLICATION_SENDING, + gettext_noop("Sets the size of WAL files held for standby servers."), + NULL, + GUC_UNIT_MB + }, + &wal_keep_size_mb, + 0, 0, MAX_KILOBYTES, + NULL, NULL, NULL + }, + + { + {"min_wal_size", PGC_SIGHUP, WAL_CHECKPOINTS, + gettext_noop("Sets the minimum size to shrink the WAL to."), + NULL, + GUC_UNIT_MB + }, + &min_wal_size_mb, + DEFAULT_MIN_WAL_SEGS * (DEFAULT_XLOG_SEG_SIZE / (1024 * 1024)), + 2, MAX_KILOBYTES, + NULL, NULL, NULL + }, + + { + {"max_wal_size", PGC_SIGHUP, WAL_CHECKPOINTS, + gettext_noop("Sets the WAL size that triggers a checkpoint."), + NULL, + GUC_UNIT_MB + }, + &max_wal_size_mb, + DEFAULT_MAX_WAL_SEGS * (DEFAULT_XLOG_SEG_SIZE / (1024 * 1024)), + 2, MAX_KILOBYTES, + NULL, assign_max_wal_size, NULL + }, + + { + {"checkpoint_timeout", PGC_SIGHUP, WAL_CHECKPOINTS, + gettext_noop("Sets the maximum time between automatic WAL checkpoints."), + NULL, + GUC_UNIT_S + }, + &CheckPointTimeout, + 300, 30, 86400, + NULL, NULL, NULL + }, + + { + {"checkpoint_warning", PGC_SIGHUP, WAL_CHECKPOINTS, + gettext_noop("Sets the maximum time before warning if checkpoints " + "triggered by WAL volume happen too frequently."), + gettext_noop("Write a message to the server log if checkpoints " + "caused by the filling of WAL segment files happen more " + "frequently than this amount of time. " + "Zero turns off the warning."), + GUC_UNIT_S + }, + &CheckPointWarning, + 30, 0, INT_MAX, + NULL, NULL, NULL + }, + + { + {"checkpoint_flush_after", PGC_SIGHUP, WAL_CHECKPOINTS, + gettext_noop("Number of pages after which previously performed writes are flushed to disk."), + NULL, + GUC_UNIT_BLOCKS + }, + &checkpoint_flush_after, + DEFAULT_CHECKPOINT_FLUSH_AFTER, 0, WRITEBACK_MAX_PENDING_FLUSHES, + NULL, NULL, NULL + }, + + { + {"wal_buffers", PGC_POSTMASTER, WAL_SETTINGS, + gettext_noop("Sets the number of disk-page buffers in shared memory for WAL."), + NULL, + GUC_UNIT_XBLOCKS + }, + &XLOGbuffers, + -1, -1, (INT_MAX / XLOG_BLCKSZ), + check_wal_buffers, NULL, NULL + }, + + { + {"wal_writer_delay", PGC_SIGHUP, WAL_SETTINGS, + gettext_noop("Time between WAL flushes performed in the WAL writer."), + NULL, + GUC_UNIT_MS + }, + &WalWriterDelay, + 200, 1, 10000, + NULL, NULL, NULL + }, + + { + {"wal_writer_flush_after", PGC_SIGHUP, WAL_SETTINGS, + gettext_noop("Amount of WAL written out by WAL writer that triggers a flush."), + NULL, + GUC_UNIT_XBLOCKS + }, + &WalWriterFlushAfter, + (1024 * 1024) / XLOG_BLCKSZ, 0, INT_MAX, + NULL, NULL, NULL + }, + + { + {"wal_skip_threshold", PGC_USERSET, WAL_SETTINGS, + gettext_noop("Minimum size of new file to fsync instead of writing WAL."), + NULL, + GUC_UNIT_KB + }, + &wal_skip_threshold, + 2048, 0, MAX_KILOBYTES, + NULL, NULL, NULL + }, + + { + {"max_wal_senders", PGC_POSTMASTER, REPLICATION_SENDING, + gettext_noop("Sets the maximum number of simultaneously running WAL sender processes."), + NULL + }, + &max_wal_senders, + 10, 0, MAX_BACKENDS, + check_max_wal_senders, NULL, NULL + }, + + { + /* see max_wal_senders */ + {"max_replication_slots", PGC_POSTMASTER, REPLICATION_SENDING, + gettext_noop("Sets the maximum number of simultaneously defined replication slots."), + NULL + }, + &max_replication_slots, + 10, 0, MAX_BACKENDS /* XXX? */ , + NULL, NULL, NULL + }, + + { + {"max_slot_wal_keep_size", PGC_SIGHUP, REPLICATION_SENDING, + gettext_noop("Sets the maximum WAL size that can be reserved by replication slots."), + gettext_noop("Replication slots will be marked as failed, and segments released " + "for deletion or recycling, if this much space is occupied by WAL " + "on disk."), + GUC_UNIT_MB + }, + &max_slot_wal_keep_size_mb, + -1, -1, MAX_KILOBYTES, + NULL, NULL, NULL + }, + + { + {"wal_sender_timeout", PGC_USERSET, REPLICATION_SENDING, + gettext_noop("Sets the maximum time to wait for WAL replication."), + NULL, + GUC_UNIT_MS + }, + &wal_sender_timeout, + 60 * 1000, 0, INT_MAX, + NULL, NULL, NULL + }, + + { + {"commit_delay", PGC_SUSET, WAL_SETTINGS, + gettext_noop("Sets the delay in microseconds between transaction commit and " + "flushing WAL to disk."), + NULL + /* we have no microseconds designation, so can't supply units here */ + }, + &CommitDelay, + 0, 0, 100000, + NULL, NULL, NULL + }, + + { + {"commit_siblings", PGC_USERSET, WAL_SETTINGS, + gettext_noop("Sets the minimum number of concurrent open transactions " + "required before performing commit_delay."), + NULL + }, + &CommitSiblings, + 5, 0, 1000, + NULL, NULL, NULL + }, + + { + {"extra_float_digits", PGC_USERSET, CLIENT_CONN_LOCALE, + gettext_noop("Sets the number of digits displayed for floating-point values."), + gettext_noop("This affects real, double precision, and geometric data types. " + "A zero or negative parameter value is added to the standard " + "number of digits (FLT_DIG or DBL_DIG as appropriate). " + "Any value greater than zero selects precise output mode.") + }, + &extra_float_digits, + 1, -15, 3, + NULL, NULL, NULL + }, + + { + {"log_min_duration_sample", PGC_SUSET, LOGGING_WHEN, + gettext_noop("Sets the minimum execution time above which " + "a sample of statements will be logged." + " Sampling is determined by log_statement_sample_rate."), + gettext_noop("Zero logs a sample of all queries. -1 turns this feature off."), + GUC_UNIT_MS + }, + &log_min_duration_sample, + -1, -1, INT_MAX, + NULL, NULL, NULL + }, + + { + {"log_min_duration_statement", PGC_SUSET, LOGGING_WHEN, + gettext_noop("Sets the minimum execution time above which " + "all statements will be logged."), + gettext_noop("Zero prints all queries. -1 turns this feature off."), + GUC_UNIT_MS + }, + &log_min_duration_statement, + -1, -1, INT_MAX, + NULL, NULL, NULL + }, + + { + {"log_autovacuum_min_duration", PGC_SIGHUP, LOGGING_WHAT, + gettext_noop("Sets the minimum execution time above which " + "autovacuum actions will be logged."), + gettext_noop("Zero prints all actions. -1 turns autovacuum logging off."), + GUC_UNIT_MS + }, + &Log_autovacuum_min_duration, + 600000, -1, INT_MAX, + NULL, NULL, NULL + }, + + { + {"log_parameter_max_length", PGC_SUSET, LOGGING_WHAT, + gettext_noop("Sets the maximum length in bytes of data logged for bind " + "parameter values when logging statements."), + gettext_noop("-1 to print values in full."), + GUC_UNIT_BYTE + }, + &log_parameter_max_length, + -1, -1, INT_MAX / 2, + NULL, NULL, NULL + }, + + { + {"log_parameter_max_length_on_error", PGC_USERSET, LOGGING_WHAT, + gettext_noop("Sets the maximum length in bytes of data logged for bind " + "parameter values when logging statements, on error."), + gettext_noop("-1 to print values in full."), + GUC_UNIT_BYTE + }, + &log_parameter_max_length_on_error, + 0, -1, INT_MAX / 2, + NULL, NULL, NULL + }, + + { + {"bgwriter_delay", PGC_SIGHUP, RESOURCES_BGWRITER, + gettext_noop("Background writer sleep time between rounds."), + NULL, + GUC_UNIT_MS + }, + &BgWriterDelay, + 200, 10, 10000, + NULL, NULL, NULL + }, + + { + {"bgwriter_lru_maxpages", PGC_SIGHUP, RESOURCES_BGWRITER, + gettext_noop("Background writer maximum number of LRU pages to flush per round."), + NULL + }, + &bgwriter_lru_maxpages, + 100, 0, INT_MAX / 2, /* Same upper limit as shared_buffers */ + NULL, NULL, NULL + }, + + { + {"bgwriter_flush_after", PGC_SIGHUP, RESOURCES_BGWRITER, + gettext_noop("Number of pages after which previously performed writes are flushed to disk."), + NULL, + GUC_UNIT_BLOCKS + }, + &bgwriter_flush_after, + DEFAULT_BGWRITER_FLUSH_AFTER, 0, WRITEBACK_MAX_PENDING_FLUSHES, + NULL, NULL, NULL + }, + + { + {"effective_io_concurrency", + PGC_USERSET, + RESOURCES_ASYNCHRONOUS, + gettext_noop("Number of simultaneous requests that can be handled efficiently by the disk subsystem."), + NULL, + GUC_EXPLAIN + }, + &effective_io_concurrency, +#ifdef USE_PREFETCH + 1, +#else + 0, +#endif + 0, MAX_IO_CONCURRENCY, + check_effective_io_concurrency, NULL, NULL + }, + + { + {"maintenance_io_concurrency", + PGC_USERSET, + RESOURCES_ASYNCHRONOUS, + gettext_noop("A variant of effective_io_concurrency that is used for maintenance work."), + NULL, + GUC_EXPLAIN + }, + &maintenance_io_concurrency, +#ifdef USE_PREFETCH + 10, +#else + 0, +#endif + 0, MAX_IO_CONCURRENCY, + check_maintenance_io_concurrency, assign_maintenance_io_concurrency, + NULL + }, + + { + {"backend_flush_after", PGC_USERSET, RESOURCES_ASYNCHRONOUS, + gettext_noop("Number of pages after which previously performed writes are flushed to disk."), + NULL, + GUC_UNIT_BLOCKS + }, + &backend_flush_after, + DEFAULT_BACKEND_FLUSH_AFTER, 0, WRITEBACK_MAX_PENDING_FLUSHES, + NULL, NULL, NULL + }, + + { + {"max_worker_processes", + PGC_POSTMASTER, + RESOURCES_ASYNCHRONOUS, + gettext_noop("Maximum number of concurrent worker processes."), + NULL, + }, + &max_worker_processes, + 8, 0, MAX_BACKENDS, + check_max_worker_processes, NULL, NULL + }, + + { + {"max_logical_replication_workers", + PGC_POSTMASTER, + REPLICATION_SUBSCRIBERS, + gettext_noop("Maximum number of logical replication worker processes."), + NULL, + }, + &max_logical_replication_workers, + 4, 0, MAX_BACKENDS, + NULL, NULL, NULL + }, + + { + {"max_sync_workers_per_subscription", + PGC_SIGHUP, + REPLICATION_SUBSCRIBERS, + gettext_noop("Maximum number of table synchronization workers per subscription."), + NULL, + }, + &max_sync_workers_per_subscription, + 2, 0, MAX_BACKENDS, + NULL, NULL, NULL + }, + + { + {"log_rotation_age", PGC_SIGHUP, LOGGING_WHERE, + gettext_noop("Sets the amount of time to wait before forcing " + "log file rotation."), + NULL, + GUC_UNIT_MIN + }, + &Log_RotationAge, + HOURS_PER_DAY * MINS_PER_HOUR, 0, INT_MAX / SECS_PER_MINUTE, + NULL, NULL, NULL + }, + + { + {"log_rotation_size", PGC_SIGHUP, LOGGING_WHERE, + gettext_noop("Sets the maximum size a log file can reach before " + "being rotated."), + NULL, + GUC_UNIT_KB + }, + &Log_RotationSize, + 10 * 1024, 0, INT_MAX / 1024, + NULL, NULL, NULL + }, + + { + {"max_function_args", PGC_INTERNAL, PRESET_OPTIONS, + gettext_noop("Shows the maximum number of function arguments."), + NULL, + GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE + }, + &max_function_args, + FUNC_MAX_ARGS, FUNC_MAX_ARGS, FUNC_MAX_ARGS, + NULL, NULL, NULL + }, + + { + {"max_index_keys", PGC_INTERNAL, PRESET_OPTIONS, + gettext_noop("Shows the maximum number of index keys."), + NULL, + GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE + }, + &max_index_keys, + INDEX_MAX_KEYS, INDEX_MAX_KEYS, INDEX_MAX_KEYS, + NULL, NULL, NULL + }, + + { + {"max_identifier_length", PGC_INTERNAL, PRESET_OPTIONS, + gettext_noop("Shows the maximum identifier length."), + NULL, + GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE + }, + &max_identifier_length, + NAMEDATALEN - 1, NAMEDATALEN - 1, NAMEDATALEN - 1, + NULL, NULL, NULL + }, + + { + {"block_size", PGC_INTERNAL, PRESET_OPTIONS, + gettext_noop("Shows the size of a disk block."), + NULL, + GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE + }, + &block_size, + BLCKSZ, BLCKSZ, BLCKSZ, + NULL, NULL, NULL + }, + + { + {"segment_size", PGC_INTERNAL, PRESET_OPTIONS, + gettext_noop("Shows the number of pages per disk file."), + NULL, + GUC_UNIT_BLOCKS | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE + }, + &segment_size, + RELSEG_SIZE, RELSEG_SIZE, RELSEG_SIZE, + NULL, NULL, NULL + }, + + { + {"wal_block_size", PGC_INTERNAL, PRESET_OPTIONS, + gettext_noop("Shows the block size in the write ahead log."), + NULL, + GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE + }, + &wal_block_size, + XLOG_BLCKSZ, XLOG_BLCKSZ, XLOG_BLCKSZ, + NULL, NULL, NULL + }, + + { + {"wal_retrieve_retry_interval", PGC_SIGHUP, REPLICATION_STANDBY, + gettext_noop("Sets the time to wait before retrying to retrieve WAL " + "after a failed attempt."), + NULL, + GUC_UNIT_MS + }, + &wal_retrieve_retry_interval, + 5000, 1, INT_MAX, + NULL, NULL, NULL + }, + + { + {"wal_segment_size", PGC_INTERNAL, PRESET_OPTIONS, + gettext_noop("Shows the size of write ahead log segments."), + NULL, + GUC_UNIT_BYTE | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE | GUC_RUNTIME_COMPUTED + }, + &wal_segment_size, + DEFAULT_XLOG_SEG_SIZE, + WalSegMinSize, + WalSegMaxSize, + NULL, NULL, NULL + }, + + { + {"autovacuum_naptime", PGC_SIGHUP, AUTOVACUUM, + gettext_noop("Time to sleep between autovacuum runs."), + NULL, + GUC_UNIT_S + }, + &autovacuum_naptime, + 60, 1, INT_MAX / 1000, + NULL, NULL, NULL + }, + { + {"autovacuum_vacuum_threshold", PGC_SIGHUP, AUTOVACUUM, + gettext_noop("Minimum number of tuple updates or deletes prior to vacuum."), + NULL + }, + &autovacuum_vac_thresh, + 50, 0, INT_MAX, + NULL, NULL, NULL + }, + { + {"autovacuum_vacuum_insert_threshold", PGC_SIGHUP, AUTOVACUUM, + gettext_noop("Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums."), + NULL + }, + &autovacuum_vac_ins_thresh, + 1000, -1, INT_MAX, + NULL, NULL, NULL + }, + { + {"autovacuum_analyze_threshold", PGC_SIGHUP, AUTOVACUUM, + gettext_noop("Minimum number of tuple inserts, updates, or deletes prior to analyze."), + NULL + }, + &autovacuum_anl_thresh, + 50, 0, INT_MAX, + NULL, NULL, NULL + }, + { + /* see varsup.c for why this is PGC_POSTMASTER not PGC_SIGHUP */ + {"autovacuum_freeze_max_age", PGC_POSTMASTER, AUTOVACUUM, + gettext_noop("Age at which to autovacuum a table to prevent transaction ID wraparound."), + NULL + }, + &autovacuum_freeze_max_age, + + /* see vacuum_failsafe_age if you change the upper-limit value. */ + 200000000, 100000, 2000000000, + NULL, NULL, NULL + }, + { + /* see multixact.c for why this is PGC_POSTMASTER not PGC_SIGHUP */ + {"autovacuum_multixact_freeze_max_age", PGC_POSTMASTER, AUTOVACUUM, + gettext_noop("Multixact age at which to autovacuum a table to prevent multixact wraparound."), + NULL + }, + &autovacuum_multixact_freeze_max_age, + 400000000, 10000, 2000000000, + NULL, NULL, NULL + }, + { + /* see max_connections */ + {"autovacuum_max_workers", PGC_POSTMASTER, AUTOVACUUM, + gettext_noop("Sets the maximum number of simultaneously running autovacuum worker processes."), + NULL + }, + &autovacuum_max_workers, + 3, 1, MAX_BACKENDS, + check_autovacuum_max_workers, NULL, NULL + }, + + { + {"max_parallel_maintenance_workers", PGC_USERSET, RESOURCES_ASYNCHRONOUS, + gettext_noop("Sets the maximum number of parallel processes per maintenance operation."), + NULL + }, + &max_parallel_maintenance_workers, + 2, 0, 1024, + NULL, NULL, NULL + }, + + { + {"max_parallel_workers_per_gather", PGC_USERSET, RESOURCES_ASYNCHRONOUS, + gettext_noop("Sets the maximum number of parallel processes per executor node."), + NULL, + GUC_EXPLAIN + }, + &max_parallel_workers_per_gather, + 2, 0, MAX_PARALLEL_WORKER_LIMIT, + NULL, NULL, NULL + }, + + { + {"max_parallel_workers", PGC_USERSET, RESOURCES_ASYNCHRONOUS, + gettext_noop("Sets the maximum number of parallel workers that can be active at one time."), + NULL, + GUC_EXPLAIN + }, + &max_parallel_workers, + 8, 0, MAX_PARALLEL_WORKER_LIMIT, + NULL, NULL, NULL + }, + + { + {"autovacuum_work_mem", PGC_SIGHUP, RESOURCES_MEM, + gettext_noop("Sets the maximum memory to be used by each autovacuum worker process."), + NULL, + GUC_UNIT_KB + }, + &autovacuum_work_mem, + -1, -1, MAX_KILOBYTES, + check_autovacuum_work_mem, NULL, NULL + }, + + { + {"old_snapshot_threshold", PGC_POSTMASTER, RESOURCES_ASYNCHRONOUS, + gettext_noop("Time before a snapshot is too old to read pages changed after the snapshot was taken."), + gettext_noop("A value of -1 disables this feature."), + GUC_UNIT_MIN + }, + &old_snapshot_threshold, + -1, -1, MINS_PER_HOUR * HOURS_PER_DAY * 60, + NULL, NULL, NULL + }, + + { + {"tcp_keepalives_idle", PGC_USERSET, CONN_AUTH_TCP, + gettext_noop("Time between issuing TCP keepalives."), + gettext_noop("A value of 0 uses the system default."), + GUC_UNIT_S + }, + &tcp_keepalives_idle, + 0, 0, INT_MAX, + NULL, assign_tcp_keepalives_idle, show_tcp_keepalives_idle + }, + + { + {"tcp_keepalives_interval", PGC_USERSET, CONN_AUTH_TCP, + gettext_noop("Time between TCP keepalive retransmits."), + gettext_noop("A value of 0 uses the system default."), + GUC_UNIT_S + }, + &tcp_keepalives_interval, + 0, 0, INT_MAX, + NULL, assign_tcp_keepalives_interval, show_tcp_keepalives_interval + }, + + { + {"ssl_renegotiation_limit", PGC_USERSET, COMPAT_OPTIONS_PREVIOUS, + gettext_noop("SSL renegotiation is no longer supported; this can only be 0."), + NULL, + GUC_NO_SHOW_ALL | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE, + }, + &ssl_renegotiation_limit, + 0, 0, 0, + NULL, NULL, NULL + }, + + { + {"tcp_keepalives_count", PGC_USERSET, CONN_AUTH_TCP, + gettext_noop("Maximum number of TCP keepalive retransmits."), + gettext_noop("This controls the number of consecutive keepalive retransmits that can be " + "lost before a connection is considered dead. A value of 0 uses the " + "system default."), + }, + &tcp_keepalives_count, + 0, 0, INT_MAX, + NULL, assign_tcp_keepalives_count, show_tcp_keepalives_count + }, + + { + {"gin_fuzzy_search_limit", PGC_USERSET, CLIENT_CONN_OTHER, + gettext_noop("Sets the maximum allowed result for exact search by GIN."), + NULL, + 0 + }, + &GinFuzzySearchLimit, + 0, 0, INT_MAX, + NULL, NULL, NULL + }, + + { + {"effective_cache_size", PGC_USERSET, QUERY_TUNING_COST, + gettext_noop("Sets the planner's assumption about the total size of the data caches."), + gettext_noop("That is, the total size of the caches (kernel cache and shared buffers) used for PostgreSQL data files. " + "This is measured in disk pages, which are normally 8 kB each."), + GUC_UNIT_BLOCKS | GUC_EXPLAIN, + }, + &effective_cache_size, + DEFAULT_EFFECTIVE_CACHE_SIZE, 1, INT_MAX, + NULL, NULL, NULL + }, + + { + {"min_parallel_table_scan_size", PGC_USERSET, QUERY_TUNING_COST, + gettext_noop("Sets the minimum amount of table data for a parallel scan."), + gettext_noop("If the planner estimates that it will read a number of table pages too small to reach this limit, a parallel scan will not be considered."), + GUC_UNIT_BLOCKS | GUC_EXPLAIN, + }, + &min_parallel_table_scan_size, + (8 * 1024 * 1024) / BLCKSZ, 0, INT_MAX / 3, + NULL, NULL, NULL + }, + + { + {"min_parallel_index_scan_size", PGC_USERSET, QUERY_TUNING_COST, + gettext_noop("Sets the minimum amount of index data for a parallel scan."), + gettext_noop("If the planner estimates that it will read a number of index pages too small to reach this limit, a parallel scan will not be considered."), + GUC_UNIT_BLOCKS | GUC_EXPLAIN, + }, + &min_parallel_index_scan_size, + (512 * 1024) / BLCKSZ, 0, INT_MAX / 3, + NULL, NULL, NULL + }, + + { + /* Can't be set in postgresql.conf */ + {"server_version_num", PGC_INTERNAL, PRESET_OPTIONS, + gettext_noop("Shows the server version as an integer."), + NULL, + GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE + }, + &server_version_num, + PG_VERSION_NUM, PG_VERSION_NUM, PG_VERSION_NUM, + NULL, NULL, NULL + }, + + { + {"log_temp_files", PGC_SUSET, LOGGING_WHAT, + gettext_noop("Log the use of temporary files larger than this number of kilobytes."), + gettext_noop("Zero logs all files. The default is -1 (turning this feature off)."), + GUC_UNIT_KB + }, + &log_temp_files, + -1, -1, INT_MAX, + NULL, NULL, NULL + }, + + { + {"track_activity_query_size", PGC_POSTMASTER, STATS_CUMULATIVE, + gettext_noop("Sets the size reserved for pg_stat_activity.query, in bytes."), + NULL, + GUC_UNIT_BYTE + }, + &pgstat_track_activity_query_size, + 1024, 100, 1048576, + NULL, NULL, NULL + }, + + { + {"gin_pending_list_limit", PGC_USERSET, CLIENT_CONN_STATEMENT, + gettext_noop("Sets the maximum size of the pending list for GIN index."), + NULL, + GUC_UNIT_KB + }, + &gin_pending_list_limit, + 4096, 64, MAX_KILOBYTES, + NULL, NULL, NULL + }, + + { + {"tcp_user_timeout", PGC_USERSET, CONN_AUTH_TCP, + gettext_noop("TCP user timeout."), + gettext_noop("A value of 0 uses the system default."), + GUC_UNIT_MS + }, + &tcp_user_timeout, + 0, 0, INT_MAX, + NULL, assign_tcp_user_timeout, show_tcp_user_timeout + }, + + { + {"huge_page_size", PGC_POSTMASTER, RESOURCES_MEM, + gettext_noop("The size of huge page that should be requested."), + NULL, + GUC_UNIT_KB + }, + &huge_page_size, + 0, 0, INT_MAX, + check_huge_page_size, NULL, NULL + }, + + { + {"debug_discard_caches", PGC_SUSET, DEVELOPER_OPTIONS, + gettext_noop("Aggressively flush system caches for debugging purposes."), + NULL, + GUC_NOT_IN_SAMPLE + }, + &debug_discard_caches, +#ifdef DISCARD_CACHES_ENABLED + /* Set default based on older compile-time-only cache clobber macros */ +#if defined(CLOBBER_CACHE_RECURSIVELY) + 3, +#elif defined(CLOBBER_CACHE_ALWAYS) + 1, +#else + 0, +#endif + 0, 5, +#else /* not DISCARD_CACHES_ENABLED */ + 0, 0, 0, +#endif /* not DISCARD_CACHES_ENABLED */ + NULL, NULL, NULL + }, + + { + {"client_connection_check_interval", PGC_USERSET, CONN_AUTH_TCP, + gettext_noop("Sets the time interval between checks for disconnection while running queries."), + NULL, + GUC_UNIT_MS + }, + &client_connection_check_interval, + 0, 0, INT_MAX, + check_client_connection_check_interval, NULL, NULL + }, + + { + {"log_startup_progress_interval", PGC_SIGHUP, LOGGING_WHEN, + gettext_noop("Time between progress updates for " + "long-running startup operations."), + gettext_noop("0 turns this feature off."), + GUC_UNIT_MS, + }, + &log_startup_progress_interval, + 10000, 0, INT_MAX, + NULL, NULL, NULL + }, + + /* End-of-list marker */ + { + {NULL, 0, 0, NULL, NULL}, NULL, 0, 0, 0, NULL, NULL, NULL + } +}; + + +struct config_real ConfigureNamesReal[] = +{ + { + {"seq_page_cost", PGC_USERSET, QUERY_TUNING_COST, + gettext_noop("Sets the planner's estimate of the cost of a " + "sequentially fetched disk page."), + NULL, + GUC_EXPLAIN + }, + &seq_page_cost, + DEFAULT_SEQ_PAGE_COST, 0, DBL_MAX, + NULL, NULL, NULL + }, + { + {"random_page_cost", PGC_USERSET, QUERY_TUNING_COST, + gettext_noop("Sets the planner's estimate of the cost of a " + "nonsequentially fetched disk page."), + NULL, + GUC_EXPLAIN + }, + &random_page_cost, + DEFAULT_RANDOM_PAGE_COST, 0, DBL_MAX, + NULL, NULL, NULL + }, + { + {"cpu_tuple_cost", PGC_USERSET, QUERY_TUNING_COST, + gettext_noop("Sets the planner's estimate of the cost of " + "processing each tuple (row)."), + NULL, + GUC_EXPLAIN + }, + &cpu_tuple_cost, + DEFAULT_CPU_TUPLE_COST, 0, DBL_MAX, + NULL, NULL, NULL + }, + { + {"cpu_index_tuple_cost", PGC_USERSET, QUERY_TUNING_COST, + gettext_noop("Sets the planner's estimate of the cost of " + "processing each index entry during an index scan."), + NULL, + GUC_EXPLAIN + }, + &cpu_index_tuple_cost, + DEFAULT_CPU_INDEX_TUPLE_COST, 0, DBL_MAX, + NULL, NULL, NULL + }, + { + {"cpu_operator_cost", PGC_USERSET, QUERY_TUNING_COST, + gettext_noop("Sets the planner's estimate of the cost of " + "processing each operator or function call."), + NULL, + GUC_EXPLAIN + }, + &cpu_operator_cost, + DEFAULT_CPU_OPERATOR_COST, 0, DBL_MAX, + NULL, NULL, NULL + }, + { + {"parallel_tuple_cost", PGC_USERSET, QUERY_TUNING_COST, + gettext_noop("Sets the planner's estimate of the cost of " + "passing each tuple (row) from worker to leader backend."), + NULL, + GUC_EXPLAIN + }, + ¶llel_tuple_cost, + DEFAULT_PARALLEL_TUPLE_COST, 0, DBL_MAX, + NULL, NULL, NULL + }, + { + {"parallel_setup_cost", PGC_USERSET, QUERY_TUNING_COST, + gettext_noop("Sets the planner's estimate of the cost of " + "starting up worker processes for parallel query."), + NULL, + GUC_EXPLAIN + }, + ¶llel_setup_cost, + DEFAULT_PARALLEL_SETUP_COST, 0, DBL_MAX, + NULL, NULL, NULL + }, + + { + {"jit_above_cost", PGC_USERSET, QUERY_TUNING_COST, + gettext_noop("Perform JIT compilation if query is more expensive."), + gettext_noop("-1 disables JIT compilation."), + GUC_EXPLAIN + }, + &jit_above_cost, + 100000, -1, DBL_MAX, + NULL, NULL, NULL + }, + + { + {"jit_optimize_above_cost", PGC_USERSET, QUERY_TUNING_COST, + gettext_noop("Optimize JIT-compiled functions if query is more expensive."), + gettext_noop("-1 disables optimization."), + GUC_EXPLAIN + }, + &jit_optimize_above_cost, + 500000, -1, DBL_MAX, + NULL, NULL, NULL + }, + + { + {"jit_inline_above_cost", PGC_USERSET, QUERY_TUNING_COST, + gettext_noop("Perform JIT inlining if query is more expensive."), + gettext_noop("-1 disables inlining."), + GUC_EXPLAIN + }, + &jit_inline_above_cost, + 500000, -1, DBL_MAX, + NULL, NULL, NULL + }, + + { + {"cursor_tuple_fraction", PGC_USERSET, QUERY_TUNING_OTHER, + gettext_noop("Sets the planner's estimate of the fraction of " + "a cursor's rows that will be retrieved."), + NULL, + GUC_EXPLAIN + }, + &cursor_tuple_fraction, + DEFAULT_CURSOR_TUPLE_FRACTION, 0.0, 1.0, + NULL, NULL, NULL + }, + + { + {"recursive_worktable_factor", PGC_USERSET, QUERY_TUNING_OTHER, + gettext_noop("Sets the planner's estimate of the average size " + "of a recursive query's working table."), + NULL, + GUC_EXPLAIN + }, + &recursive_worktable_factor, + DEFAULT_RECURSIVE_WORKTABLE_FACTOR, 0.001, 1000000.0, + NULL, NULL, NULL + }, + + { + {"geqo_selection_bias", PGC_USERSET, QUERY_TUNING_GEQO, + gettext_noop("GEQO: selective pressure within the population."), + NULL, + GUC_EXPLAIN + }, + &Geqo_selection_bias, + DEFAULT_GEQO_SELECTION_BIAS, + MIN_GEQO_SELECTION_BIAS, MAX_GEQO_SELECTION_BIAS, + NULL, NULL, NULL + }, + { + {"geqo_seed", PGC_USERSET, QUERY_TUNING_GEQO, + gettext_noop("GEQO: seed for random path selection."), + NULL, + GUC_EXPLAIN + }, + &Geqo_seed, + 0.0, 0.0, 1.0, + NULL, NULL, NULL + }, + + { + {"hash_mem_multiplier", PGC_USERSET, RESOURCES_MEM, + gettext_noop("Multiple of work_mem to use for hash tables."), + NULL, + GUC_EXPLAIN + }, + &hash_mem_multiplier, + 2.0, 1.0, 1000.0, + NULL, NULL, NULL + }, + + { + {"bgwriter_lru_multiplier", PGC_SIGHUP, RESOURCES_BGWRITER, + gettext_noop("Multiple of the average buffer usage to free per round."), + NULL + }, + &bgwriter_lru_multiplier, + 2.0, 0.0, 10.0, + NULL, NULL, NULL + }, + + { + {"seed", PGC_USERSET, UNGROUPED, + gettext_noop("Sets the seed for random-number generation."), + NULL, + GUC_NO_SHOW_ALL | GUC_NO_RESET_ALL | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE + }, + &phony_random_seed, + 0.0, -1.0, 1.0, + check_random_seed, assign_random_seed, show_random_seed + }, + + { + {"vacuum_cost_delay", PGC_USERSET, RESOURCES_VACUUM_DELAY, + gettext_noop("Vacuum cost delay in milliseconds."), + NULL, + GUC_UNIT_MS + }, + &VacuumCostDelay, + 0, 0, 100, + NULL, NULL, NULL + }, + + { + {"autovacuum_vacuum_cost_delay", PGC_SIGHUP, AUTOVACUUM, + gettext_noop("Vacuum cost delay in milliseconds, for autovacuum."), + NULL, + GUC_UNIT_MS + }, + &autovacuum_vac_cost_delay, + 2, -1, 100, + NULL, NULL, NULL + }, + + { + {"autovacuum_vacuum_scale_factor", PGC_SIGHUP, AUTOVACUUM, + gettext_noop("Number of tuple updates or deletes prior to vacuum as a fraction of reltuples."), + NULL + }, + &autovacuum_vac_scale, + 0.2, 0.0, 100.0, + NULL, NULL, NULL + }, + + { + {"autovacuum_vacuum_insert_scale_factor", PGC_SIGHUP, AUTOVACUUM, + gettext_noop("Number of tuple inserts prior to vacuum as a fraction of reltuples."), + NULL + }, + &autovacuum_vac_ins_scale, + 0.2, 0.0, 100.0, + NULL, NULL, NULL + }, + + { + {"autovacuum_analyze_scale_factor", PGC_SIGHUP, AUTOVACUUM, + gettext_noop("Number of tuple inserts, updates, or deletes prior to analyze as a fraction of reltuples."), + NULL + }, + &autovacuum_anl_scale, + 0.1, 0.0, 100.0, + NULL, NULL, NULL + }, + + { + {"checkpoint_completion_target", PGC_SIGHUP, WAL_CHECKPOINTS, + gettext_noop("Time spent flushing dirty buffers during checkpoint, as fraction of checkpoint interval."), + NULL + }, + &CheckPointCompletionTarget, + 0.9, 0.0, 1.0, + NULL, NULL, NULL + }, + + { + {"log_statement_sample_rate", PGC_SUSET, LOGGING_WHEN, + gettext_noop("Fraction of statements exceeding log_min_duration_sample to be logged."), + gettext_noop("Use a value between 0.0 (never log) and 1.0 (always log).") + }, + &log_statement_sample_rate, + 1.0, 0.0, 1.0, + NULL, NULL, NULL + }, + + { + {"log_transaction_sample_rate", PGC_SUSET, LOGGING_WHEN, + gettext_noop("Sets the fraction of transactions from which to log all statements."), + gettext_noop("Use a value between 0.0 (never log) and 1.0 (log all " + "statements for all transactions).") + }, + &log_xact_sample_rate, + 0.0, 0.0, 1.0, + NULL, NULL, NULL + }, + + /* End-of-list marker */ + { + {NULL, 0, 0, NULL, NULL}, NULL, 0.0, 0.0, 0.0, NULL, NULL, NULL + } +}; + + +struct config_string ConfigureNamesString[] = +{ + { + {"archive_command", PGC_SIGHUP, WAL_ARCHIVING, + gettext_noop("Sets the shell command that will be called to archive a WAL file."), + gettext_noop("This is used only if \"archive_library\" is not set.") + }, + &XLogArchiveCommand, + "", + NULL, NULL, show_archive_command + }, + + { + {"archive_library", PGC_SIGHUP, WAL_ARCHIVING, + gettext_noop("Sets the library that will be called to archive a WAL file."), + gettext_noop("An empty string indicates that \"archive_command\" should be used.") + }, + &XLogArchiveLibrary, + "", + NULL, NULL, NULL + }, + + { + {"restore_command", PGC_SIGHUP, WAL_ARCHIVE_RECOVERY, + gettext_noop("Sets the shell command that will be called to retrieve an archived WAL file."), + NULL + }, + &recoveryRestoreCommand, + "", + NULL, NULL, NULL + }, + + { + {"archive_cleanup_command", PGC_SIGHUP, WAL_ARCHIVE_RECOVERY, + gettext_noop("Sets the shell command that will be executed at every restart point."), + NULL + }, + &archiveCleanupCommand, + "", + NULL, NULL, NULL + }, + + { + {"recovery_end_command", PGC_SIGHUP, WAL_ARCHIVE_RECOVERY, + gettext_noop("Sets the shell command that will be executed once at the end of recovery."), + NULL + }, + &recoveryEndCommand, + "", + NULL, NULL, NULL + }, + + { + {"recovery_target_timeline", PGC_POSTMASTER, WAL_RECOVERY_TARGET, + gettext_noop("Specifies the timeline to recover into."), + NULL + }, + &recovery_target_timeline_string, + "latest", + check_recovery_target_timeline, assign_recovery_target_timeline, NULL + }, + + { + {"recovery_target", PGC_POSTMASTER, WAL_RECOVERY_TARGET, + gettext_noop("Set to \"immediate\" to end recovery as soon as a consistent state is reached."), + NULL + }, + &recovery_target_string, + "", + check_recovery_target, assign_recovery_target, NULL + }, + { + {"recovery_target_xid", PGC_POSTMASTER, WAL_RECOVERY_TARGET, + gettext_noop("Sets the transaction ID up to which recovery will proceed."), + NULL + }, + &recovery_target_xid_string, + "", + check_recovery_target_xid, assign_recovery_target_xid, NULL + }, + { + {"recovery_target_time", PGC_POSTMASTER, WAL_RECOVERY_TARGET, + gettext_noop("Sets the time stamp up to which recovery will proceed."), + NULL + }, + &recovery_target_time_string, + "", + check_recovery_target_time, assign_recovery_target_time, NULL + }, + { + {"recovery_target_name", PGC_POSTMASTER, WAL_RECOVERY_TARGET, + gettext_noop("Sets the named restore point up to which recovery will proceed."), + NULL + }, + &recovery_target_name_string, + "", + check_recovery_target_name, assign_recovery_target_name, NULL + }, + { + {"recovery_target_lsn", PGC_POSTMASTER, WAL_RECOVERY_TARGET, + gettext_noop("Sets the LSN of the write-ahead log location up to which recovery will proceed."), + NULL + }, + &recovery_target_lsn_string, + "", + check_recovery_target_lsn, assign_recovery_target_lsn, NULL + }, + + { + {"promote_trigger_file", PGC_SIGHUP, REPLICATION_STANDBY, + gettext_noop("Specifies a file name whose presence ends recovery in the standby."), + NULL + }, + &PromoteTriggerFile, + "", + NULL, NULL, NULL + }, + + { + {"primary_conninfo", PGC_SIGHUP, REPLICATION_STANDBY, + gettext_noop("Sets the connection string to be used to connect to the sending server."), + NULL, + GUC_SUPERUSER_ONLY + }, + &PrimaryConnInfo, + "", + NULL, NULL, NULL + }, + + { + {"primary_slot_name", PGC_SIGHUP, REPLICATION_STANDBY, + gettext_noop("Sets the name of the replication slot to use on the sending server."), + NULL + }, + &PrimarySlotName, + "", + check_primary_slot_name, NULL, NULL + }, + + { + {"client_encoding", PGC_USERSET, CLIENT_CONN_LOCALE, + gettext_noop("Sets the client's character set encoding."), + NULL, + GUC_IS_NAME | GUC_REPORT + }, + &client_encoding_string, + "SQL_ASCII", + check_client_encoding, assign_client_encoding, NULL + }, + + { + {"log_line_prefix", PGC_SIGHUP, LOGGING_WHAT, + gettext_noop("Controls information prefixed to each log line."), + gettext_noop("If blank, no prefix is used.") + }, + &Log_line_prefix, + "%m [%p] ", + NULL, NULL, NULL + }, + + { + {"log_timezone", PGC_SIGHUP, LOGGING_WHAT, + gettext_noop("Sets the time zone to use in log messages."), + NULL + }, + &log_timezone_string, + "GMT", + check_log_timezone, assign_log_timezone, show_log_timezone + }, + + { + {"DateStyle", PGC_USERSET, CLIENT_CONN_LOCALE, + gettext_noop("Sets the display format for date and time values."), + gettext_noop("Also controls interpretation of ambiguous " + "date inputs."), + GUC_LIST_INPUT | GUC_REPORT + }, + &datestyle_string, + "ISO, MDY", + check_datestyle, assign_datestyle, NULL + }, + + { + {"default_table_access_method", PGC_USERSET, CLIENT_CONN_STATEMENT, + gettext_noop("Sets the default table access method for new tables."), + NULL, + GUC_IS_NAME + }, + &default_table_access_method, + DEFAULT_TABLE_ACCESS_METHOD, + check_default_table_access_method, NULL, NULL + }, + + { + {"default_tablespace", PGC_USERSET, CLIENT_CONN_STATEMENT, + gettext_noop("Sets the default tablespace to create tables and indexes in."), + gettext_noop("An empty string selects the database's default tablespace."), + GUC_IS_NAME + }, + &default_tablespace, + "", + check_default_tablespace, NULL, NULL + }, + + { + {"temp_tablespaces", PGC_USERSET, CLIENT_CONN_STATEMENT, + gettext_noop("Sets the tablespace(s) to use for temporary tables and sort files."), + NULL, + GUC_LIST_INPUT | GUC_LIST_QUOTE + }, + &temp_tablespaces, + "", + check_temp_tablespaces, assign_temp_tablespaces, NULL + }, + + { + {"dynamic_library_path", PGC_SUSET, CLIENT_CONN_OTHER, + gettext_noop("Sets the path for dynamically loadable modules."), + gettext_noop("If a dynamically loadable module needs to be opened and " + "the specified name does not have a directory component (i.e., the " + "name does not contain a slash), the system will search this path for " + "the specified file."), + GUC_SUPERUSER_ONLY + }, + &Dynamic_library_path, + "$libdir", + NULL, NULL, NULL + }, + + { + {"krb_server_keyfile", PGC_SIGHUP, CONN_AUTH_AUTH, + gettext_noop("Sets the location of the Kerberos server key file."), + NULL, + GUC_SUPERUSER_ONLY + }, + &pg_krb_server_keyfile, + PG_KRB_SRVTAB, + NULL, NULL, NULL + }, + + { + {"bonjour_name", PGC_POSTMASTER, CONN_AUTH_SETTINGS, + gettext_noop("Sets the Bonjour service name."), + NULL + }, + &bonjour_name, + "", + NULL, NULL, NULL + }, + + /* See main.c about why defaults for LC_foo are not all alike */ + + { + {"lc_collate", PGC_INTERNAL, PRESET_OPTIONS, + gettext_noop("Shows the collation order locale."), + NULL, + GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE + }, + &locale_collate, + "C", + NULL, NULL, NULL + }, + + { + {"lc_ctype", PGC_INTERNAL, PRESET_OPTIONS, + gettext_noop("Shows the character classification and case conversion locale."), + NULL, + GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE + }, + &locale_ctype, + "C", + NULL, NULL, NULL + }, + + { + {"lc_messages", PGC_SUSET, CLIENT_CONN_LOCALE, + gettext_noop("Sets the language in which messages are displayed."), + NULL + }, + &locale_messages, + "", + check_locale_messages, assign_locale_messages, NULL + }, + + { + {"lc_monetary", PGC_USERSET, CLIENT_CONN_LOCALE, + gettext_noop("Sets the locale for formatting monetary amounts."), + NULL + }, + &locale_monetary, + "C", + check_locale_monetary, assign_locale_monetary, NULL + }, + + { + {"lc_numeric", PGC_USERSET, CLIENT_CONN_LOCALE, + gettext_noop("Sets the locale for formatting numbers."), + NULL + }, + &locale_numeric, + "C", + check_locale_numeric, assign_locale_numeric, NULL + }, + + { + {"lc_time", PGC_USERSET, CLIENT_CONN_LOCALE, + gettext_noop("Sets the locale for formatting date and time values."), + NULL + }, + &locale_time, + "C", + check_locale_time, assign_locale_time, NULL + }, + + { + {"session_preload_libraries", PGC_SUSET, CLIENT_CONN_PRELOAD, + gettext_noop("Lists shared libraries to preload into each backend."), + NULL, + GUC_LIST_INPUT | GUC_LIST_QUOTE | GUC_SUPERUSER_ONLY + }, + &session_preload_libraries_string, + "", + NULL, NULL, NULL + }, + + { + {"shared_preload_libraries", PGC_POSTMASTER, CLIENT_CONN_PRELOAD, + gettext_noop("Lists shared libraries to preload into server."), + NULL, + GUC_LIST_INPUT | GUC_LIST_QUOTE | GUC_SUPERUSER_ONLY + }, + &shared_preload_libraries_string, + "", + NULL, NULL, NULL + }, + + { + {"local_preload_libraries", PGC_USERSET, CLIENT_CONN_PRELOAD, + gettext_noop("Lists unprivileged shared libraries to preload into each backend."), + NULL, + GUC_LIST_INPUT | GUC_LIST_QUOTE + }, + &local_preload_libraries_string, + "", + NULL, NULL, NULL + }, + + { + {"search_path", PGC_USERSET, CLIENT_CONN_STATEMENT, + gettext_noop("Sets the schema search order for names that are not schema-qualified."), + NULL, + GUC_LIST_INPUT | GUC_LIST_QUOTE | GUC_EXPLAIN + }, + &namespace_search_path, + "\"$user\", public", + check_search_path, assign_search_path, NULL + }, + + { + /* Can't be set in postgresql.conf */ + {"server_encoding", PGC_INTERNAL, PRESET_OPTIONS, + gettext_noop("Shows the server (database) character set encoding."), + NULL, + GUC_IS_NAME | GUC_REPORT | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE + }, + &server_encoding_string, + "SQL_ASCII", + NULL, NULL, NULL + }, + + { + /* Can't be set in postgresql.conf */ + {"server_version", PGC_INTERNAL, PRESET_OPTIONS, + gettext_noop("Shows the server version."), + NULL, + GUC_REPORT | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE + }, + &server_version_string, + PG_VERSION, + NULL, NULL, NULL + }, + + { + /* Not for general use --- used by SET ROLE */ + {"role", PGC_USERSET, UNGROUPED, + gettext_noop("Sets the current role."), + NULL, + GUC_IS_NAME | GUC_NO_SHOW_ALL | GUC_NO_RESET_ALL | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE | GUC_NOT_WHILE_SEC_REST + }, + &role_string, + "none", + check_role, assign_role, show_role + }, + + { + /* Not for general use --- used by SET SESSION AUTHORIZATION */ + {"session_authorization", PGC_USERSET, UNGROUPED, + gettext_noop("Sets the session user name."), + NULL, + GUC_IS_NAME | GUC_REPORT | GUC_NO_SHOW_ALL | GUC_NO_RESET_ALL | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE | GUC_NOT_WHILE_SEC_REST + }, + &session_authorization_string, + NULL, + check_session_authorization, assign_session_authorization, NULL + }, + + { + {"log_destination", PGC_SIGHUP, LOGGING_WHERE, + gettext_noop("Sets the destination for server log output."), + gettext_noop("Valid values are combinations of \"stderr\", " + "\"syslog\", \"csvlog\", \"jsonlog\", and \"eventlog\", " + "depending on the platform."), + GUC_LIST_INPUT + }, + &Log_destination_string, + "stderr", + check_log_destination, assign_log_destination, NULL + }, + { + {"log_directory", PGC_SIGHUP, LOGGING_WHERE, + gettext_noop("Sets the destination directory for log files."), + gettext_noop("Can be specified as relative to the data directory " + "or as absolute path."), + GUC_SUPERUSER_ONLY + }, + &Log_directory, + "log", + check_canonical_path, NULL, NULL + }, + { + {"log_filename", PGC_SIGHUP, LOGGING_WHERE, + gettext_noop("Sets the file name pattern for log files."), + NULL, + GUC_SUPERUSER_ONLY + }, + &Log_filename, + "postgresql-%Y-%m-%d_%H%M%S.log", + NULL, NULL, NULL + }, + + { + {"syslog_ident", PGC_SIGHUP, LOGGING_WHERE, + gettext_noop("Sets the program name used to identify PostgreSQL " + "messages in syslog."), + NULL + }, + &syslog_ident_str, + "postgres", + NULL, assign_syslog_ident, NULL + }, + + { + {"event_source", PGC_POSTMASTER, LOGGING_WHERE, + gettext_noop("Sets the application name used to identify " + "PostgreSQL messages in the event log."), + NULL + }, + &event_source, + DEFAULT_EVENT_SOURCE, + NULL, NULL, NULL + }, + + { + {"TimeZone", PGC_USERSET, CLIENT_CONN_LOCALE, + gettext_noop("Sets the time zone for displaying and interpreting time stamps."), + NULL, + GUC_REPORT + }, + &timezone_string, + "GMT", + check_timezone, assign_timezone, show_timezone + }, + { + {"timezone_abbreviations", PGC_USERSET, CLIENT_CONN_LOCALE, + gettext_noop("Selects a file of time zone abbreviations."), + NULL + }, + &timezone_abbreviations_string, + NULL, + check_timezone_abbreviations, assign_timezone_abbreviations, NULL + }, + + { + {"unix_socket_group", PGC_POSTMASTER, CONN_AUTH_SETTINGS, + gettext_noop("Sets the owning group of the Unix-domain socket."), + gettext_noop("The owning user of the socket is always the user " + "that starts the server.") + }, + &Unix_socket_group, + "", + NULL, NULL, NULL + }, + + { + {"unix_socket_directories", PGC_POSTMASTER, CONN_AUTH_SETTINGS, + gettext_noop("Sets the directories where Unix-domain sockets will be created."), + NULL, + GUC_LIST_INPUT | GUC_LIST_QUOTE | GUC_SUPERUSER_ONLY + }, + &Unix_socket_directories, + DEFAULT_PGSOCKET_DIR, + NULL, NULL, NULL + }, + + { + {"listen_addresses", PGC_POSTMASTER, CONN_AUTH_SETTINGS, + gettext_noop("Sets the host name or IP address(es) to listen to."), + NULL, + GUC_LIST_INPUT + }, + &ListenAddresses, + "localhost", + NULL, NULL, NULL + }, + + { + /* + * Can't be set by ALTER SYSTEM as it can lead to recursive definition + * of data_directory. + */ + {"data_directory", PGC_POSTMASTER, FILE_LOCATIONS, + gettext_noop("Sets the server's data directory."), + NULL, + GUC_SUPERUSER_ONLY | GUC_DISALLOW_IN_AUTO_FILE + }, + &data_directory, + NULL, + NULL, NULL, NULL + }, + + { + {"config_file", PGC_POSTMASTER, FILE_LOCATIONS, + gettext_noop("Sets the server's main configuration file."), + NULL, + GUC_DISALLOW_IN_FILE | GUC_SUPERUSER_ONLY + }, + &ConfigFileName, + NULL, + NULL, NULL, NULL + }, + + { + {"hba_file", PGC_POSTMASTER, FILE_LOCATIONS, + gettext_noop("Sets the server's \"hba\" configuration file."), + NULL, + GUC_SUPERUSER_ONLY + }, + &HbaFileName, + NULL, + NULL, NULL, NULL + }, + + { + {"ident_file", PGC_POSTMASTER, FILE_LOCATIONS, + gettext_noop("Sets the server's \"ident\" configuration file."), + NULL, + GUC_SUPERUSER_ONLY + }, + &IdentFileName, + NULL, + NULL, NULL, NULL + }, + + { + {"external_pid_file", PGC_POSTMASTER, FILE_LOCATIONS, + gettext_noop("Writes the postmaster PID to the specified file."), + NULL, + GUC_SUPERUSER_ONLY + }, + &external_pid_file, + NULL, + check_canonical_path, NULL, NULL + }, + + { + {"ssl_library", PGC_INTERNAL, PRESET_OPTIONS, + gettext_noop("Shows the name of the SSL library."), + NULL, + GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE + }, + &ssl_library, +#ifdef USE_SSL + "OpenSSL", +#else + "", +#endif + NULL, NULL, NULL + }, + + { + {"ssl_cert_file", PGC_SIGHUP, CONN_AUTH_SSL, + gettext_noop("Location of the SSL server certificate file."), + NULL + }, + &ssl_cert_file, + "server.crt", + NULL, NULL, NULL + }, + + { + {"ssl_key_file", PGC_SIGHUP, CONN_AUTH_SSL, + gettext_noop("Location of the SSL server private key file."), + NULL + }, + &ssl_key_file, + "server.key", + NULL, NULL, NULL + }, + + { + {"ssl_ca_file", PGC_SIGHUP, CONN_AUTH_SSL, + gettext_noop("Location of the SSL certificate authority file."), + NULL + }, + &ssl_ca_file, + "", + NULL, NULL, NULL + }, + + { + {"ssl_crl_file", PGC_SIGHUP, CONN_AUTH_SSL, + gettext_noop("Location of the SSL certificate revocation list file."), + NULL + }, + &ssl_crl_file, + "", + NULL, NULL, NULL + }, + + { + {"ssl_crl_dir", PGC_SIGHUP, CONN_AUTH_SSL, + gettext_noop("Location of the SSL certificate revocation list directory."), + NULL + }, + &ssl_crl_dir, + "", + NULL, NULL, NULL + }, + + { + {"synchronous_standby_names", PGC_SIGHUP, REPLICATION_PRIMARY, + gettext_noop("Number of synchronous standbys and list of names of potential synchronous ones."), + NULL, + GUC_LIST_INPUT + }, + &SyncRepStandbyNames, + "", + check_synchronous_standby_names, assign_synchronous_standby_names, NULL + }, + + { + {"default_text_search_config", PGC_USERSET, CLIENT_CONN_LOCALE, + gettext_noop("Sets default text search configuration."), + NULL + }, + &TSCurrentConfig, + "pg_catalog.simple", + check_default_text_search_config, assign_default_text_search_config, NULL + }, + + { + {"ssl_ciphers", PGC_SIGHUP, CONN_AUTH_SSL, + gettext_noop("Sets the list of allowed SSL ciphers."), + NULL, + GUC_SUPERUSER_ONLY + }, + &SSLCipherSuites, +#ifdef USE_OPENSSL + "HIGH:MEDIUM:+3DES:!aNULL", +#else + "none", +#endif + NULL, NULL, NULL + }, + + { + {"ssl_ecdh_curve", PGC_SIGHUP, CONN_AUTH_SSL, + gettext_noop("Sets the curve to use for ECDH."), + NULL, + GUC_SUPERUSER_ONLY + }, + &SSLECDHCurve, +#ifdef USE_SSL + "prime256v1", +#else + "none", +#endif + NULL, NULL, NULL + }, + + { + {"ssl_dh_params_file", PGC_SIGHUP, CONN_AUTH_SSL, + gettext_noop("Location of the SSL DH parameters file."), + NULL, + GUC_SUPERUSER_ONLY + }, + &ssl_dh_params_file, + "", + NULL, NULL, NULL + }, + + { + {"ssl_passphrase_command", PGC_SIGHUP, CONN_AUTH_SSL, + gettext_noop("Command to obtain passphrases for SSL."), + NULL, + GUC_SUPERUSER_ONLY + }, + &ssl_passphrase_command, + "", + NULL, NULL, NULL + }, + + { + {"application_name", PGC_USERSET, LOGGING_WHAT, + gettext_noop("Sets the application name to be reported in statistics and logs."), + NULL, + GUC_IS_NAME | GUC_REPORT | GUC_NOT_IN_SAMPLE + }, + &application_name, + "", + check_application_name, assign_application_name, NULL + }, + + { + {"cluster_name", PGC_POSTMASTER, PROCESS_TITLE, + gettext_noop("Sets the name of the cluster, which is included in the process title."), + NULL, + GUC_IS_NAME + }, + &cluster_name, + "", + check_cluster_name, NULL, NULL + }, + + { + {"wal_consistency_checking", PGC_SUSET, DEVELOPER_OPTIONS, + gettext_noop("Sets the WAL resource managers for which WAL consistency checks are done."), + gettext_noop("Full-page images will be logged for all data blocks and cross-checked against the results of WAL replay."), + GUC_LIST_INPUT | GUC_NOT_IN_SAMPLE + }, + &wal_consistency_checking_string, + "", + check_wal_consistency_checking, assign_wal_consistency_checking, NULL + }, + + { + {"jit_provider", PGC_POSTMASTER, CLIENT_CONN_PRELOAD, + gettext_noop("JIT provider to use."), + NULL, + GUC_SUPERUSER_ONLY + }, + &jit_provider, + "llvmjit", + NULL, NULL, NULL + }, + + { + {"backtrace_functions", PGC_SUSET, DEVELOPER_OPTIONS, + gettext_noop("Log backtrace for errors in these functions."), + NULL, + GUC_NOT_IN_SAMPLE + }, + &backtrace_functions, + "", + check_backtrace_functions, assign_backtrace_functions, NULL + }, + + /* End-of-list marker */ + { + {NULL, 0, 0, NULL, NULL}, NULL, NULL, NULL, NULL, NULL + } +}; + + +struct config_enum ConfigureNamesEnum[] = +{ + { + {"backslash_quote", PGC_USERSET, COMPAT_OPTIONS_PREVIOUS, + gettext_noop("Sets whether \"\\'\" is allowed in string literals."), + NULL + }, + &backslash_quote, + BACKSLASH_QUOTE_SAFE_ENCODING, backslash_quote_options, + NULL, NULL, NULL + }, + + { + {"bytea_output", PGC_USERSET, CLIENT_CONN_STATEMENT, + gettext_noop("Sets the output format for bytea."), + NULL + }, + &bytea_output, + BYTEA_OUTPUT_HEX, bytea_output_options, + NULL, NULL, NULL + }, + + { + {"client_min_messages", PGC_USERSET, CLIENT_CONN_STATEMENT, + gettext_noop("Sets the message levels that are sent to the client."), + gettext_noop("Each level includes all the levels that follow it. The later" + " the level, the fewer messages are sent.") + }, + &client_min_messages, + NOTICE, client_message_level_options, + NULL, NULL, NULL + }, + + { + {"compute_query_id", PGC_SUSET, STATS_MONITORING, + gettext_noop("Enables in-core computation of query identifiers."), + NULL + }, + &compute_query_id, + COMPUTE_QUERY_ID_AUTO, compute_query_id_options, + NULL, NULL, NULL + }, + + { + {"constraint_exclusion", PGC_USERSET, QUERY_TUNING_OTHER, + gettext_noop("Enables the planner to use constraints to optimize queries."), + gettext_noop("Table scans will be skipped if their constraints" + " guarantee that no rows match the query."), + GUC_EXPLAIN + }, + &constraint_exclusion, + CONSTRAINT_EXCLUSION_PARTITION, constraint_exclusion_options, + NULL, NULL, NULL + }, + + { + {"default_toast_compression", PGC_USERSET, CLIENT_CONN_STATEMENT, + gettext_noop("Sets the default compression method for compressible values."), + NULL + }, + &default_toast_compression, + TOAST_PGLZ_COMPRESSION, + default_toast_compression_options, + NULL, NULL, NULL + }, + + { + {"default_transaction_isolation", PGC_USERSET, CLIENT_CONN_STATEMENT, + gettext_noop("Sets the transaction isolation level of each new transaction."), + NULL + }, + &DefaultXactIsoLevel, + XACT_READ_COMMITTED, isolation_level_options, + NULL, NULL, NULL + }, + + { + {"transaction_isolation", PGC_USERSET, CLIENT_CONN_STATEMENT, + gettext_noop("Sets the current transaction's isolation level."), + NULL, + GUC_NO_RESET_ALL | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE + }, + &XactIsoLevel, + XACT_READ_COMMITTED, isolation_level_options, + check_transaction_isolation, NULL, NULL + }, + + { + {"IntervalStyle", PGC_USERSET, CLIENT_CONN_LOCALE, + gettext_noop("Sets the display format for interval values."), + NULL, + GUC_REPORT + }, + &IntervalStyle, + INTSTYLE_POSTGRES, intervalstyle_options, + NULL, NULL, NULL + }, + + { + {"log_error_verbosity", PGC_SUSET, LOGGING_WHAT, + gettext_noop("Sets the verbosity of logged messages."), + NULL + }, + &Log_error_verbosity, + PGERROR_DEFAULT, log_error_verbosity_options, + NULL, NULL, NULL + }, + + { + {"log_min_messages", PGC_SUSET, LOGGING_WHEN, + gettext_noop("Sets the message levels that are logged."), + gettext_noop("Each level includes all the levels that follow it. The later" + " the level, the fewer messages are sent.") + }, + &log_min_messages, + WARNING, server_message_level_options, + NULL, NULL, NULL + }, + + { + {"log_min_error_statement", PGC_SUSET, LOGGING_WHEN, + gettext_noop("Causes all statements generating error at or above this level to be logged."), + gettext_noop("Each level includes all the levels that follow it. The later" + " the level, the fewer messages are sent.") + }, + &log_min_error_statement, + ERROR, server_message_level_options, + NULL, NULL, NULL + }, + + { + {"log_statement", PGC_SUSET, LOGGING_WHAT, + gettext_noop("Sets the type of statements logged."), + NULL + }, + &log_statement, + LOGSTMT_NONE, log_statement_options, + NULL, NULL, NULL + }, + + { + {"syslog_facility", PGC_SIGHUP, LOGGING_WHERE, + gettext_noop("Sets the syslog \"facility\" to be used when syslog enabled."), + NULL + }, + &syslog_facility, +#ifdef HAVE_SYSLOG + LOG_LOCAL0, +#else + 0, +#endif + syslog_facility_options, + NULL, assign_syslog_facility, NULL + }, + + { + {"session_replication_role", PGC_SUSET, CLIENT_CONN_STATEMENT, + gettext_noop("Sets the session's behavior for triggers and rewrite rules."), + NULL + }, + &SessionReplicationRole, + SESSION_REPLICATION_ROLE_ORIGIN, session_replication_role_options, + NULL, assign_session_replication_role, NULL + }, + + { + {"synchronous_commit", PGC_USERSET, WAL_SETTINGS, + gettext_noop("Sets the current transaction's synchronization level."), + NULL + }, + &synchronous_commit, + SYNCHRONOUS_COMMIT_ON, synchronous_commit_options, + NULL, assign_synchronous_commit, NULL + }, + + { + {"archive_mode", PGC_POSTMASTER, WAL_ARCHIVING, + gettext_noop("Allows archiving of WAL files using archive_command."), + NULL + }, + &XLogArchiveMode, + ARCHIVE_MODE_OFF, archive_mode_options, + NULL, NULL, NULL + }, + + { + {"recovery_target_action", PGC_POSTMASTER, WAL_RECOVERY_TARGET, + gettext_noop("Sets the action to perform upon reaching the recovery target."), + NULL + }, + &recoveryTargetAction, + RECOVERY_TARGET_ACTION_PAUSE, recovery_target_action_options, + NULL, NULL, NULL + }, + + { + {"trace_recovery_messages", PGC_SIGHUP, DEVELOPER_OPTIONS, + gettext_noop("Enables logging of recovery-related debugging information."), + gettext_noop("Each level includes all the levels that follow it. The later" + " the level, the fewer messages are sent."), + GUC_NOT_IN_SAMPLE, + }, + &trace_recovery_messages, + + /* + * client_message_level_options allows too many values, really, but + * it's not worth having a separate options array for this. + */ + LOG, client_message_level_options, + NULL, NULL, NULL + }, + + { + {"track_functions", PGC_SUSET, STATS_CUMULATIVE, + gettext_noop("Collects function-level statistics on database activity."), + NULL + }, + &pgstat_track_functions, + TRACK_FUNC_OFF, track_function_options, + NULL, NULL, NULL + }, + + + { + {"stats_fetch_consistency", PGC_USERSET, STATS_CUMULATIVE, + gettext_noop("Sets the consistency of accesses to statistics data."), + NULL + }, + &pgstat_fetch_consistency, + PGSTAT_FETCH_CONSISTENCY_CACHE, stats_fetch_consistency, + NULL, NULL, NULL + }, + + { + {"wal_compression", PGC_SUSET, WAL_SETTINGS, + gettext_noop("Compresses full-page writes written in WAL file with specified method."), + NULL + }, + &wal_compression, + WAL_COMPRESSION_NONE, wal_compression_options, + NULL, NULL, NULL + }, + + { + {"wal_level", PGC_POSTMASTER, WAL_SETTINGS, + gettext_noop("Sets the level of information written to the WAL."), + NULL + }, + &wal_level, + WAL_LEVEL_REPLICA, wal_level_options, + NULL, NULL, NULL + }, + + { + {"dynamic_shared_memory_type", PGC_POSTMASTER, RESOURCES_MEM, + gettext_noop("Selects the dynamic shared memory implementation used."), + NULL + }, + &dynamic_shared_memory_type, + DEFAULT_DYNAMIC_SHARED_MEMORY_TYPE, dynamic_shared_memory_options, + NULL, NULL, NULL + }, + + { + {"shared_memory_type", PGC_POSTMASTER, RESOURCES_MEM, + gettext_noop("Selects the shared memory implementation used for the main shared memory region."), + NULL + }, + &shared_memory_type, + DEFAULT_SHARED_MEMORY_TYPE, shared_memory_options, + NULL, NULL, NULL + }, + + { + {"wal_sync_method", PGC_SIGHUP, WAL_SETTINGS, + gettext_noop("Selects the method used for forcing WAL updates to disk."), + NULL + }, + &sync_method, + DEFAULT_SYNC_METHOD, sync_method_options, + NULL, assign_xlog_sync_method, NULL + }, + + { + {"xmlbinary", PGC_USERSET, CLIENT_CONN_STATEMENT, + gettext_noop("Sets how binary values are to be encoded in XML."), + NULL + }, + &xmlbinary, + XMLBINARY_BASE64, xmlbinary_options, + NULL, NULL, NULL + }, + + { + {"xmloption", PGC_USERSET, CLIENT_CONN_STATEMENT, + gettext_noop("Sets whether XML data in implicit parsing and serialization " + "operations is to be considered as documents or content fragments."), + NULL + }, + &xmloption, + XMLOPTION_CONTENT, xmloption_options, + NULL, NULL, NULL + }, + + { + {"huge_pages", PGC_POSTMASTER, RESOURCES_MEM, + gettext_noop("Use of huge pages on Linux or Windows."), + NULL + }, + &huge_pages, + HUGE_PAGES_TRY, huge_pages_options, + NULL, NULL, NULL + }, + + { + {"recovery_prefetch", PGC_SIGHUP, WAL_RECOVERY, + gettext_noop("Prefetch referenced blocks during recovery."), + gettext_noop("Look ahead in the WAL to find references to uncached data.") + }, + &recovery_prefetch, + RECOVERY_PREFETCH_TRY, recovery_prefetch_options, + check_recovery_prefetch, assign_recovery_prefetch, NULL + }, + + { + {"force_parallel_mode", PGC_USERSET, DEVELOPER_OPTIONS, + gettext_noop("Forces use of parallel query facilities."), + gettext_noop("If possible, run query using a parallel worker and with parallel restrictions."), + GUC_NOT_IN_SAMPLE | GUC_EXPLAIN + }, + &force_parallel_mode, + FORCE_PARALLEL_OFF, force_parallel_mode_options, + NULL, NULL, NULL + }, + + { + {"password_encryption", PGC_USERSET, CONN_AUTH_AUTH, + gettext_noop("Chooses the algorithm for encrypting passwords."), + NULL + }, + &Password_encryption, + PASSWORD_TYPE_SCRAM_SHA_256, password_encryption_options, + NULL, NULL, NULL + }, + + { + {"plan_cache_mode", PGC_USERSET, QUERY_TUNING_OTHER, + gettext_noop("Controls the planner's selection of custom or generic plan."), + gettext_noop("Prepared statements can have custom and generic plans, and the planner " + "will attempt to choose which is better. This can be set to override " + "the default behavior."), + GUC_EXPLAIN + }, + &plan_cache_mode, + PLAN_CACHE_MODE_AUTO, plan_cache_mode_options, + NULL, NULL, NULL + }, + + { + {"ssl_min_protocol_version", PGC_SIGHUP, CONN_AUTH_SSL, + gettext_noop("Sets the minimum SSL/TLS protocol version to use."), + NULL, + GUC_SUPERUSER_ONLY + }, + &ssl_min_protocol_version, + PG_TLS1_2_VERSION, + ssl_protocol_versions_info + 1, /* don't allow PG_TLS_ANY */ + NULL, NULL, NULL + }, + + { + {"ssl_max_protocol_version", PGC_SIGHUP, CONN_AUTH_SSL, + gettext_noop("Sets the maximum SSL/TLS protocol version to use."), + NULL, + GUC_SUPERUSER_ONLY + }, + &ssl_max_protocol_version, + PG_TLS_ANY, + ssl_protocol_versions_info, + NULL, NULL, NULL + }, + + { + {"recovery_init_sync_method", PGC_SIGHUP, ERROR_HANDLING_OPTIONS, + gettext_noop("Sets the method for synchronizing the data directory before crash recovery."), + }, + &recovery_init_sync_method, + RECOVERY_INIT_SYNC_METHOD_FSYNC, recovery_init_sync_method_options, + NULL, NULL, NULL + }, + + /* End-of-list marker */ + { + {NULL, 0, 0, NULL, NULL}, NULL, 0, NULL, NULL, NULL, NULL + } +}; diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h index 9df4e7cb0a..ffe265d2a1 100644 --- a/src/include/access/tableam.h +++ b/src/include/access/tableam.h @@ -20,7 +20,7 @@ #include "access/relscan.h" #include "access/sdir.h" #include "access/xact.h" -#include "utils/guc.h" +#include "executor/tuptable.h" #include "utils/rel.h" #include "utils/snapshot.h" @@ -2072,7 +2072,5 @@ extern void table_block_relation_estimate_size(Relation rel, extern const TableAmRoutine *GetTableAmRoutine(Oid amhandler); extern const TableAmRoutine *GetHeapamTableAmRoutine(void); -extern bool check_default_table_access_method(char **newval, void **extra, - GucSource source); #endif /* TABLEAM_H */ diff --git a/src/include/access/xlog.h b/src/include/access/xlog.h index cd674c3c23..9ebd321ba7 100644 --- a/src/include/access/xlog.h +++ b/src/include/access/xlog.h @@ -227,6 +227,7 @@ extern XLogRecPtr GetFakeLSNForUnloggedRel(void); extern Size XLOGShmemSize(void); extern void XLOGShmemInit(void); extern void BootStrapXLOG(void); +extern void InitializeWalConsistencyChecking(void); extern void LocalProcessControlFile(bool reset); extern void StartupXLOG(void); extern void ShutdownXLOG(int code, Datum arg); @@ -245,9 +246,6 @@ extern XLogRecPtr GetLastImportantRecPtr(void); extern void SetWalWriterSleeping(bool sleeping); -extern void assign_max_wal_size(int newval, void *extra); -extern void assign_checkpoint_completion_target(double newval, void *extra); - /* * Routines used by xlogrecovery.c to call back into xlog.c during recovery. */ diff --git a/src/include/commands/variable.h b/src/include/commands/variable.h deleted file mode 100644 index 0e5ddcbcf3..0000000000 --- a/src/include/commands/variable.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * variable.h - * Routines for handling specialized SET variables. - * - * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * src/include/commands/variable.h - */ -#ifndef VARIABLE_H -#define VARIABLE_H - -#include "utils/guc.h" - - -extern bool check_datestyle(char **newval, void **extra, GucSource source); -extern void assign_datestyle(const char *newval, void *extra); -extern bool check_timezone(char **newval, void **extra, GucSource source); -extern void assign_timezone(const char *newval, void *extra); -extern const char *show_timezone(void); -extern bool check_log_timezone(char **newval, void **extra, GucSource source); -extern void assign_log_timezone(const char *newval, void *extra); -extern const char *show_log_timezone(void); -extern bool check_transaction_read_only(bool *newval, void **extra, GucSource source); -extern bool check_XactIsoLevel(int *newval, void **extra, GucSource source); -extern bool check_transaction_deferrable(bool *newval, void **extra, GucSource source); -extern bool check_random_seed(double *newval, void **extra, GucSource source); -extern void assign_random_seed(double newval, void *extra); -extern const char *show_random_seed(void); -extern bool check_client_encoding(char **newval, void **extra, GucSource source); -extern void assign_client_encoding(const char *newval, void *extra); -extern bool check_session_authorization(char **newval, void **extra, GucSource source); -extern void assign_session_authorization(const char *newval, void *extra); -extern bool check_role(char **newval, void **extra, GucSource source); -extern void assign_role(const char *newval, void *extra); -extern const char *show_role(void); - -#endif /* VARIABLE_H */ diff --git a/src/include/replication/syncrep.h b/src/include/replication/syncrep.h index 4d7c90b9f0..b5446597b5 100644 --- a/src/include/replication/syncrep.h +++ b/src/include/replication/syncrep.h @@ -14,7 +14,6 @@ #define _SYNCREP_H #include "access/xlogdefs.h" -#include "utils/guc.h" #define SyncRepRequested() \ (max_wal_senders > 0 && synchronous_commit > SYNCHRONOUS_COMMIT_LOCAL_FLUSH) @@ -97,11 +96,6 @@ extern int SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys); /* called by checkpointer */ extern void SyncRepUpdateSyncStandbysDefined(void); -/* GUC infrastructure */ -extern bool check_synchronous_standby_names(char **newval, void **extra, GucSource source); -extern void assign_synchronous_standby_names(const char *newval, void *extra); -extern void assign_synchronous_commit(int newval, void *extra); - /* * Internal functions for parsing synchronous_standby_names grammar, * in syncrep_gram.y and syncrep_scanner.l diff --git a/src/include/tcop/tcopprot.h b/src/include/tcop/tcopprot.h index 70d9dab25b..5d34978f32 100644 --- a/src/include/tcop/tcopprot.h +++ b/src/include/tcop/tcopprot.h @@ -66,9 +66,6 @@ extern List *pg_plan_queries(List *querytrees, const char *query_string, int cursorOptions, ParamListInfo boundParams); -extern bool check_max_stack_depth(int *newval, void **extra, GucSource source); -extern void assign_max_stack_depth(int newval, void *extra); - extern void die(SIGNAL_ARGS); extern void quickdie(SIGNAL_ARGS) pg_attribute_noreturn(); extern void StatementCancelHandler(SIGNAL_ARGS); diff --git a/src/include/tsearch/ts_cache.h b/src/include/tsearch/ts_cache.h index 5e4a49ea1c..bcb5c7665b 100644 --- a/src/include/tsearch/ts_cache.h +++ b/src/include/tsearch/ts_cache.h @@ -13,7 +13,7 @@ #ifndef TS_CACHE_H #define TS_CACHE_H -#include "utils/guc.h" +#include "fmgr.h" /* @@ -92,7 +92,5 @@ extern TSDictionaryCacheEntry *lookup_ts_dictionary_cache(Oid dictId); extern TSConfigCacheEntry *lookup_ts_config_cache(Oid cfgId); extern Oid getTSCurrentConfig(bool emitError); -extern bool check_TSCurrentConfig(char **newval, void **extra, GucSource source); -extern void assign_TSCurrentConfig(const char *newval, void *extra); #endif /* TS_CACHE_H */ diff --git a/src/include/utils/elog.h b/src/include/utils/elog.h index 5639817690..4dd9658a3c 100644 --- a/src/include/utils/elog.h +++ b/src/include/utils/elog.h @@ -460,10 +460,6 @@ extern void write_pipe_chunks(char *data, int len, int dest); extern void write_csvlog(ErrorData *edata); extern void write_jsonlog(ErrorData *edata); -#ifdef HAVE_SYSLOG -extern void set_syslog_parameters(const char *ident, int facility); -#endif - /* * Write errors to stderr (or by equal means when stderr is * not available). Used before ereport/elog can be used diff --git a/src/include/utils/guc.h b/src/include/utils/guc.h index 5da17a4849..e426dd757d 100644 --- a/src/include/utils/guc.h +++ b/src/include/utils/guc.h @@ -1,8 +1,7 @@ /*-------------------------------------------------------------------- * guc.h * - * External declarations pertaining to backend/utils/misc/guc.c and - * backend/utils/misc/guc-file.l + * External declarations pertaining to Grand Unified Configuration. * * Copyright (c) 2000-2022, PostgreSQL Global Development Group * Written by Peter Eisentraut . @@ -242,7 +241,7 @@ typedef enum #define GUC_UNIT (GUC_UNIT_MEMORY | GUC_UNIT_TIME) -/* GUC vars that are actually declared in guc.c, rather than elsewhere */ +/* GUC vars that are actually defined in guc_tables.c, rather than elsewhere */ extern PGDLLIMPORT bool Debug_print_plan; extern PGDLLIMPORT bool Debug_print_parse; extern PGDLLIMPORT bool Debug_print_rewritten; @@ -269,7 +268,6 @@ extern PGDLLIMPORT int log_temp_files; extern PGDLLIMPORT double log_statement_sample_rate; extern PGDLLIMPORT double log_xact_sample_rate; extern PGDLLIMPORT char *backtrace_functions; -extern PGDLLIMPORT char *backtrace_symbol_list; extern PGDLLIMPORT int temp_file_limit; @@ -371,7 +369,6 @@ extern void ProcessConfigFile(GucContext context); extern char *convert_GUC_name_for_parameter_acl(const char *name); extern bool check_GUC_name_for_parameter_acl(const char *name); extern void InitializeGUCOptions(void); -extern void InitializeWalConsistencyChecking(void); extern bool SelectConfigFiles(const char *userDoption, const char *progname); extern void ResetAllOptions(void); extern void AtStart_GUC(void); @@ -380,6 +377,7 @@ extern void AtEOXact_GUC(bool isCommit, int nestLevel); extern void BeginReportingGUCOptions(void); extern void ReportChangedGUCOptions(void); extern void ParseLongOption(const char *string, char **name, char **value); +extern const char *get_config_unit_name(int flags); extern bool parse_int(const char *value, int *result, int flags, const char **hintmsg); extern bool parse_real(const char *value, double *result, int flags, @@ -396,22 +394,18 @@ extern int set_config_option_ext(const char *name, const char *value, extern void AlterSystemSetConfigFile(AlterSystemStmt *altersysstmt); extern char *GetConfigOptionByName(const char *name, const char **varname, bool missing_ok); -extern void GetConfigOptionByNum(int varnum, const char **values, bool *noshow); extern int GetNumConfigOptions(void); -extern void SetPGVariable(const char *name, List *args, bool is_local); -extern void GetPGVariable(const char *name, DestReceiver *dest); -extern TupleDesc GetPGVariableResultDesc(const char *name); - -extern void ExecSetVariableStmt(VariableSetStmt *stmt, bool isTopLevel); -extern char *ExtractSetVariableArgs(VariableSetStmt *stmt); - extern void ProcessGUCArray(ArrayType *array, GucContext context, GucSource source, GucAction action); extern ArrayType *GUCArrayAdd(ArrayType *array, const char *name, const char *value); extern ArrayType *GUCArrayDelete(ArrayType *array, const char *name); extern ArrayType *GUCArrayReset(ArrayType *array); +extern void *guc_malloc(int elevel, size_t size); +extern pg_nodiscard void *guc_realloc(int elevel, void *old, size_t size); +extern char *guc_strdup(int elevel, const char *src); + #ifdef EXEC_BACKEND extern void write_nondefault_variables(GucContext context); extern void read_nondefault_variables(void); @@ -422,6 +416,13 @@ extern Size EstimateGUCStateSpace(void); extern void SerializeGUCState(Size maxsize, char *start_address); extern void RestoreGUCState(void *gucstate); +/* Functions exported by guc_funcs.c */ +extern void ExecSetVariableStmt(VariableSetStmt *stmt, bool isTopLevel); +extern char *ExtractSetVariableArgs(VariableSetStmt *stmt); +extern void SetPGVariable(const char *name, List *args, bool is_local); +extern void GetPGVariable(const char *name, DestReceiver *dest); +extern TupleDesc GetPGVariableResultDesc(const char *name); + /* Support for messages reported from GUC check hooks */ extern PGDLLIMPORT char *GUC_check_errmsg_string; @@ -442,27 +443,4 @@ extern void GUC_check_errcode(int sqlerrcode); pre_format_elog_string(errno, TEXTDOMAIN), \ GUC_check_errhint_string = format_elog_string -/* - * The following functions are not in guc.c, but are declared here to avoid - * having to include guc.h in some widely used headers that it really doesn't - * belong in. - */ - -/* in commands/tablespace.c */ -extern bool check_default_tablespace(char **newval, void **extra, GucSource source); -extern bool check_temp_tablespaces(char **newval, void **extra, GucSource source); -extern void assign_temp_tablespaces(const char *newval, void *extra); - -/* in catalog/namespace.c */ -extern bool check_search_path(char **newval, void **extra, GucSource source); -extern void assign_search_path(const char *newval, void *extra); - -/* in access/transam/xlog.c */ -extern bool check_wal_buffers(int *newval, void **extra, GucSource source); -extern void assign_xlog_sync_method(int new_sync_method, void *extra); - -/* in access/transam/xlogprefetcher.c */ -extern bool check_recovery_prefetch(int *new_value, void **extra, GucSource source); -extern void assign_recovery_prefetch(int new_value, void *extra); - #endif /* GUC_H */ diff --git a/src/include/utils/guc_hooks.h b/src/include/utils/guc_hooks.h new file mode 100644 index 0000000000..f1a9a183b4 --- /dev/null +++ b/src/include/utils/guc_hooks.h @@ -0,0 +1,158 @@ +/*------------------------------------------------------------------------- + * + * guc_hooks.h + * Declarations of per-variable callback functions used by GUC. + * + * These functions are scattered throughout the system, but we + * declare them all here to avoid having to propagate guc.h into + * a lot of unrelated header files. + * + * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group + * + * src/include/utils/guc_hooks.h + * + *------------------------------------------------------------------------- + */ +#ifndef GUC_HOOKS_H +#define GUC_HOOKS_H 1 + +#include "utils/guc.h" + +/* + * See guc.h for the typedefs that these hook functions should match + * (GucBoolCheckHook and so on). + * + * Please keep the declarations in order by GUC variable name. + */ + +extern bool check_application_name(char **newval, void **extra, + GucSource source); +extern void assign_application_name(const char *newval, void *extra); +extern const char *show_archive_command(void); +extern bool check_autovacuum_max_workers(int *newval, void **extra, + GucSource source); +extern bool check_autovacuum_work_mem(int *newval, void **extra, + GucSource source); +extern bool check_backtrace_functions(char **newval, void **extra, + GucSource source); +extern void assign_backtrace_functions(const char *newval, void *extra); +extern bool check_bonjour(bool *newval, void **extra, GucSource source); +extern bool check_canonical_path(char **newval, void **extra, GucSource source); +extern void assign_checkpoint_completion_target(double newval, void *extra); +extern bool check_client_connection_check_interval(int *newval, void **extra, + GucSource source); +extern bool check_client_encoding(char **newval, void **extra, GucSource source); +extern void assign_client_encoding(const char *newval, void *extra); +extern bool check_cluster_name(char **newval, void **extra, GucSource source); +extern const char *show_data_directory_mode(void); +extern bool check_datestyle(char **newval, void **extra, GucSource source); +extern void assign_datestyle(const char *newval, void *extra); +extern bool check_default_table_access_method(char **newval, void **extra, + GucSource source); +extern bool check_default_tablespace(char **newval, void **extra, + GucSource source); +extern bool check_default_text_search_config(char **newval, void **extra, GucSource source); +extern void assign_default_text_search_config(const char *newval, void *extra); +extern bool check_default_with_oids(bool *newval, void **extra, + GucSource source); +extern bool check_effective_io_concurrency(int *newval, void **extra, + GucSource source); +extern bool check_huge_page_size(int *newval, void **extra, GucSource source); +extern const char *show_in_hot_standby(void); +extern bool check_locale_messages(char **newval, void **extra, GucSource source); +extern void assign_locale_messages(const char *newval, void *extra); +extern bool check_locale_monetary(char **newval, void **extra, GucSource source); +extern void assign_locale_monetary(const char *newval, void *extra); +extern bool check_locale_numeric(char **newval, void **extra, GucSource source); +extern void assign_locale_numeric(const char *newval, void *extra); +extern bool check_locale_time(char **newval, void **extra, GucSource source); +extern void assign_locale_time(const char *newval, void *extra); +extern bool check_log_destination(char **newval, void **extra, + GucSource source); +extern void assign_log_destination(const char *newval, void *extra); +extern const char *show_log_file_mode(void); +extern bool check_log_stats(bool *newval, void **extra, GucSource source); +extern bool check_log_timezone(char **newval, void **extra, GucSource source); +extern void assign_log_timezone(const char *newval, void *extra); +extern const char *show_log_timezone(void); +extern bool check_maintenance_io_concurrency(int *newval, void **extra, + GucSource source); +extern void assign_maintenance_io_concurrency(int newval, void *extra); +extern bool check_max_connections(int *newval, void **extra, GucSource source); +extern bool check_max_wal_senders(int *newval, void **extra, GucSource source); +extern void assign_max_wal_size(int newval, void *extra); +extern bool check_max_worker_processes(int *newval, void **extra, + GucSource source); +extern bool check_max_stack_depth(int *newval, void **extra, GucSource source); +extern void assign_max_stack_depth(int newval, void *extra); +extern bool check_primary_slot_name(char **newval, void **extra, + GucSource source); +extern bool check_random_seed(double *newval, void **extra, GucSource source); +extern void assign_random_seed(double newval, void *extra); +extern const char *show_random_seed(void); +extern bool check_recovery_prefetch(int *new_value, void **extra, + GucSource source); +extern void assign_recovery_prefetch(int new_value, void *extra); +extern bool check_recovery_target(char **newval, void **extra, + GucSource source); +extern void assign_recovery_target(const char *newval, void *extra); +extern bool check_recovery_target_lsn(char **newval, void **extra, + GucSource source); +extern void assign_recovery_target_lsn(const char *newval, void *extra); +extern bool check_recovery_target_name(char **newval, void **extra, + GucSource source); +extern void assign_recovery_target_name(const char *newval, void *extra); +extern bool check_recovery_target_time(char **newval, void **extra, + GucSource source); +extern void assign_recovery_target_time(const char *newval, void *extra); +extern bool check_recovery_target_timeline(char **newval, void **extra, + GucSource source); +extern void assign_recovery_target_timeline(const char *newval, void *extra); +extern bool check_recovery_target_xid(char **newval, void **extra, + GucSource source); +extern void assign_recovery_target_xid(const char *newval, void *extra); +extern bool check_role(char **newval, void **extra, GucSource source); +extern void assign_role(const char *newval, void *extra); +extern const char *show_role(void); +extern bool check_search_path(char **newval, void **extra, GucSource source); +extern void assign_search_path(const char *newval, void *extra); +extern bool check_session_authorization(char **newval, void **extra, GucSource source); +extern void assign_session_authorization(const char *newval, void *extra); +extern void assign_session_replication_role(int newval, void *extra); +extern bool check_ssl(bool *newval, void **extra, GucSource source); +extern bool check_stage_log_stats(bool *newval, void **extra, GucSource source); +extern bool check_synchronous_standby_names(char **newval, void **extra, + GucSource source); +extern void assign_synchronous_standby_names(const char *newval, void *extra); +extern void assign_synchronous_commit(int newval, void *extra); +extern void assign_syslog_facility(int newval, void *extra); +extern void assign_syslog_ident(const char *newval, void *extra); +extern void assign_tcp_keepalives_count(int newval, void *extra); +extern const char *show_tcp_keepalives_count(void); +extern void assign_tcp_keepalives_idle(int newval, void *extra); +extern const char *show_tcp_keepalives_idle(void); +extern void assign_tcp_keepalives_interval(int newval, void *extra); +extern const char *show_tcp_keepalives_interval(void); +extern void assign_tcp_user_timeout(int newval, void *extra); +extern const char *show_tcp_user_timeout(void); +extern bool check_temp_buffers(int *newval, void **extra, GucSource source); +extern bool check_temp_tablespaces(char **newval, void **extra, + GucSource source); +extern void assign_temp_tablespaces(const char *newval, void *extra); +extern bool check_timezone(char **newval, void **extra, GucSource source); +extern void assign_timezone(const char *newval, void *extra); +extern const char *show_timezone(void); +extern bool check_timezone_abbreviations(char **newval, void **extra, + GucSource source); +extern void assign_timezone_abbreviations(const char *newval, void *extra); +extern bool check_transaction_deferrable(bool *newval, void **extra, GucSource source); +extern bool check_transaction_isolation(int *newval, void **extra, GucSource source); +extern bool check_transaction_read_only(bool *newval, void **extra, GucSource source); +extern const char *show_unix_socket_permissions(void); +extern bool check_wal_buffers(int *newval, void **extra, GucSource source); +extern bool check_wal_consistency_checking(char **newval, void **extra, + GucSource source); +extern void assign_wal_consistency_checking(const char *newval, void *extra); +extern void assign_xlog_sync_method(int new_sync_method, void *extra); + +#endif /* GUC_HOOKS_H */ diff --git a/src/include/utils/guc_tables.h b/src/include/utils/guc_tables.h index 90565b9921..b3d2a959c3 100644 --- a/src/include/utils/guc_tables.h +++ b/src/include/utils/guc_tables.h @@ -263,6 +263,23 @@ extern PGDLLIMPORT const char *const config_type_names[]; extern PGDLLIMPORT const char *const GucContext_Names[]; extern PGDLLIMPORT const char *const GucSource_Names[]; +/* data arrays defining all the built-in GUC variables */ +extern PGDLLIMPORT struct config_bool ConfigureNamesBool[]; +extern PGDLLIMPORT struct config_int ConfigureNamesInt[]; +extern PGDLLIMPORT struct config_real ConfigureNamesReal[]; +extern PGDLLIMPORT struct config_string ConfigureNamesString[]; +extern PGDLLIMPORT struct config_enum ConfigureNamesEnum[]; + +/* lookup GUC variables, returning config_generic pointers */ +extern struct config_generic *find_option(const char *name, + bool create_placeholders, + bool skip_errors, + int elevel); +extern struct config_generic **get_explain_guc_options(int *num); + +/* get string value of variable */ +extern char *ShowGUCOption(struct config_generic *record, bool use_units); + /* get the current set of variables */ extern struct config_generic **get_guc_variables(void); @@ -272,6 +289,9 @@ extern void build_guc_variables(void); extern const char *config_enum_lookup_by_value(struct config_enum *record, int val); extern bool config_enum_lookup_by_name(struct config_enum *record, const char *value, int *retval); -extern struct config_generic **get_explain_guc_options(int *num); +extern char *config_enum_get_options(struct config_enum *record, + const char *prefix, + const char *suffix, + const char *separator); #endif /* GUC_TABLES_H */ diff --git a/src/include/utils/pg_locale.h b/src/include/utils/pg_locale.h index e7385faef8..a875942123 100644 --- a/src/include/utils/pg_locale.h +++ b/src/include/utils/pg_locale.h @@ -19,8 +19,6 @@ #include #endif -#include "utils/guc.h" - #ifdef USE_ICU /* * ucol_strcollUTF8() was introduced in ICU 50, but it is buggy before ICU 53. @@ -50,15 +48,6 @@ extern PGDLLIMPORT char *localized_abbrev_months[]; extern PGDLLIMPORT char *localized_full_months[]; -extern bool check_locale_messages(char **newval, void **extra, GucSource source); -extern void assign_locale_messages(const char *newval, void *extra); -extern bool check_locale_monetary(char **newval, void **extra, GucSource source); -extern void assign_locale_monetary(const char *newval, void *extra); -extern bool check_locale_numeric(char **newval, void **extra, GucSource source); -extern void assign_locale_numeric(const char *newval, void *extra); -extern bool check_locale_time(char **newval, void **extra, GucSource source); -extern void assign_locale_time(const char *newval, void *extra); - extern bool check_locale(int category, const char *locale, char **canonname); extern char *pg_perm_setlocale(int category, const char *locale); extern void check_strxfrm_bug(void); diff --git a/src/test/regress/regress.c b/src/test/regress/regress.c index 78dde97849..548afb4438 100644 --- a/src/test/regress/regress.c +++ b/src/test/regress/regress.c @@ -39,6 +39,7 @@ #include "parser/parse_coerce.h" #include "port/atomics.h" #include "storage/spin.h" +#include "utils/array.h" #include "utils/builtins.h" #include "utils/geo_decls.h" #include "utils/lsyscache.h"