* ReThrowError --- re-throw a previously copied error * * A handler can do CopyErrorData/FlushErrorState to get out of the error * subsystem, then do some processing, and finally ReThrowError to re-throw * the original error. This is slower than just PG_RE_THROW() but should * be used if the "some processing" is likely to incur another error. */
| 1999 | * be used if the "some processing" is likely to incur another error. |
| 2000 | */ |
| 2001 | void |
| 2002 | ReThrowError(ErrorData *edata) |
| 2003 | { |
| 2004 | ErrorData *newedata; |
| 2005 | |
| 2006 | Assert(edata->elevel <= ERROR); /* CDB: Ok to rethrow elog_demote'd error */ |
| 2007 | |
| 2008 | /* Push the data back into the error context */ |
| 2009 | recursion_depth++; |
| 2010 | MemoryContextSwitchTo(ErrorContext); |
| 2011 | |
| 2012 | if (++errordata_stack_depth >= ERRORDATA_STACK_SIZE) |
| 2013 | { |
| 2014 | /* |
| 2015 | * Wups, stack not big enough. We treat this as a PANIC condition |
| 2016 | * because it suggests an infinite loop of errors during error |
| 2017 | * recovery. Note that the message is intentionally not localized, |
| 2018 | * else failure to convert it to client encoding could cause further |
| 2019 | * recursion. |
| 2020 | */ |
| 2021 | errordata_stack_depth = -1; /* make room on stack */ |
| 2022 | ereport(PANIC, (errmsg_internal("ERRORDATA_STACK_SIZE exceeded"))); |
| 2023 | } |
| 2024 | |
| 2025 | newedata = &errordata[errordata_stack_depth]; |
| 2026 | memcpy(newedata, edata, sizeof(ErrorData)); |
| 2027 | |
| 2028 | /* Make copies of separately-allocated fields */ |
| 2029 | if (newedata->message) |
| 2030 | newedata->message = pstrdup(newedata->message); |
| 2031 | if (newedata->detail) |
| 2032 | newedata->detail = pstrdup(newedata->detail); |
| 2033 | if (newedata->detail_log) |
| 2034 | newedata->detail_log = pstrdup(newedata->detail_log); |
| 2035 | if (newedata->hint) |
| 2036 | newedata->hint = pstrdup(newedata->hint); |
| 2037 | if (newedata->context) |
| 2038 | newedata->context = pstrdup(newedata->context); |
| 2039 | if (newedata->backtrace) |
| 2040 | newedata->backtrace = pstrdup(newedata->backtrace); |
| 2041 | if (newedata->schema_name) |
| 2042 | newedata->schema_name = pstrdup(newedata->schema_name); |
| 2043 | if (newedata->table_name) |
| 2044 | newedata->table_name = pstrdup(newedata->table_name); |
| 2045 | if (newedata->column_name) |
| 2046 | newedata->column_name = pstrdup(newedata->column_name); |
| 2047 | if (newedata->datatype_name) |
| 2048 | newedata->datatype_name = pstrdup(newedata->datatype_name); |
| 2049 | if (newedata->constraint_name) |
| 2050 | newedata->constraint_name = pstrdup(newedata->constraint_name); |
| 2051 | if (newedata->internalquery) |
| 2052 | newedata->internalquery = pstrdup(newedata->internalquery); |
| 2053 | |
| 2054 | /* Reset the assoc_context to be ErrorContext */ |
| 2055 | newedata->assoc_context = ErrorContext; |
| 2056 | |
| 2057 | recursion_depth--; |
| 2058 | PG_RE_THROW(); |
no test coverage detected