Add support to receive error HINTs from remote nodes and send it back to the
authorPavan Deolasee <[email protected]>
Thu, 2 Jul 2015 06:31:15 +0000 (12:01 +0530)
committerPavan Deolasee <[email protected]>
Thu, 2 Jul 2015 06:31:15 +0000 (12:01 +0530)
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

src/backend/pgxc/pool/execRemote.c
src/include/pgxc/execRemote.h

index beed69527c6fbf02a5cab0a6bd9368a407a061c7..d6c9e7176e7900d9836b37575c031db15f856172 100644 (file)
@@ -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)));
        }
 }
 
index d596f95efcfd485d5a0b67f9ff4bce77ae593b25..3f4d19e8589e6cedb1e1f44de81ebcfbbdd4d12e 100644 (file)
@@ -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 */