diff options
| author | Pavan Deolasee | 2015-07-02 06:31:15 +0000 |
|---|---|---|
| committer | Pavan Deolasee | 2015-07-02 06:31:15 +0000 |
| commit | b79758ce085042a7fbf29827bb8bf7acfbfb31f5 (patch) | |
| tree | f09b0382b7658d4e62a1bf06bb2254eeda46d378 | |
| parent | 75c9669618b609e17c226df2ad3d12375d074614 (diff) | |
Add support to receive error HINTs from remote nodes and send it back to the
client along with the error message
While we were collecting error and detail messages, the hints were lost during
coordinator-datanode communucation. So clients would not see these hints. Fix
that by tracking the hints received in the response combiner and sending them
back to the client along with the error message
| -rw-r--r-- | src/backend/pgxc/pool/execRemote.c | 78 | ||||
| -rw-r--r-- | src/include/pgxc/execRemote.h | 1 |
2 files changed, 31 insertions, 48 deletions
diff --git a/src/backend/pgxc/pool/execRemote.c b/src/backend/pgxc/pool/execRemote.c index beed69527c..d6c9e7176e 100644 --- a/src/backend/pgxc/pool/execRemote.c +++ b/src/backend/pgxc/pool/execRemote.c @@ -363,6 +363,7 @@ CreateResponseCombiner(int node_count, CombineType combine_type) combiner->copy_file = NULL; combiner->errorMessage = NULL; combiner->errorDetail = NULL; + combiner->errorHint = NULL; combiner->tuple_desc = NULL; #ifdef XCP combiner->probing_primary = false; @@ -987,6 +988,7 @@ HandleError(RemoteQueryState *combiner, char *msg_body, size_t len) char *code = NULL; char *message = NULL; char *detail = NULL; + char *hint = NULL; int offset = 0; /* @@ -1009,10 +1011,13 @@ HandleError(RemoteQueryState *combiner, char *msg_body, size_t len) detail = str; break; + case 'H': /* hint */ + hint = str; + break; + /* Fields not yet in use */ case 'S': /* severity */ case 'R': /* routine */ - case 'H': /* hint */ case 'P': /* position string */ case 'p': /* position int */ case 'q': /* int query */ @@ -1050,6 +1055,8 @@ HandleError(RemoteQueryState *combiner, char *msg_body, size_t len) memcpy(combiner->errorCode, code, 5); if (detail) combiner->errorDetail = pstrdup(detail); + if (hint) + combiner->errorHint = pstrdup(hint); } /* @@ -1245,6 +1252,8 @@ CloseCombiner(ResponseCombiner *combiner) pfree(combiner->errorMessage); if (combiner->errorDetail) pfree(combiner->errorDetail); + if (combiner->errorHint) + pfree(combiner->errorHint); if (combiner->cursor_connections) pfree(combiner->cursor_connections); if (combiner->tapenodes) @@ -4681,17 +4690,7 @@ DataNodeCopyFinish(PGXCNodeHandle** copy_connections, int primary_dn_index, Comb if (!validate_combiner(&combiner) || error) { if (combiner.errorMessage) - { - char *code = combiner.errorCode; - if (combiner.errorDetail) - ereport(ERROR, - (errcode(MAKE_SQLSTATE(code[0], code[1], code[2], code[3], code[4])), - errmsg("%s", combiner.errorMessage), errdetail("%s", combiner.errorDetail) )); - else - ereport(ERROR, - (errcode(MAKE_SQLSTATE(code[0], code[1], code[2], code[3], code[4])), - errmsg("%s", combiner.errorMessage))); - } + pgxc_node_report_error(&combiner); else ereport(ERROR, (errcode(ERRCODE_INTERNAL_ERROR), @@ -7571,17 +7570,7 @@ ExecRemoteQuery(RemoteQueryState *node) errmsg("Unexpected response from data node"))); } if (combiner->errorMessage) - { - char *code = combiner->errorCode; - if (combiner->errorDetail != NULL) - ereport(ERROR, - (errcode(MAKE_SQLSTATE(code[0], code[1], code[2], code[3], code[4])), - errmsg("%s", combiner->errorMessage), errdetail("%s", combiner->errorDetail) )); - else - ereport(ERROR, - (errcode(MAKE_SQLSTATE(code[0], code[1], code[2], code[3], code[4])), - errmsg("%s", combiner->errorMessage))); - } + pgxc_node_report_error(combiner); } for (i = 0; i < regular_conn_count; i++) @@ -7663,17 +7652,7 @@ ExecRemoteQuery(RemoteQueryState *node) } if (combiner->errorMessage) - { - char *code = combiner->errorCode; - if (combiner->errorDetail != NULL) - ereport(ERROR, - (errcode(MAKE_SQLSTATE(code[0], code[1], code[2], code[3], code[4])), - errmsg("%s", combiner->errorMessage), errdetail("%s", combiner->errorDetail) )); - else - ereport(ERROR, - (errcode(MAKE_SQLSTATE(code[0], code[1], code[2], code[3], code[4])), - errmsg("%s", combiner->errorMessage))); - } + pgxc_node_report_error(combiner); return NULL; } @@ -8975,17 +8954,8 @@ primary_mode_phase_two: goto primary_mode_phase_two; } if (combiner->errorMessage) - { - char *code = combiner->errorCode; - if (combiner->errorDetail) - ereport(ERROR, - (errcode(MAKE_SQLSTATE(code[0], code[1], code[2], code[3], code[4])), - errmsg("%s", combiner->errorMessage), errdetail("%s", combiner->errorDetail) )); - else - ereport(ERROR, - (errcode(MAKE_SQLSTATE(code[0], code[1], code[2], code[3], code[4])), - errmsg("%s", combiner->errorMessage))); - } + pgxc_node_report_error(combiner); + return NULL; } @@ -9227,14 +9197,26 @@ pgxc_node_report_error(RemoteQueryState *combiner) if (combiner->errorMessage) { char *code = combiner->errorCode; - if (combiner->errorDetail != NULL) + if ((combiner->errorDetail == NULL) && (combiner->errorHint == NULL)) + ereport(ERROR, + (errcode(MAKE_SQLSTATE(code[0], code[1], code[2], code[3], code[4])), + errmsg("%s", combiner->errorMessage))); + else if ((combiner->errorDetail != NULL) && (combiner->errorHint != NULL)) + ereport(ERROR, + (errcode(MAKE_SQLSTATE(code[0], code[1], code[2], code[3], code[4])), + errmsg("%s", combiner->errorMessage), + errdetail("%s", combiner->errorDetail), + errhint("%s", combiner->errorHint))); + else if (combiner->errorDetail != NULL) ereport(ERROR, (errcode(MAKE_SQLSTATE(code[0], code[1], code[2], code[3], code[4])), - errmsg("%s", combiner->errorMessage), errdetail("%s", combiner->errorDetail) )); + errmsg("%s", combiner->errorMessage), + errdetail("%s", combiner->errorDetail))); else ereport(ERROR, (errcode(MAKE_SQLSTATE(code[0], code[1], code[2], code[3], code[4])), - errmsg("%s", combiner->errorMessage))); + errmsg("%s", combiner->errorMessage), + errhint("%s", combiner->errorHint))); } } diff --git a/src/include/pgxc/execRemote.h b/src/include/pgxc/execRemote.h index d596f95efc..3f4d19e858 100644 --- a/src/include/pgxc/execRemote.h +++ b/src/include/pgxc/execRemote.h @@ -127,6 +127,7 @@ typedef struct RemoteQueryState char errorCode[5]; /* error code to send back to client */ char *errorMessage; /* error message to send back to client */ char *errorDetail; /* error detail to send back to client */ + char *errorHint; /* error hint to send back to client */ #ifdef XCP Oid returning_node; /* returning replicated node */ RemoteDataRow currentRow; /* next data ro to be wrapped into a tuple */ |
