aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands/variable.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2022-09-13 11:05:07 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2022-09-13 11:11:45 -0400
commit0a20ff54f5e66158930d5328f89f087d4e9ab400 (patch)
tree061094ad7638e0d0be3fe007f29ed31710a75cec /src/backend/commands/variable.c
parent257eb57b50f7c65467bfc2f4d579622fa13f3370 (diff)
downloadpostgresql-0a20ff54f5e66158930d5328f89f087d4e9ab400.tar.gz
postgresql-0a20ff54f5e66158930d5328f89f087d4e9ab400.zip
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
Diffstat (limited to 'src/backend/commands/variable.c')
-rw-r--r--src/backend/commands/variable.c271
1 files changed, 269 insertions, 2 deletions
diff --git a/src/backend/commands/variable.c b/src/backend/commands/variable.c
index e5ddcda0b4a..c795cb7a29c 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"
/*
@@ -467,6 +475,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
*
* We allow idempotent changes (r/w -> r/w and r/o -> r/o) at any time, and
@@ -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;
+}