static void assign_recovery_target_lsn(const char *newval, void *extra);
static bool check_primary_slot_name(char **newval, void **extra, GucSource source);
static bool check_default_with_oids(bool *newval, void **extra, GucSource source);
+static void check_reserved_prefixes(const char *varName);
+static List *reserved_class_prefix = NIL;
/* Private functions in guc-file.l that need to be called from guc.c */
static ConfigVariable *ProcessConfigFileInternal(GucContext context,
(superuser() ? PGC_SUSET : PGC_USERSET),
PGC_S_SESSION,
action, true, 0, false);
+ check_reserved_prefixes(stmt->name);
break;
case VAR_SET_MULTI:
(superuser() ? PGC_SUSET : PGC_USERSET),
PGC_S_SESSION,
action, true, 0, false);
+
+ check_reserved_prefixes(stmt->name);
break;
case VAR_RESET_ALL:
ResetAllOptions();
{
int classLen = strlen(className);
int i;
+ MemoryContext oldcontext;
for (i = 0; i < num_guc_variables; i++)
{
var->name)));
}
}
+
+ oldcontext = MemoryContextSwitchTo(TopMemoryContext);
+ reserved_class_prefix = lappend(reserved_class_prefix, pstrdup(className));
+ MemoryContextSwitchTo(oldcontext);
}
+/*
+ * Check a setting name against prefixes previously reserved by
+ * EmitWarningsOnPlaceholders() and throw a warning if matching.
+ */
+static void
+check_reserved_prefixes(const char *varName)
+{
+ char *sep = strchr(varName, GUC_QUALIFIER_SEPARATOR);
+
+ if (sep)
+ {
+ size_t classLen = sep - varName;
+ ListCell *lc;
+
+ foreach(lc, reserved_class_prefix)
+ {
+ char *rcprefix = lfirst(lc);
+
+ if (strncmp(varName, rcprefix, classLen) == 0)
+ {
+ for (int i = 0; i < num_guc_variables; i++)
+ {
+ struct config_generic *var = guc_variables[i];
+
+ if ((var->flags & GUC_CUSTOM_PLACEHOLDER) != 0 &&
+ strcmp(varName, var->name) == 0)
+ {
+ ereport(WARNING,
+ (errcode(ERRCODE_UNDEFINED_OBJECT),
+ errmsg("unrecognized configuration parameter \"%s\"", var->name),
+ errdetail("\"%.*s\" is a reserved prefix.", (int) classLen, var->name)));
+ }
+ }
+ }
+ }
+ }
+}
/*
* SHOW command
-- Should not allow to set it to true.
set default_with_oids to t;
ERROR: tables declared WITH OIDS are not supported
+-- test SET unrecognized parameter
+SET foo = false; -- no such setting
+ERROR: unrecognized configuration parameter "foo"
+-- test setting a parameter with a registered prefix (plpgsql)
+SET plpgsql.extra_foo_warnings = false; -- no such setting
+WARNING: unrecognized configuration parameter "plpgsql.extra_foo_warnings"
+DETAIL: "plpgsql" is a reserved prefix.
+SHOW plpgsql.extra_foo_warnings; -- but the parameter is set
+ plpgsql.extra_foo_warnings
+----------------------------
+ false
+(1 row)
+
+-- cleanup
+RESET foo;
+ERROR: unrecognized configuration parameter "foo"
+RESET plpgsql.extra_foo_warnings;
+WARNING: unrecognized configuration parameter "plpgsql.extra_foo_warnings"
+DETAIL: "plpgsql" is a reserved prefix.
set default_with_oids to f;
-- Should not allow to set it to true.
set default_with_oids to t;
+
+-- test SET unrecognized parameter
+SET foo = false; -- no such setting
+
+-- test setting a parameter with a registered prefix (plpgsql)
+SET plpgsql.extra_foo_warnings = false; -- no such setting
+SHOW plpgsql.extra_foo_warnings; -- but the parameter is set
+
+-- cleanup
+RESET foo;
+RESET plpgsql.extra_foo_warnings;