/*
  * ThrowErrorData --- report an error described by an ErrorData structure
  *
- * This is intended to be used to re-report errors originally thrown by
+ * This is somewhat like ReThrowError, but it allows elevels besides ERROR,
+ * and the boolean flags such as output_to_server are computed via the
+ * default rules rather than being copied from the given ErrorData.
+ * This is primarily used to re-report errors originally reported by
  * background worker processes and then propagated (with or without
  * modification) to the backend responsible for them.
  */
 
        if (!errstart(edata->elevel, edata->filename, edata->lineno,
                                  edata->funcname, NULL))
-               return;
+               return;                                 /* error is not to be reported at all */
 
        newedata = &errordata[errordata_stack_depth];
-       oldcontext = MemoryContextSwitchTo(edata->assoc_context);
+       recursion_depth++;
+       oldcontext = MemoryContextSwitchTo(newedata->assoc_context);
 
-       /* Copy the supplied fields to the error stack. */
-       if (edata->sqlerrcode > 0)
+       /* Copy the supplied fields to the error stack entry. */
+       if (edata->sqlerrcode != 0)
                newedata->sqlerrcode = edata->sqlerrcode;
        if (edata->message)
                newedata->message = pstrdup(edata->message);
                newedata->hint = pstrdup(edata->hint);
        if (edata->context)
                newedata->context = pstrdup(edata->context);
+       /* assume message_id is not available */
        if (edata->schema_name)
                newedata->schema_name = pstrdup(edata->schema_name);
        if (edata->table_name)
                newedata->datatype_name = pstrdup(edata->datatype_name);
        if (edata->constraint_name)
                newedata->constraint_name = pstrdup(edata->constraint_name);
+       newedata->cursorpos = edata->cursorpos;
+       newedata->internalpos = edata->internalpos;
        if (edata->internalquery)
                newedata->internalquery = pstrdup(edata->internalquery);
 
        MemoryContextSwitchTo(oldcontext);
+       recursion_depth--;
 
+       /* Process the error. */
        errfinish(0);
 }