aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Munro <tmunro@postgresql.org>2019-10-17 13:24:50 +1300
committerThomas Munro <tmunro@postgresql.org>2019-10-17 14:00:15 +1300
commit3af7c64fe70c0b9d1072c660ddb1cb87dbe0a9d3 (patch)
tree65361acc0a7f09287b000c07f899054f48a44c9f
parent486a8f152233520b0c841d2e9c32b1ae7949e85c (diff)
downloadpostgresql-3af7c64fe70c0b9d1072c660ddb1cb87dbe0a9d3.tar.gz
postgresql-3af7c64fe70c0b9d1072c660ddb1cb87dbe0a9d3.zip
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
-rw-r--r--src/backend/utils/misc/guc.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index f0ed326a1b7..dc8f910ea46 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -10210,6 +10210,21 @@ read_gucstate_binary(char **srcptr, char *srcend, void *dest, Size size)
}
/*
+ * Callback used to add a context message when reporting errors that occur
+ * while trying to restore GUCs in parallel workers.
+ */
+static void
+guc_restore_error_context_callback(void *arg)
+{
+ char **error_context_name_and_value = (char **) arg;
+
+ if (error_context_name_and_value)
+ errcontext("while setting parameter \"%s\" to \"%s\"",
+ error_context_name_and_value[0],
+ error_context_name_and_value[1]);
+}
+
+/*
* RestoreGUCState:
* Reads the GUC state at the specified address and updates the GUCs with the
* values read from the GUC state.
@@ -10227,6 +10242,7 @@ RestoreGUCState(void *gucstate)
char *srcend;
Size len;
int i;
+ ErrorContextCallback error_context_callback;
/* See comment at can_skip_gucvar(). */
for (i = 0; i < num_guc_variables; i++)
@@ -10239,9 +10255,16 @@ RestoreGUCState(void *gucstate)
srcptr += sizeof(len);
srcend = srcptr + len;
+ /* If the GUC value check fails, we want errors to show useful context. */
+ error_context_callback.callback = guc_restore_error_context_callback;
+ error_context_callback.previous = error_context_stack;
+ error_context_callback.arg = NULL;
+ error_context_stack = &error_context_callback;
+
while (srcptr < srcend)
{
int result;
+ char *error_context_name_and_value[2];
varname = read_gucstate(&srcptr, srcend);
varvalue = read_gucstate(&srcptr, srcend);
@@ -10256,6 +10279,9 @@ RestoreGUCState(void *gucstate)
read_gucstate_binary(&srcptr, srcend,
&varscontext, sizeof(varscontext));
+ error_context_name_and_value[0] = varname;
+ error_context_name_and_value[1] = varvalue;
+ error_context_callback.arg = &error_context_name_and_value[0];
result = set_config_option(varname, varvalue, varscontext, varsource,
GUC_ACTION_SET, true, ERROR, true);
if (result <= 0)
@@ -10264,7 +10290,10 @@ RestoreGUCState(void *gucstate)
errmsg("parameter \"%s\" could not be set", varname)));
if (varsourcefile[0])
set_config_sourcefile(varname, varsourcefile, varsourceline);
+ error_context_callback.arg = NULL;
}
+
+ error_context_stack = error_context_callback.previous;
}
/*