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
This commit is contained in:
Tom Lane 2022-09-13 11:05:07 -04:00
parent 257eb57b50
commit 0a20ff54f5
59 changed files with 7466 additions and 7128 deletions

View File

@ -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"

View File

@ -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);

View File

@ -10,6 +10,7 @@
#include <ctype.h>
#include "ltree.h"
#include "utils/array.h"
PG_FUNCTION_INFO_V1(_ltree_isparent);
PG_FUNCTION_INFO_V1(_ltree_r_isparent);

View File

@ -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);

View File

@ -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 )

View File

@ -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;

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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.
*

View File

@ -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"
/*

View File

@ -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, &timestamp) != 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;
}

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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()
*/

View File

@ -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;
}

View File

@ -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.
*/

View File

@ -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"

View File

@ -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.
*

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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"

View File

@ -15,6 +15,7 @@
*/
#include "postgres.h"
#include "nodes/parsenodes.h"
#include "utils/builtins.h"
#include "parser/scansup.h"

View File

@ -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 */

View File

@ -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 */

View File

@ -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

View File

@ -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
*

View File

@ -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 */

View File

@ -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,

View File

@ -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

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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;

View File

@ -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

View File

@ -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.

View File

@ -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 \

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -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 */

View File

@ -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.
*/

View File

@ -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 */

View File

@ -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

View File

@ -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);

View File

@ -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 */

View File

@ -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

View File

@ -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 <peter_e@gmx.net>.
@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -19,8 +19,6 @@
#include <unicode/ucol.h>
#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);

View File

@ -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"