mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-08-28 15:07:20 +02:00
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.
This commit is contained in:
parent
9dca62e9ff
commit
6e47c6cf7d
@ -1601,7 +1601,10 @@ FlushErrorState(void)
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
@ -1613,13 +1616,14 @@ ThrowErrorData(ErrorData *edata)
|
||||
|
||||
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);
|
||||
@ -1631,6 +1635,7 @@ ThrowErrorData(ErrorData *edata)
|
||||
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)
|
||||
@ -1641,11 +1646,15 @@ ThrowErrorData(ErrorData *edata)
|
||||
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);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user