@@ -243,10 +243,6 @@ static void assign_recovery_target_lsn(const char *newval, void *extra);
243
243
static bool check_primary_slot_name (char * * newval , void * * extra , GucSource source );
244
244
static bool check_default_with_oids (bool * newval , void * * extra , GucSource source );
245
245
246
- /* Private functions in guc-file.l that need to be called from guc.c */
247
- static ConfigVariable * ProcessConfigFileInternal (GucContext context ,
248
- bool applySettings , int elevel );
249
-
250
246
/*
251
247
* Track whether there were any deferred checks for custom resource managers
252
248
* specified in wal_consistency_checking.
@@ -5160,8 +5156,8 @@ static bool report_needed; /* true if any GUC_REPORT reports are needed */
5160
5156
static int GUCNestLevel = 0 ; /* 1 when in main transaction */
5161
5157
5162
5158
5159
+ static struct config_generic * find_option (const char * name , bool create_placeholders , bool skip_errors , int elevel );
5163
5160
static int guc_var_compare (const void * a , const void * b );
5164
- static int guc_name_compare (const char * namea , const char * nameb );
5165
5161
static void InitializeGUCOptionsFromEnvironment (void );
5166
5162
static void InitializeOneGUCOption (struct config_generic * gconf );
5167
5163
static void push_old_value (struct config_generic * gconf , GucAction action );
@@ -5180,7 +5176,359 @@ static bool validate_option_array_item(const char *name, const char *value,
5180
5176
static void write_auto_conf_file (int fd , const char * filename , ConfigVariable * head_p );
5181
5177
static void replace_auto_config_value (ConfigVariable * * head_p , ConfigVariable * * tail_p ,
5182
5178
const char * name , const char * value );
5179
+ static bool valid_custom_variable_name (const char * name );
5180
+
5181
+ /*
5182
+ * This function handles both actual config file (re)loads and execution of
5183
+ * show_all_file_settings() (i.e., the pg_file_settings view). In the latter
5184
+ * case we don't apply any of the settings, but we make all the usual validity
5185
+ * checks, and we return the ConfigVariable list so that it can be printed out
5186
+ * by show_all_file_settings().
5187
+ */
5188
+ ConfigVariable *
5189
+ ProcessConfigFileInternal (GucContext context , bool applySettings , int elevel )
5190
+ {
5191
+ bool error = false;
5192
+ bool applying = false;
5193
+ const char * ConfFileWithError ;
5194
+ ConfigVariable * item ,
5195
+ * head ,
5196
+ * tail ;
5197
+ int i ;
5198
+
5199
+ /* Parse the main config file into a list of option names and values */
5200
+ ConfFileWithError = ConfigFileName ;
5201
+ head = tail = NULL ;
5202
+
5203
+ if (!ParseConfigFile (ConfigFileName , true,
5204
+ NULL , 0 , 0 , elevel ,
5205
+ & head , & tail ))
5206
+ {
5207
+ /* Syntax error(s) detected in the file, so bail out */
5208
+ error = true;
5209
+ goto bail_out ;
5210
+ }
5211
+
5212
+ /*
5213
+ * Parse the PG_AUTOCONF_FILENAME file, if present, after the main file to
5214
+ * replace any parameters set by ALTER SYSTEM command. Because this file
5215
+ * is in the data directory, we can't read it until the DataDir has been
5216
+ * set.
5217
+ */
5218
+ if (DataDir )
5219
+ {
5220
+ if (!ParseConfigFile (PG_AUTOCONF_FILENAME , false,
5221
+ NULL , 0 , 0 , elevel ,
5222
+ & head , & tail ))
5223
+ {
5224
+ /* Syntax error(s) detected in the file, so bail out */
5225
+ error = true;
5226
+ ConfFileWithError = PG_AUTOCONF_FILENAME ;
5227
+ goto bail_out ;
5228
+ }
5229
+ }
5230
+ else
5231
+ {
5232
+ /*
5233
+ * If DataDir is not set, the PG_AUTOCONF_FILENAME file cannot be
5234
+ * read. In this case, we don't want to accept any settings but
5235
+ * data_directory from postgresql.conf, because they might be
5236
+ * overwritten with settings in the PG_AUTOCONF_FILENAME file which
5237
+ * will be read later. OTOH, since data_directory isn't allowed in the
5238
+ * PG_AUTOCONF_FILENAME file, it will never be overwritten later.
5239
+ */
5240
+ ConfigVariable * newlist = NULL ;
5241
+
5242
+ /*
5243
+ * Prune all items except the last "data_directory" from the list.
5244
+ */
5245
+ for (item = head ; item ; item = item -> next )
5246
+ {
5247
+ if (!item -> ignore &&
5248
+ strcmp (item -> name , "data_directory" ) == 0 )
5249
+ newlist = item ;
5250
+ }
5183
5251
5252
+ if (newlist )
5253
+ newlist -> next = NULL ;
5254
+ head = tail = newlist ;
5255
+
5256
+ /*
5257
+ * Quick exit if data_directory is not present in file.
5258
+ *
5259
+ * We need not do any further processing, in particular we don't set
5260
+ * PgReloadTime; that will be set soon by subsequent full loading of
5261
+ * the config file.
5262
+ */
5263
+ if (head == NULL )
5264
+ goto bail_out ;
5265
+ }
5266
+
5267
+ /*
5268
+ * Mark all extant GUC variables as not present in the config file. We
5269
+ * need this so that we can tell below which ones have been removed from
5270
+ * the file since we last processed it.
5271
+ */
5272
+ for (i = 0 ; i < num_guc_variables ; i ++ )
5273
+ {
5274
+ struct config_generic * gconf = guc_variables [i ];
5275
+
5276
+ gconf -> status &= ~GUC_IS_IN_FILE ;
5277
+ }
5278
+
5279
+ /*
5280
+ * Check if all the supplied option names are valid, as an additional
5281
+ * quasi-syntactic check on the validity of the config file. It is
5282
+ * important that the postmaster and all backends agree on the results of
5283
+ * this phase, else we will have strange inconsistencies about which
5284
+ * processes accept a config file update and which don't. Hence, unknown
5285
+ * custom variable names have to be accepted without complaint. For the
5286
+ * same reason, we don't attempt to validate the options' values here.
5287
+ *
5288
+ * In addition, the GUC_IS_IN_FILE flag is set on each existing GUC
5289
+ * variable mentioned in the file; and we detect duplicate entries in the
5290
+ * file and mark the earlier occurrences as ignorable.
5291
+ */
5292
+ for (item = head ; item ; item = item -> next )
5293
+ {
5294
+ struct config_generic * record ;
5295
+
5296
+ /* Ignore anything already marked as ignorable */
5297
+ if (item -> ignore )
5298
+ continue ;
5299
+
5300
+ /*
5301
+ * Try to find the variable; but do not create a custom placeholder if
5302
+ * it's not there already.
5303
+ */
5304
+ record = find_option (item -> name , false, true, elevel );
5305
+
5306
+ if (record )
5307
+ {
5308
+ /* If it's already marked, then this is a duplicate entry */
5309
+ if (record -> status & GUC_IS_IN_FILE )
5310
+ {
5311
+ /*
5312
+ * Mark the earlier occurrence(s) as dead/ignorable. We could
5313
+ * avoid the O(N^2) behavior here with some additional state,
5314
+ * but it seems unlikely to be worth the trouble.
5315
+ */
5316
+ ConfigVariable * pitem ;
5317
+
5318
+ for (pitem = head ; pitem != item ; pitem = pitem -> next )
5319
+ {
5320
+ if (!pitem -> ignore &&
5321
+ strcmp (pitem -> name , item -> name ) == 0 )
5322
+ pitem -> ignore = true;
5323
+ }
5324
+ }
5325
+ /* Now mark it as present in file */
5326
+ record -> status |= GUC_IS_IN_FILE ;
5327
+ }
5328
+ else if (!valid_custom_variable_name (item -> name ))
5329
+ {
5330
+ /* Invalid non-custom variable, so complain */
5331
+ ereport (elevel ,
5332
+ (errcode (ERRCODE_UNDEFINED_OBJECT ),
5333
+ errmsg ("unrecognized configuration parameter \"%s\" in file \"%s\" line %d" ,
5334
+ item -> name ,
5335
+ item -> filename , item -> sourceline )));
5336
+ item -> errmsg = pstrdup ("unrecognized configuration parameter" );
5337
+ error = true;
5338
+ ConfFileWithError = item -> filename ;
5339
+ }
5340
+ }
5341
+
5342
+ /*
5343
+ * If we've detected any errors so far, we don't want to risk applying any
5344
+ * changes.
5345
+ */
5346
+ if (error )
5347
+ goto bail_out ;
5348
+
5349
+ /* Otherwise, set flag that we're beginning to apply changes */
5350
+ applying = true;
5351
+
5352
+ /*
5353
+ * Check for variables having been removed from the config file, and
5354
+ * revert their reset values (and perhaps also effective values) to the
5355
+ * boot-time defaults. If such a variable can't be changed after startup,
5356
+ * report that and continue.
5357
+ */
5358
+ for (i = 0 ; i < num_guc_variables ; i ++ )
5359
+ {
5360
+ struct config_generic * gconf = guc_variables [i ];
5361
+ GucStack * stack ;
5362
+
5363
+ if (gconf -> reset_source != PGC_S_FILE ||
5364
+ (gconf -> status & GUC_IS_IN_FILE ))
5365
+ continue ;
5366
+ if (gconf -> context < PGC_SIGHUP )
5367
+ {
5368
+ /* The removal can't be effective without a restart */
5369
+ gconf -> status |= GUC_PENDING_RESTART ;
5370
+ ereport (elevel ,
5371
+ (errcode (ERRCODE_CANT_CHANGE_RUNTIME_PARAM ),
5372
+ errmsg ("parameter \"%s\" cannot be changed without restarting the server" ,
5373
+ gconf -> name )));
5374
+ record_config_file_error (psprintf ("parameter \"%s\" cannot be changed without restarting the server" ,
5375
+ gconf -> name ),
5376
+ NULL , 0 ,
5377
+ & head , & tail );
5378
+ error = true;
5379
+ continue ;
5380
+ }
5381
+
5382
+ /* No more to do if we're just doing show_all_file_settings() */
5383
+ if (!applySettings )
5384
+ continue ;
5385
+
5386
+ /*
5387
+ * Reset any "file" sources to "default", else set_config_option will
5388
+ * not override those settings.
5389
+ */
5390
+ if (gconf -> reset_source == PGC_S_FILE )
5391
+ gconf -> reset_source = PGC_S_DEFAULT ;
5392
+ if (gconf -> source == PGC_S_FILE )
5393
+ gconf -> source = PGC_S_DEFAULT ;
5394
+ for (stack = gconf -> stack ; stack ; stack = stack -> prev )
5395
+ {
5396
+ if (stack -> source == PGC_S_FILE )
5397
+ stack -> source = PGC_S_DEFAULT ;
5398
+ }
5399
+
5400
+ /* Now we can re-apply the wired-in default (i.e., the boot_val) */
5401
+ if (set_config_option (gconf -> name , NULL ,
5402
+ context , PGC_S_DEFAULT ,
5403
+ GUC_ACTION_SET , true, 0 , false) > 0 )
5404
+ {
5405
+ /* Log the change if appropriate */
5406
+ if (context == PGC_SIGHUP )
5407
+ ereport (elevel ,
5408
+ (errmsg ("parameter \"%s\" removed from configuration file, reset to default" ,
5409
+ gconf -> name )));
5410
+ }
5411
+ }
5412
+
5413
+ /*
5414
+ * Restore any variables determined by environment variables or
5415
+ * dynamically-computed defaults. This is a no-op except in the case
5416
+ * where one of these had been in the config file and is now removed.
5417
+ *
5418
+ * In particular, we *must not* do this during the postmaster's initial
5419
+ * loading of the file, since the timezone functions in particular should
5420
+ * be run only after initialization is complete.
5421
+ *
5422
+ * XXX this is an unmaintainable crock, because we have to know how to set
5423
+ * (or at least what to call to set) every non-PGC_INTERNAL variable that
5424
+ * could potentially have PGC_S_DYNAMIC_DEFAULT or PGC_S_ENV_VAR source.
5425
+ */
5426
+ if (context == PGC_SIGHUP && applySettings )
5427
+ {
5428
+ InitializeGUCOptionsFromEnvironment ();
5429
+ pg_timezone_abbrev_initialize ();
5430
+ /* this selects SQL_ASCII in processes not connected to a database */
5431
+ SetConfigOption ("client_encoding" , GetDatabaseEncodingName (),
5432
+ PGC_BACKEND , PGC_S_DYNAMIC_DEFAULT );
5433
+ }
5434
+
5435
+ /*
5436
+ * Now apply the values from the config file.
5437
+ */
5438
+ for (item = head ; item ; item = item -> next )
5439
+ {
5440
+ char * pre_value = NULL ;
5441
+ int scres ;
5442
+
5443
+ /* Ignore anything marked as ignorable */
5444
+ if (item -> ignore )
5445
+ continue ;
5446
+
5447
+ /* In SIGHUP cases in the postmaster, we want to report changes */
5448
+ if (context == PGC_SIGHUP && applySettings && !IsUnderPostmaster )
5449
+ {
5450
+ const char * preval = GetConfigOption (item -> name , true, false);
5451
+
5452
+ /* If option doesn't exist yet or is NULL, treat as empty string */
5453
+ if (!preval )
5454
+ preval = "" ;
5455
+ /* must dup, else might have dangling pointer below */
5456
+ pre_value = pstrdup (preval );
5457
+ }
5458
+
5459
+ scres = set_config_option (item -> name , item -> value ,
5460
+ context , PGC_S_FILE ,
5461
+ GUC_ACTION_SET , applySettings , 0 , false);
5462
+ if (scres > 0 )
5463
+ {
5464
+ /* variable was updated, so log the change if appropriate */
5465
+ if (pre_value )
5466
+ {
5467
+ const char * post_value = GetConfigOption (item -> name , true, false);
5468
+
5469
+ if (!post_value )
5470
+ post_value = "" ;
5471
+ if (strcmp (pre_value , post_value ) != 0 )
5472
+ ereport (elevel ,
5473
+ (errmsg ("parameter \"%s\" changed to \"%s\"" ,
5474
+ item -> name , item -> value )));
5475
+ }
5476
+ item -> applied = true;
5477
+ }
5478
+ else if (scres == 0 )
5479
+ {
5480
+ error = true;
5481
+ item -> errmsg = pstrdup ("setting could not be applied" );
5482
+ ConfFileWithError = item -> filename ;
5483
+ }
5484
+ else
5485
+ {
5486
+ /* no error, but variable's active value was not changed */
5487
+ item -> applied = true;
5488
+ }
5489
+
5490
+ /*
5491
+ * We should update source location unless there was an error, since
5492
+ * even if the active value didn't change, the reset value might have.
5493
+ * (In the postmaster, there won't be a difference, but it does matter
5494
+ * in backends.)
5495
+ */
5496
+ if (scres != 0 && applySettings )
5497
+ set_config_sourcefile (item -> name , item -> filename ,
5498
+ item -> sourceline );
5499
+
5500
+ if (pre_value )
5501
+ pfree (pre_value );
5502
+ }
5503
+
5504
+ /* Remember when we last successfully loaded the config file. */
5505
+ if (applySettings )
5506
+ PgReloadTime = GetCurrentTimestamp ();
5507
+
5508
+ bail_out :
5509
+ if (error && applySettings )
5510
+ {
5511
+ /* During postmaster startup, any error is fatal */
5512
+ if (context == PGC_POSTMASTER )
5513
+ ereport (ERROR ,
5514
+ (errcode (ERRCODE_CONFIG_FILE_ERROR ),
5515
+ errmsg ("configuration file \"%s\" contains errors" ,
5516
+ ConfFileWithError )));
5517
+ else if (applying )
5518
+ ereport (elevel ,
5519
+ (errcode (ERRCODE_CONFIG_FILE_ERROR ),
5520
+ errmsg ("configuration file \"%s\" contains errors; unaffected changes were applied" ,
5521
+ ConfFileWithError )));
5522
+ else
5523
+ ereport (elevel ,
5524
+ (errcode (ERRCODE_CONFIG_FILE_ERROR ),
5525
+ errmsg ("configuration file \"%s\" contains errors; no changes were applied" ,
5526
+ ConfFileWithError )));
5527
+ }
5528
+
5529
+ /* Successful or otherwise, return the collected data list */
5530
+ return head ;
5531
+ }
5184
5532
5185
5533
/*
5186
5534
* Some infrastructure for checking malloc/strdup/realloc calls
@@ -5737,7 +6085,7 @@ guc_var_compare(const void *a, const void *b)
5737
6085
/*
5738
6086
* the bare comparison function for GUC names
5739
6087
*/
5740
- static int
6088
+ int
5741
6089
guc_name_compare (const char * namea , const char * nameb )
5742
6090
{
5743
6091
/*
0 commit comments