fix_alter_role_reset_v1.patch
text/plain
Filename: fix_alter_role_reset_v1.patch
Type: text/plain
Part: 0
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: unified
Series: patch v1
| File | + | − |
|---|---|---|
| src/backend/utils/misc/guc.c | 21 | 8 |
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 667df448732..ba1bf49e83c 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -250,7 +250,7 @@ static void reapply_stacked_values(struct config_generic *variable,
GucContext curscontext, GucSource cursource,
Oid cursrole);
static bool validate_option_array_item(const char *name, const char *value,
- bool skipIfNoPermissions);
+ bool skipIfNoPermissions, bool isReset);
static void write_auto_conf_file(int fd, const char *filename, ConfigVariable *head);
static void replace_auto_config_value(ConfigVariable **head_p, ConfigVariable **tail_p,
const char *name, const char *value);
@@ -6497,7 +6497,7 @@ GUCArrayAdd(ArrayType *array, const char *name, const char *value)
Assert(value);
/* test if the option is valid and we're allowed to set it */
- (void) validate_option_array_item(name, value, false);
+ (void) validate_option_array_item(name, value, false, false);
/* normalize name (converts obsolete GUC names to modern spellings) */
record = find_option(name, false, true, WARNING);
@@ -6574,7 +6574,7 @@ GUCArrayDelete(ArrayType *array, const char *name)
Assert(name);
/* test if the option is valid and we're allowed to set it */
- (void) validate_option_array_item(name, NULL, false);
+ (void) validate_option_array_item(name, NULL, false, true);
/* normalize name (converts obsolete GUC names to modern spellings) */
record = find_option(name, false, true, WARNING);
@@ -6672,7 +6672,7 @@ GUCArrayReset(ArrayType *array)
*eqsgn = '\0';
/* skip if we have permission to delete it */
- if (validate_option_array_item(val, NULL, true))
+ if (validate_option_array_item(val, NULL, true, true))
continue;
/* else add it to the output array */
@@ -6707,10 +6707,18 @@ GUCArrayReset(ArrayType *array)
*/
static bool
validate_option_array_item(const char *name, const char *value,
- bool skipIfNoPermissions)
+ bool skipIfNoPermissions, bool isReset)
{
struct config_generic *gconf;
+ bool skip_errors;
+
+ /*
+ * For RESET and RESET ALL, we treat unknown custom GUCs with reserved
+ * prefixes the same as if a placeholder is created. That requires we
+ * skip errors in find_option().
+ */
+ skip_errors = (isReset && valid_custom_variable_name(name));
/*
* There are three cases to consider:
@@ -6731,14 +6739,19 @@ validate_option_array_item(const char *name, const char *value,
* name is not known and can't be created as a placeholder. Throw error,
* unless skipIfNoPermissions is true, in which case return false.
*/
- gconf = find_option(name, true, skipIfNoPermissions, ERROR);
- if (!gconf)
+ gconf = find_option(name, true, skipIfNoPermissions || skip_errors, ERROR);
+ if (!gconf && !skip_errors)
{
/* not known, failed to make a placeholder */
return false;
}
- if (gconf->flags & GUC_CUSTOM_PLACEHOLDER)
+ /*
+ * If we reach this point and gconf is NULL, we know we're dealing with a
+ * RESET or RESET ALL command for an unknown custom GUC with a reserved
+ * prefix. We treat that the same as if a placeholder was created.
+ */
+ if (!gconf || gconf->flags & GUC_CUSTOM_PLACEHOLDER)
{
/*
* We cannot do any meaningful check on the value, so only permissions