@@ -148,6 +148,8 @@ extern bool optimize_bounded_sort;
148
148
149
149
static int GUC_check_errcode_value ;
150
150
151
+ static List * reserved_class_prefix = NIL ;
152
+
151
153
/* global variables for check hook support */
152
154
char * GUC_check_errmsg_string ;
153
155
char * GUC_check_errdetail_string ;
@@ -235,8 +237,6 @@ static bool check_recovery_target_lsn(char **newval, void **extra, GucSource sou
235
237
static void assign_recovery_target_lsn (const char * newval , void * extra );
236
238
static bool check_primary_slot_name (char * * newval , void * * extra , GucSource source );
237
239
static 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 ;
240
240
241
241
/* Private functions in guc-file.l that need to be called from guc.c */
242
242
static ConfigVariable * ProcessConfigFileInternal (GucContext context ,
@@ -5569,18 +5569,44 @@ find_option(const char *name, bool create_placeholders, bool skip_errors,
5569
5569
* doesn't contain a separator, don't assume that it was meant to be a
5570
5570
* placeholder.
5571
5571
*/
5572
- if (strchr (name , GUC_QUALIFIER_SEPARATOR ) != NULL )
5572
+ const char * sep = strchr (name , GUC_QUALIFIER_SEPARATOR );
5573
+
5574
+ if (sep != NULL )
5573
5575
{
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 );
5584
5610
}
5585
5611
}
5586
5612
@@ -8764,7 +8790,6 @@ ExecSetVariableStmt(VariableSetStmt *stmt, bool isTopLevel)
8764
8790
(superuser () ? PGC_SUSET : PGC_USERSET ),
8765
8791
PGC_S_SESSION ,
8766
8792
action , true, 0 , false);
8767
- check_reserved_prefixes (stmt -> name );
8768
8793
break ;
8769
8794
case VAR_SET_MULTI :
8770
8795
@@ -8850,8 +8875,6 @@ ExecSetVariableStmt(VariableSetStmt *stmt, bool isTopLevel)
8850
8875
(superuser () ? PGC_SUSET : PGC_USERSET ),
8851
8876
PGC_S_SESSION ,
8852
8877
action , true, 0 , false);
8853
-
8854
- check_reserved_prefixes (stmt -> name );
8855
8878
break ;
8856
8879
case VAR_RESET_ALL :
8857
8880
ResetAllOptions ();
@@ -9345,8 +9368,9 @@ EmitWarningsOnPlaceholders(const char *className)
9345
9368
{
9346
9369
int classLen = strlen (className );
9347
9370
int i ;
9348
- MemoryContext oldcontext ;
9371
+ MemoryContext oldcontext ;
9349
9372
9373
+ /* Check for existing placeholders. */
9350
9374
for (i = 0 ; i < num_guc_variables ; i ++ )
9351
9375
{
9352
9376
struct config_generic * var = guc_variables [i ];
@@ -9362,48 +9386,12 @@ EmitWarningsOnPlaceholders(const char *className)
9362
9386
}
9363
9387
}
9364
9388
9389
+ /* And remember the name so we can prevent future mistakes. */
9365
9390
oldcontext = MemoryContextSwitchTo (TopMemoryContext );
9366
9391
reserved_class_prefix = lappend (reserved_class_prefix , pstrdup (className ));
9367
9392
MemoryContextSwitchTo (oldcontext );
9368
9393
}
9369
9394
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
- }
9407
9395
9408
9396
/*
9409
9397
* SHOW command
0 commit comments