summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--contrib/auto_explain/Makefile2
-rw-r--r--contrib/auto_explain/expected/alter_reset.out17
-rw-r--r--contrib/auto_explain/sql/alter_reset.sql20
-rw-r--r--src/backend/utils/misc/guc.c14
4 files changed, 49 insertions, 4 deletions
diff --git a/contrib/auto_explain/Makefile b/contrib/auto_explain/Makefile
index efd127d3cae..94ab28e7c06 100644
--- a/contrib/auto_explain/Makefile
+++ b/contrib/auto_explain/Makefile
@@ -6,6 +6,8 @@ OBJS = \
auto_explain.o
PGFILEDESC = "auto_explain - logging facility for execution plans"
+REGRESS = alter_reset
+
TAP_TESTS = 1
ifdef USE_PGXS
diff --git a/contrib/auto_explain/expected/alter_reset.out b/contrib/auto_explain/expected/alter_reset.out
new file mode 100644
index 00000000000..49317c76561
--- /dev/null
+++ b/contrib/auto_explain/expected/alter_reset.out
@@ -0,0 +1,17 @@
+--
+-- This tests resetting unknown custom GUCs with reserved prefixes. There's
+-- nothing specific to auto_explain; this is just a convenient place to put
+-- this test.
+--
+SELECT current_database() AS datname \gset
+CREATE ROLE regress_ae_role;
+ALTER DATABASE :"datname" SET auto_explain.bogus = 1;
+ALTER ROLE regress_ae_role SET auto_explain.bogus = 1;
+ALTER ROLE regress_ae_role IN DATABASE :"datname" SET auto_explain.bogus = 1;
+LOAD 'auto_explain';
+WARNING: invalid configuration parameter name "auto_explain.bogus", removing it
+DETAIL: "auto_explain" is now a reserved prefix.
+ALTER DATABASE :"datname" RESET auto_explain.bogus;
+ALTER ROLE regress_ae_role RESET auto_explain.bogus;
+ALTER ROLE regress_ae_role IN DATABASE :"datname" RESET auto_explain.bogus;
+DROP ROLE regress_ae_role;
diff --git a/contrib/auto_explain/sql/alter_reset.sql b/contrib/auto_explain/sql/alter_reset.sql
new file mode 100644
index 00000000000..3c472755d6a
--- /dev/null
+++ b/contrib/auto_explain/sql/alter_reset.sql
@@ -0,0 +1,20 @@
+--
+-- This tests resetting unknown custom GUCs with reserved prefixes. There's
+-- nothing specific to auto_explain; this is just a convenient place to put
+-- this test.
+--
+
+SELECT current_database() AS datname \gset
+CREATE ROLE regress_ae_role;
+
+ALTER DATABASE :"datname" SET auto_explain.bogus = 1;
+ALTER ROLE regress_ae_role SET auto_explain.bogus = 1;
+ALTER ROLE regress_ae_role IN DATABASE :"datname" SET auto_explain.bogus = 1;
+
+LOAD 'auto_explain';
+
+ALTER DATABASE :"datname" RESET auto_explain.bogus;
+ALTER ROLE regress_ae_role RESET auto_explain.bogus;
+ALTER ROLE regress_ae_role IN DATABASE :"datname" RESET auto_explain.bogus;
+
+DROP ROLE regress_ae_role;
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index e5600862d7f..abfc581171a 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -11821,6 +11821,7 @@ validate_option_array_item(const char *name, const char *value,
{
struct config_generic *gconf;
+ bool reset_custom;
/*
* There are three cases to consider:
@@ -11839,16 +11840,21 @@ validate_option_array_item(const char *name, const char *value,
* it's assumed to be fully validated.)
*
* name is not known and can't be created as a placeholder. Throw error,
- * unless skipIfNoPermissions is true, in which case return false.
+ * unless skipIfNoPermissions or reset_custom is true. If reset_custom is
+ * true, this is a RESET or RESET ALL operation for an unknown custom GUC
+ * with a reserved prefix, in which case we want to fall through to the
+ * placeholder case described in the preceding paragraph (else there'd be
+ * no way for users to remove them). Otherwise, return false.
*/
- gconf = find_option(name, true, skipIfNoPermissions, ERROR);
- if (!gconf)
+ reset_custom = (!value && valid_custom_variable_name(name));
+ gconf = find_option(name, true, skipIfNoPermissions || reset_custom, ERROR);
+ if (!gconf && !reset_custom)
{
/* not known, failed to make a placeholder */
return false;
}
- if (gconf->flags & GUC_CUSTOM_PLACEHOLDER)
+ if (!gconf || gconf->flags & GUC_CUSTOM_PLACEHOLDER)
{
/*
* We cannot do any meaningful check on the value, so only permissions