*srcptr += 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
char *srcend;
Size len;
int i;
+ ErrorContextCallback error_context_callback;
/* See comment at can_skip_gucvar(). */
for (i = 0; i < num_guc_variables; i++)
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);
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)
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;
}
/*