diff options
author | Robert Haas <rhaas@postgresql.org> | 2014-10-31 12:02:40 -0400 |
---|---|---|
committer | Robert Haas <rhaas@postgresql.org> | 2014-10-31 12:02:40 -0400 |
commit | 2bd9e412f92bc6a68f3e8bcb18e04955cc35001d (patch) | |
tree | 9a4a8dc45c5761aa0554d7f1ba255d5e599150b5 /src/backend/utils/error/elog.c | |
parent | 252e652edea80b948fbc9c3723183065e94d8480 (diff) |
Support frontend-backend protocol communication using a shm_mq.
A background worker can use pq_redirect_to_shm_mq() to direct protocol
that would normally be sent to the frontend to a shm_mq so that another
process may read them.
The receiving process may use pq_parse_errornotice() to parse an
ErrorResponse or NoticeResponse from the background worker and, if
it wishes, ThrowErrorData() to propagate the error (with or without
further modification).
Patch by me. Review by Andres Freund.
Diffstat (limited to 'src/backend/utils/error/elog.c')
-rw-r--r-- | src/backend/utils/error/elog.c | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/src/backend/utils/error/elog.c b/src/backend/utils/error/elog.c index 32a9663366d..23164648191 100644 --- a/src/backend/utils/error/elog.c +++ b/src/backend/utils/error/elog.c @@ -1577,6 +1577,57 @@ FlushErrorState(void) } /* + * ThrowErrorData --- report an error described by an ErrorData structure + * + * This is intended to be used to re-report errors originally thrown by + * background worker processes and then propagated (with or without + * modification) to the backend responsible for them. + */ +void +ThrowErrorData(ErrorData *edata) +{ + ErrorData *newedata; + MemoryContext oldcontext; + + if (!errstart(edata->elevel, edata->filename, edata->lineno, + edata->funcname, NULL)) + return; + + newedata = &errordata[errordata_stack_depth]; + oldcontext = MemoryContextSwitchTo(edata->assoc_context); + + /* Copy the supplied fields to the error stack. */ + if (edata->sqlerrcode > 0) + newedata->sqlerrcode = edata->sqlerrcode; + if (edata->message) + newedata->message = pstrdup(edata->message); + if (edata->detail) + newedata->detail = pstrdup(edata->detail); + if (edata->detail_log) + newedata->detail_log = pstrdup(edata->detail_log); + if (edata->hint) + newedata->hint = pstrdup(edata->hint); + if (edata->context) + newedata->context = pstrdup(edata->context); + if (edata->schema_name) + newedata->schema_name = pstrdup(edata->schema_name); + if (edata->table_name) + newedata->table_name = pstrdup(edata->table_name); + if (edata->column_name) + newedata->column_name = pstrdup(edata->column_name); + if (edata->datatype_name) + newedata->datatype_name = pstrdup(edata->datatype_name); + if (edata->constraint_name) + newedata->constraint_name = pstrdup(edata->constraint_name); + if (edata->internalquery) + newedata->internalquery = pstrdup(edata->internalquery); + + MemoryContextSwitchTo(oldcontext); + + errfinish(0); +} + +/* * ReThrowError --- re-throw a previously copied error * * A handler can do CopyErrorData/FlushErrorState to get out of the error |