| 61 | gpopt_context.Free(gpopt_context.epinQuery, gpopt_context.epinPlStmt); |
| 62 | } |
| 63 | GPOS_CATCH_EX(ex) |
| 64 | { |
| 65 | // clone the error message before context free. |
| 66 | BOOL clone_failed = false; |
| 67 | CHAR *serialized_error_msg = |
| 68 | gpopt_context.CloneErrorMsg(MessageContext, &clone_failed); |
| 69 | // clean up context |
| 70 | gpopt_context.Free(gpopt_context.epinQuery, gpopt_context.epinPlStmt); |
| 71 | |
| 72 | // Special handler for a few common user-facing errors. In particular, |
| 73 | // we want to use the correct error code for these, in case an application |
| 74 | // tries to do something smart with them. |
| 75 | |
| 76 | if (clone_failed || GPOS_MATCH_EX(ex, gpdxl::ExmaGPDB, gpdxl::ExmiGPDBError)) |
| 77 | { |
| 78 | PG_RE_THROW(); |
| 79 | } |
| 80 | else if (GPOS_MATCH_EX(ex, CException::ExmaInvalid, |
| 81 | CException::ExmiORCAInvalidState)) |
| 82 | { |
| 83 | // The fallback logic below cannot be used because the current |
| 84 | // exception stack does not belong to the current QUERY. |
| 85 | if (errstart(LOG, TEXTDOMAIN)) |
| 86 | { |
| 87 | errcode(ERRCODE_INTERNAL_ERROR); |
| 88 | errmsg( |
| 89 | "Worker is already registered! This is an invalid state, please report this error. "); |
| 90 | errfinish(ex.Filename(), ex.Line(), nullptr); |
| 91 | } |
| 92 | GPOS_RESET_EX; |
| 93 | } |
| 94 | |
| 95 | // Failed to produce a plan, but it wasn't an error that should |
| 96 | // be propagated to the user. Log the failure if needed, and |
| 97 | // return without a plan. The caller should fall back to the |
| 98 | // Postgres planner. |
| 99 | |
| 100 | if (optimizer_trace_fallback) |
| 101 | { |
| 102 | if (errstart(INFO, TEXTDOMAIN)) |
| 103 | { |
| 104 | errcode(ERRCODE_FEATURE_NOT_SUPPORTED); |
| 105 | errmsg( |
| 106 | "GPORCA failed to produce a plan, falling back to Postgres-based planner"); |
| 107 | if (serialized_error_msg) |
| 108 | { |
| 109 | errdetail("%s", serialized_error_msg); |
| 110 | } |
| 111 | errfinish(ex.Filename(), ex.Line(), nullptr); |
| 112 | } |
| 113 | } |
| 114 | |
| 115 | *had_unexpected_failure = gpopt_context.m_is_unexpected_failure; |
| 116 | |
| 117 | if (serialized_error_msg) |
| 118 | { |
| 119 | pfree(serialized_error_msg); |
| 120 | } |