@@ -148,6 +148,8 @@ extern bool optimize_bounded_sort;
148148
149149static int GUC_check_errcode_value ;
150150
151+ static List * reserved_class_prefix = NIL ;
152+
151153/* global variables for check hook support */
152154char * GUC_check_errmsg_string ;
153155char * GUC_check_errdetail_string ;
@@ -235,8 +237,6 @@ static bool check_recovery_target_lsn(char **newval, void **extra, GucSource sou
235237static void assign_recovery_target_lsn (const char * newval , void * extra );
236238static bool check_primary_slot_name (char * * newval , void * * extra , GucSource source );
237239static bool check_default_with_oids (bool * newval , void * * extra , GucSource source );
238- static void check_reserved_prefixes (const char * varName );
239- static List * reserved_class_prefix = NIL ;
240240
241241/* Private functions in guc-file.l that need to be called from guc.c */
242242static ConfigVariable * ProcessConfigFileInternal (GucContext context ,
@@ -5569,18 +5569,44 @@ find_option(const char *name, bool create_placeholders, bool skip_errors,
55695569 * doesn't contain a separator, don't assume that it was meant to be a
55705570 * placeholder.
55715571 */
5572- if (strchr (name , GUC_QUALIFIER_SEPARATOR ) != NULL )
5572+ const char * sep = strchr (name , GUC_QUALIFIER_SEPARATOR );
5573+
5574+ if (sep != NULL )
55735575 {
5574- if (valid_custom_variable_name (name ))
5575- return add_placeholder_variable (name , elevel );
5576- /* A special error message seems desirable here */
5577- if (!skip_errors )
5578- ereport (elevel ,
5579- (errcode (ERRCODE_INVALID_NAME ),
5580- errmsg ("invalid configuration parameter name \"%s\"" ,
5581- name ),
5582- errdetail ("Custom parameter names must be two or more simple identifiers separated by dots." )));
5583- return NULL ;
5576+ size_t classLen = sep - name ;
5577+ ListCell * lc ;
5578+
5579+ /* The name must be syntactically acceptable ... */
5580+ if (!valid_custom_variable_name (name ))
5581+ {
5582+ if (!skip_errors )
5583+ ereport (elevel ,
5584+ (errcode (ERRCODE_INVALID_NAME ),
5585+ errmsg ("invalid configuration parameter name \"%s\"" ,
5586+ name ),
5587+ errdetail ("Custom parameter names must be two or more simple identifiers separated by dots." )));
5588+ return NULL ;
5589+ }
5590+ /* ... and it must not match any previously-reserved prefix */
5591+ foreach (lc , reserved_class_prefix )
5592+ {
5593+ const char * rcprefix = lfirst (lc );
5594+
5595+ if (strlen (rcprefix ) == classLen &&
5596+ strncmp (name , rcprefix , classLen ) == 0 )
5597+ {
5598+ if (!skip_errors )
5599+ ereport (elevel ,
5600+ (errcode (ERRCODE_INVALID_NAME ),
5601+ errmsg ("invalid configuration parameter name \"%s\"" ,
5602+ name ),
5603+ errdetail ("\"%s\" is a reserved prefix." ,
5604+ rcprefix )));
5605+ return NULL ;
5606+ }
5607+ }
5608+ /* OK, create it */
5609+ return add_placeholder_variable (name , elevel );
55845610 }
55855611 }
55865612
@@ -8764,7 +8790,6 @@ ExecSetVariableStmt(VariableSetStmt *stmt, bool isTopLevel)
87648790 (superuser () ? PGC_SUSET : PGC_USERSET ),
87658791 PGC_S_SESSION ,
87668792 action , true, 0 , false);
8767- check_reserved_prefixes (stmt -> name );
87688793 break ;
87698794 case VAR_SET_MULTI :
87708795
@@ -8850,8 +8875,6 @@ ExecSetVariableStmt(VariableSetStmt *stmt, bool isTopLevel)
88508875 (superuser () ? PGC_SUSET : PGC_USERSET ),
88518876 PGC_S_SESSION ,
88528877 action , true, 0 , false);
8853-
8854- check_reserved_prefixes (stmt -> name );
88558878 break ;
88568879 case VAR_RESET_ALL :
88578880 ResetAllOptions ();
@@ -9345,8 +9368,9 @@ EmitWarningsOnPlaceholders(const char *className)
93459368{
93469369 int classLen = strlen (className );
93479370 int i ;
9348- MemoryContext oldcontext ;
9371+ MemoryContext oldcontext ;
93499372
9373+ /* Check for existing placeholders. */
93509374 for (i = 0 ; i < num_guc_variables ; i ++ )
93519375 {
93529376 struct config_generic * var = guc_variables [i ];
@@ -9362,48 +9386,12 @@ EmitWarningsOnPlaceholders(const char *className)
93629386 }
93639387 }
93649388
9389+ /* And remember the name so we can prevent future mistakes. */
93659390 oldcontext = MemoryContextSwitchTo (TopMemoryContext );
93669391 reserved_class_prefix = lappend (reserved_class_prefix , pstrdup (className ));
93679392 MemoryContextSwitchTo (oldcontext );
93689393}
93699394
9370- /*
9371- * Check a setting name against prefixes previously reserved by
9372- * EmitWarningsOnPlaceholders() and throw a warning if matching.
9373- */
9374- static void
9375- check_reserved_prefixes (const char * varName )
9376- {
9377- char * sep = strchr (varName , GUC_QUALIFIER_SEPARATOR );
9378-
9379- if (sep )
9380- {
9381- size_t classLen = sep - varName ;
9382- ListCell * lc ;
9383-
9384- foreach (lc , reserved_class_prefix )
9385- {
9386- char * rcprefix = lfirst (lc );
9387-
9388- if (strncmp (varName , rcprefix , classLen ) == 0 )
9389- {
9390- for (int i = 0 ; i < num_guc_variables ; i ++ )
9391- {
9392- struct config_generic * var = guc_variables [i ];
9393-
9394- if ((var -> flags & GUC_CUSTOM_PLACEHOLDER ) != 0 &&
9395- strcmp (varName , var -> name ) == 0 )
9396- {
9397- ereport (WARNING ,
9398- (errcode (ERRCODE_UNDEFINED_OBJECT ),
9399- errmsg ("unrecognized configuration parameter \"%s\"" , var -> name ),
9400- errdetail ("\"%.*s\" is a reserved prefix." , (int ) classLen , var -> name )));
9401- }
9402- }
9403- }
9404- }
9405- }
9406- }
94079395
94089396/*
94099397 * SHOW command
0 commit comments