Skip to content

Commit 89a3cdb

Browse files
committed
When restoring GUCs in parallel workers, show an error context.
Otherwise it can be hard to see where an error is coming from, when the parallel worker sets all the GUCs that it received from the leader. Bug #15726. Back-patch to 9.5, where RestoreGUCState() appeared. Reported-by: Tiago Anastacio Reviewed-by: Daniel Gustafsson, Tom Lane Discussion: https://postgr.es/m/15726-6d67e4fa14f027b3%40postgresql.org
1 parent 583d86f commit 89a3cdb

File tree

1 file changed

+29
-0
lines changed
  • src/backend/utils/misc

1 file changed

+29
-0
lines changed

src/backend/utils/misc/guc.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9348,6 +9348,21 @@ read_gucstate_binary(char **srcptr, char *srcend, void *dest, Size size)
93489348
*srcptr += size;
93499349
}
93509350

9351+
/*
9352+
* Callback used to add a context message when reporting errors that occur
9353+
* while trying to restore GUCs in parallel workers.
9354+
*/
9355+
static void
9356+
guc_restore_error_context_callback(void *arg)
9357+
{
9358+
char **error_context_name_and_value = (char **) arg;
9359+
9360+
if (error_context_name_and_value)
9361+
errcontext("while setting parameter \"%s\" to \"%s\"",
9362+
error_context_name_and_value[0],
9363+
error_context_name_and_value[1]);
9364+
}
9365+
93519366
/*
93529367
* RestoreGUCState:
93539368
* Reads the GUC state at the specified address and updates the GUCs with the
@@ -9366,6 +9381,7 @@ RestoreGUCState(void *gucstate)
93669381
char *srcend;
93679382
Size len;
93689383
int i;
9384+
ErrorContextCallback error_context_callback;
93699385

93709386
/* See comment at can_skip_gucvar(). */
93719387
for (i = 0; i < num_guc_variables; i++)
@@ -9378,9 +9394,16 @@ RestoreGUCState(void *gucstate)
93789394
srcptr += sizeof(len);
93799395
srcend = srcptr + len;
93809396

9397+
/* If the GUC value check fails, we want errors to show useful context. */
9398+
error_context_callback.callback = guc_restore_error_context_callback;
9399+
error_context_callback.previous = error_context_stack;
9400+
error_context_callback.arg = NULL;
9401+
error_context_stack = &error_context_callback;
9402+
93819403
while (srcptr < srcend)
93829404
{
93839405
int result;
9406+
char *error_context_name_and_value[2];
93849407

93859408
varname = read_gucstate(&srcptr, srcend);
93869409
varvalue = read_gucstate(&srcptr, srcend);
@@ -9393,6 +9416,9 @@ RestoreGUCState(void *gucstate)
93939416
read_gucstate_binary(&srcptr, srcend,
93949417
&varscontext, sizeof(varscontext));
93959418

9419+
error_context_name_and_value[0] = varname;
9420+
error_context_name_and_value[1] = varvalue;
9421+
error_context_callback.arg = &error_context_name_and_value[0];
93969422
result = set_config_option(varname, varvalue, varscontext, varsource,
93979423
GUC_ACTION_SET, true, ERROR, true);
93989424
if (result <= 0)
@@ -9401,7 +9427,10 @@ RestoreGUCState(void *gucstate)
94019427
errmsg("parameter \"%s\" could not be set", varname)));
94029428
if (varsourcefile[0])
94039429
set_config_sourcefile(varname, varsourcefile, varsourceline);
9430+
error_context_callback.arg = NULL;
94049431
}
9432+
9433+
error_context_stack = error_context_callback.previous;
94059434
}
94069435

94079436
/*

0 commit comments

Comments
 (0)