]> granicus.if.org Git - postgresql/commitdiff
Fix logic for adding "parallel worker" context line to worker errors.
authorTom Lane <tgl@sss.pgh.pa.us>
Fri, 26 Aug 2016 14:07:28 +0000 (10:07 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Fri, 26 Aug 2016 14:07:28 +0000 (10:07 -0400)
The previous coding here was capable of adding a "parallel worker" context
line to errors that were not, in fact, returned from a parallel worker.
Instead of using an errcontext callback to add that annotation, just paste
it onto the message by hand; this looks uglier but is more reliable.

Discussion: <19757.1472151987@sss.pgh.pa.us>

src/backend/access/transam/parallel.c

index a47eba647bcba5e5b8ce7841cf376e7921c369b3..ec6e1c5e6dc20844e5f8d9a463133b1a2ccd75b9 100644 (file)
@@ -108,7 +108,6 @@ static dlist_head pcxt_list = DLIST_STATIC_INIT(pcxt_list);
 
 /* Private functions. */
 static void HandleParallelMessage(ParallelContext *pcxt, int i, StringInfo msg);
-static void ParallelErrorContext(void *arg);
 static void ParallelExtensionTrampoline(dsm_segment *seg, shm_toc *toc);
 static void ParallelWorkerMain(Datum main_arg);
 static void WaitForParallelWorkersToExit(ParallelContext *pcxt);
@@ -788,30 +787,43 @@ HandleParallelMessage(ParallelContext *pcxt, int i, StringInfo msg)
                case 'N':                               /* NoticeResponse */
                        {
                                ErrorData       edata;
-                               ErrorContextCallback errctx;
                                ErrorContextCallback *save_error_context_stack;
 
-                               /*
-                                * Rethrow the error using the error context callbacks that
-                                * were in effect when the context was created, not the
-                                * current ones.
-                                */
-                               save_error_context_stack = error_context_stack;
-                               errctx.callback = ParallelErrorContext;
-                               errctx.arg = NULL;
-                               errctx.previous = pcxt->error_context_stack;
-                               error_context_stack = &errctx;
-
                                /* Parse ErrorResponse or NoticeResponse. */
                                pq_parse_errornotice(msg, &edata);
 
                                /* Death of a worker isn't enough justification for suicide. */
                                edata.elevel = Min(edata.elevel, ERROR);
 
-                               /* Rethrow error or notice. */
+                               /*
+                                * If desired, add a context line to show that this is a
+                                * message propagated from a parallel worker.  Otherwise, it
+                                * can sometimes be confusing to understand what actually
+                                * happened.  (We don't do this in FORCE_PARALLEL_REGRESS mode
+                                * because it causes test-result instability depending on
+                                * whether a parallel worker is actually used or not.)
+                                */
+                               if (force_parallel_mode != FORCE_PARALLEL_REGRESS)
+                               {
+                                       if (edata.context)
+                                               edata.context = psprintf("%s\n%s", edata.context,
+                                                                                                _("parallel worker"));
+                                       else
+                                               edata.context = pstrdup(_("parallel worker"));
+                               }
+
+                               /*
+                                * Context beyond that should use the error context callbacks
+                                * that were in effect when the ParallelContext was created,
+                                * not the current ones.
+                                */
+                               save_error_context_stack = error_context_stack;
+                               error_context_stack = pcxt->error_context_stack;
+
+                               /* Rethrow error or print notice. */
                                ThrowErrorData(&edata);
 
-                               /* Restore previous context. */
+                               /* Not an error, so restore previous context stack. */
                                error_context_stack = save_error_context_stack;
 
                                break;
@@ -1112,18 +1124,6 @@ ParallelExtensionTrampoline(dsm_segment *seg, shm_toc *toc)
        entrypt(seg, toc);
 }
 
-/*
- * Give the user a hint that this is a message propagated from a parallel
- * worker.  Otherwise, it can sometimes be confusing to understand what
- * actually happened.
- */
-static void
-ParallelErrorContext(void *arg)
-{
-       if (force_parallel_mode != FORCE_PARALLEL_REGRESS)
-               errcontext("parallel worker");
-}
-
 /*
  * Update shared memory with the ending location of the last WAL record we
  * wrote, if it's greater than the value already stored there.