Skip to content

Commit 7b9674a

Browse files
Allow resetting unknown custom GUCs with reserved prefixes.
Currently, ALTER DATABASE/ROLE/SYSTEM RESET [ALL] with an unknown custom GUC with a prefix reserved by MarkGUCPrefixReserved() errors (unless a superuser runs a RESET ALL variant). This is problematic for cases such as an extension library upgrade that removes a GUC. To fix, simply make sure the relevant code paths explicitly allow it. Note that we require superuser or privileges on the parameter to reset it. This is perhaps a bit more restrictive than is necessary, but it's not clear whether further relaxing the requirements is safe. Oversight in commit 8810356. The ALTER SYSTEM fix is dependent on commit 2d870b4, which first appeared in v17. Unfortunately, back-patching that commit would introduce ABI breakage, and while that breakage seems unlikely to bother anyone, it doesn't seem worth the risk. Hence, the ALTER SYSTEM part of this commit is omitted on v15 and v16. Reported-by: Mert Alev <mert@futo.org> Reviewed-by: Laurenz Albe <laurenz.albe@cybertec.at> Discussion: https://postgr.es/m/18964-ba09dea8c98fccd6%40postgresql.org Backpatch-through: 15
1 parent 6012189 commit 7b9674a

File tree

5 files changed

+64
-5
lines changed

5 files changed

+64
-5
lines changed

contrib/auto_explain/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ OBJS = \
66
auto_explain.o
77
PGFILEDESC = "auto_explain - logging facility for execution plans"
88

9+
REGRESS = alter_reset
10+
911
TAP_TESTS = 1
1012

1113
ifdef USE_PGXS
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
--
2+
-- This tests resetting unknown custom GUCs with reserved prefixes. There's
3+
-- nothing specific to auto_explain; this is just a convenient place to put
4+
-- this test.
5+
--
6+
SELECT current_database() AS datname \gset
7+
CREATE ROLE regress_ae_role;
8+
ALTER DATABASE :"datname" SET auto_explain.bogus = 1;
9+
ALTER ROLE regress_ae_role SET auto_explain.bogus = 1;
10+
ALTER ROLE regress_ae_role IN DATABASE :"datname" SET auto_explain.bogus = 1;
11+
ALTER SYSTEM SET auto_explain.bogus = 1;
12+
LOAD 'auto_explain';
13+
WARNING: invalid configuration parameter name "auto_explain.bogus", removing it
14+
DETAIL: "auto_explain" is now a reserved prefix.
15+
ALTER DATABASE :"datname" RESET auto_explain.bogus;
16+
ALTER ROLE regress_ae_role RESET auto_explain.bogus;
17+
ALTER ROLE regress_ae_role IN DATABASE :"datname" RESET auto_explain.bogus;
18+
ALTER SYSTEM RESET auto_explain.bogus;
19+
DROP ROLE regress_ae_role;

contrib/auto_explain/meson.build

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@ tests += {
2020
'name': 'auto_explain',
2121
'sd': meson.current_source_dir(),
2222
'bd': meson.current_build_dir(),
23+
'regress': {
24+
'sql': [
25+
'alter_reset',
26+
],
27+
},
2328
'tap': {
2429
'tests': [
2530
't/001_auto_explain.pl',
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
--
2+
-- This tests resetting unknown custom GUCs with reserved prefixes. There's
3+
-- nothing specific to auto_explain; this is just a convenient place to put
4+
-- this test.
5+
--
6+
7+
SELECT current_database() AS datname \gset
8+
CREATE ROLE regress_ae_role;
9+
10+
ALTER DATABASE :"datname" SET auto_explain.bogus = 1;
11+
ALTER ROLE regress_ae_role SET auto_explain.bogus = 1;
12+
ALTER ROLE regress_ae_role IN DATABASE :"datname" SET auto_explain.bogus = 1;
13+
ALTER SYSTEM SET auto_explain.bogus = 1;
14+
15+
LOAD 'auto_explain';
16+
17+
ALTER DATABASE :"datname" RESET auto_explain.bogus;
18+
ALTER ROLE regress_ae_role RESET auto_explain.bogus;
19+
ALTER ROLE regress_ae_role IN DATABASE :"datname" RESET auto_explain.bogus;
20+
ALTER SYSTEM RESET auto_explain.bogus;
21+
22+
DROP ROLE regress_ae_role;

src/backend/utils/misc/guc.c

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4722,8 +4722,13 @@ AlterSystemSetConfigFile(AlterSystemStmt *altersysstmt)
47224722
* the config file cannot cause postmaster start to fail, so we
47234723
* don't have to be too tense about possibly installing a bad
47244724
* value.)
4725+
*
4726+
* As an exception, we skip this check if this is a RESET command
4727+
* for an unknown custom GUC, else there'd be no way for users to
4728+
* remove such settings with reserved prefixes.
47254729
*/
4726-
(void) assignable_custom_variable_name(name, false, ERROR);
4730+
if (value || !valid_custom_variable_name(name))
4731+
(void) assignable_custom_variable_name(name, false, ERROR);
47274732
}
47284733

47294734
/*
@@ -6711,6 +6716,7 @@ validate_option_array_item(const char *name, const char *value,
67116716

67126717
{
67136718
struct config_generic *gconf;
6719+
bool reset_custom;
67146720

67156721
/*
67166722
* There are three cases to consider:
@@ -6729,16 +6735,21 @@ validate_option_array_item(const char *name, const char *value,
67296735
* it's assumed to be fully validated.)
67306736
*
67316737
* name is not known and can't be created as a placeholder. Throw error,
6732-
* unless skipIfNoPermissions is true, in which case return false.
6738+
* unless skipIfNoPermissions or reset_custom is true. If reset_custom is
6739+
* true, this is a RESET or RESET ALL operation for an unknown custom GUC
6740+
* with a reserved prefix, in which case we want to fall through to the
6741+
* placeholder case described in the preceding paragraph (else there'd be
6742+
* no way for users to remove them). Otherwise, return false.
67336743
*/
6734-
gconf = find_option(name, true, skipIfNoPermissions, ERROR);
6735-
if (!gconf)
6744+
reset_custom = (!value && valid_custom_variable_name(name));
6745+
gconf = find_option(name, true, skipIfNoPermissions || reset_custom, ERROR);
6746+
if (!gconf && !reset_custom)
67366747
{
67376748
/* not known, failed to make a placeholder */
67386749
return false;
67396750
}
67406751

6741-
if (gconf->flags & GUC_CUSTOM_PLACEHOLDER)
6752+
if (!gconf || gconf->flags & GUC_CUSTOM_PLACEHOLDER)
67426753
{
67436754
/*
67446755
* We cannot do any meaningful check on the value, so only permissions

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy