Skip to content

Commit 9a9e530

Browse files
committed
Fix another oversight in logging of changes in postgresql.conf settings.
We were using GetConfigOption to collect the old value of each setting, overlooking the possibility that it didn't exist yet. This does happen in the case of adding a new entry within a custom variable class, as exhibited in bug #6097 from Maxim Boguk. To fix, add a missing_ok parameter to GetConfigOption, but only in 9.1 and HEAD --- it seems possible that some third-party code is using that function, so changing its API in a minor release would cause problems. In 9.0, create a near-duplicate function instead.
1 parent d1ca2a1 commit 9a9e530

File tree

3 files changed

+44
-3
lines changed

3 files changed

+44
-3
lines changed

src/backend/utils/misc/guc-file.l

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -317,9 +317,9 @@ ProcessConfigFile(GucContext context)
317317
/* In SIGHUP cases in the postmaster, report changes */
318318
if (context == PGC_SIGHUP && !IsUnderPostmaster)
319319
{
320-
const char *preval = GetConfigOption(item->name, false);
320+
const char *preval = GetConfigOptionNoError(item->name);
321321

322-
/* string variables could be NULL; treat that as empty */
322+
/* If option doesn't exist yet or is NULL, treat as empty string */
323323
if (!preval)
324324
preval = "";
325325
/* must dup, else might have dangling pointer below */
@@ -334,7 +334,7 @@ ProcessConfigFile(GucContext context)
334334

335335
if (pre_value)
336336
{
337-
const char *post_value = GetConfigOption(item->name, false);
337+
const char *post_value = GetConfigOptionNoError(item->name);
338338

339339
if (!post_value)
340340
post_value = "";

src/backend/utils/misc/guc.c

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5391,6 +5391,46 @@ GetConfigOption(const char *name, bool restrict_superuser)
53915391
return NULL;
53925392
}
53935393

5394+
/*
5395+
* As above, but return NULL if no such option.
5396+
* (This is a stopgap to avoid changing GetConfigOption's API within the
5397+
* 9.0.x release series.)
5398+
*/
5399+
const char *
5400+
GetConfigOptionNoError(const char *name)
5401+
{
5402+
struct config_generic *record;
5403+
static char buffer[256];
5404+
5405+
record = find_option(name, false, ERROR);
5406+
if (record == NULL)
5407+
return NULL;
5408+
5409+
switch (record->vartype)
5410+
{
5411+
case PGC_BOOL:
5412+
return *((struct config_bool *) record)->variable ? "on" : "off";
5413+
5414+
case PGC_INT:
5415+
snprintf(buffer, sizeof(buffer), "%d",
5416+
*((struct config_int *) record)->variable);
5417+
return buffer;
5418+
5419+
case PGC_REAL:
5420+
snprintf(buffer, sizeof(buffer), "%g",
5421+
*((struct config_real *) record)->variable);
5422+
return buffer;
5423+
5424+
case PGC_STRING:
5425+
return *((struct config_string *) record)->variable;
5426+
5427+
case PGC_ENUM:
5428+
return config_enum_lookup_by_value((struct config_enum *) record,
5429+
*((struct config_enum *) record)->variable);
5430+
}
5431+
return NULL;
5432+
}
5433+
53945434
/*
53955435
* Get the RESET value associated with the given option.
53965436
*

src/include/utils/guc.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,7 @@ extern void DefineCustomEnumVariable(
253253
extern void EmitWarningsOnPlaceholders(const char *className);
254254

255255
extern const char *GetConfigOption(const char *name, bool restrict_superuser);
256+
extern const char *GetConfigOptionNoError(const char *name);
256257
extern const char *GetConfigOptionResetString(const char *name);
257258
extern void ProcessConfigFile(GucContext context);
258259
extern void InitializeGUCOptions(void);

0 commit comments

Comments
 (0)