Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 6e47c6c

Browse files
committed
Fix assorted small bugs in ThrowErrorData().
Copy the palloc'd strings into the correct context, ie ErrorContext not wherever the source ErrorData is. This would be a large bug, except that it appears that all catchers of thrown errors do either EmitErrorReport or CopyErrorData before doing anything that would cause transient memory contexts to be cleaned up. Still, it's wrong and it will bite somebody someday. Fix failure to copy cursorpos and internalpos. Utter the appropriate incantations involving recursion_depth, so that we'll behave sanely if we get an error inside pstrdup. (In general, the body of this function ought to act like, eg, errdetail().) Per code reading induced by Jakob Egger's report.
1 parent 9dca62e commit 6e47c6c

File tree

1 file changed

+14
-5
lines changed

1 file changed

+14
-5
lines changed

src/backend/utils/error/elog.c

+14-5
Original file line numberDiff line numberDiff line change
@@ -1601,7 +1601,10 @@ FlushErrorState(void)
16011601
/*
16021602
* ThrowErrorData --- report an error described by an ErrorData structure
16031603
*
1604-
* This is intended to be used to re-report errors originally thrown by
1604+
* This is somewhat like ReThrowError, but it allows elevels besides ERROR,
1605+
* and the boolean flags such as output_to_server are computed via the
1606+
* default rules rather than being copied from the given ErrorData.
1607+
* This is primarily used to re-report errors originally reported by
16051608
* background worker processes and then propagated (with or without
16061609
* modification) to the backend responsible for them.
16071610
*/
@@ -1613,13 +1616,14 @@ ThrowErrorData(ErrorData *edata)
16131616

16141617
if (!errstart(edata->elevel, edata->filename, edata->lineno,
16151618
edata->funcname, NULL))
1616-
return;
1619+
return; /* error is not to be reported at all */
16171620

16181621
newedata = &errordata[errordata_stack_depth];
1619-
oldcontext = MemoryContextSwitchTo(edata->assoc_context);
1622+
recursion_depth++;
1623+
oldcontext = MemoryContextSwitchTo(newedata->assoc_context);
16201624

1621-
/* Copy the supplied fields to the error stack. */
1622-
if (edata->sqlerrcode > 0)
1625+
/* Copy the supplied fields to the error stack entry. */
1626+
if (edata->sqlerrcode != 0)
16231627
newedata->sqlerrcode = edata->sqlerrcode;
16241628
if (edata->message)
16251629
newedata->message = pstrdup(edata->message);
@@ -1631,6 +1635,7 @@ ThrowErrorData(ErrorData *edata)
16311635
newedata->hint = pstrdup(edata->hint);
16321636
if (edata->context)
16331637
newedata->context = pstrdup(edata->context);
1638+
/* assume message_id is not available */
16341639
if (edata->schema_name)
16351640
newedata->schema_name = pstrdup(edata->schema_name);
16361641
if (edata->table_name)
@@ -1641,11 +1646,15 @@ ThrowErrorData(ErrorData *edata)
16411646
newedata->datatype_name = pstrdup(edata->datatype_name);
16421647
if (edata->constraint_name)
16431648
newedata->constraint_name = pstrdup(edata->constraint_name);
1649+
newedata->cursorpos = edata->cursorpos;
1650+
newedata->internalpos = edata->internalpos;
16441651
if (edata->internalquery)
16451652
newedata->internalquery = pstrdup(edata->internalquery);
16461653

16471654
MemoryContextSwitchTo(oldcontext);
1655+
recursion_depth--;
16481656

1657+
/* Process the error. */
16491658
errfinish(0);
16501659
}
16511660

0 commit comments

Comments
 (0)