PQclear in ReportResultError to prevent memory leaks

pull/1109/head
Marco Slot 2017-01-10 02:18:01 +01:00
parent 31231ce196
commit ef326b202a
1 changed files with 47 additions and 34 deletions

View File

@ -125,46 +125,59 @@ ReportConnectionError(MultiConnection *connection, int elevel)
void void
ReportResultError(MultiConnection *connection, PGresult *result, int elevel) ReportResultError(MultiConnection *connection, PGresult *result, int elevel)
{ {
char *sqlStateString = PQresultErrorField(result, PG_DIAG_SQLSTATE); /* we release PQresult when throwing an error because the caller can't */
char *messagePrimary = PQresultErrorField(result, PG_DIAG_MESSAGE_PRIMARY); PG_TRY();
char *messageDetail = PQresultErrorField(result, PG_DIAG_MESSAGE_DETAIL);
char *messageHint = PQresultErrorField(result, PG_DIAG_MESSAGE_HINT);
char *messageContext = PQresultErrorField(result, PG_DIAG_CONTEXT);
char *nodeName = connection->hostname;
int nodePort = connection->port;
int sqlState = ERRCODE_INTERNAL_ERROR;
if (sqlStateString != NULL)
{ {
sqlState = MAKE_SQLSTATE(sqlStateString[0], sqlStateString[1], sqlStateString[2], char *sqlStateString = PQresultErrorField(result, PG_DIAG_SQLSTATE);
sqlStateString[3], sqlStateString[4]); char *messagePrimary = PQresultErrorField(result, PG_DIAG_MESSAGE_PRIMARY);
} char *messageDetail = PQresultErrorField(result, PG_DIAG_MESSAGE_DETAIL);
char *messageHint = PQresultErrorField(result, PG_DIAG_MESSAGE_HINT);
char *messageContext = PQresultErrorField(result, PG_DIAG_CONTEXT);
/* char *nodeName = connection->hostname;
* If the PGresult did not contain a message, the connection may provide a int nodePort = connection->port;
* suitable top level one. At worst, this is an empty string. int sqlState = ERRCODE_INTERNAL_ERROR;
*/
if (messagePrimary == NULL)
{
char *lastNewlineIndex = NULL;
messagePrimary = PQerrorMessage(connection->pgConn); if (sqlStateString != NULL)
lastNewlineIndex = strrchr(messagePrimary, '\n');
/* trim trailing newline, if any */
if (lastNewlineIndex != NULL)
{ {
*lastNewlineIndex = '\0'; sqlState = MAKE_SQLSTATE(sqlStateString[0],
sqlStateString[1],
sqlStateString[2],
sqlStateString[3],
sqlStateString[4]);
} }
}
ereport(elevel, (errcode(sqlState), errmsg("%s", messagePrimary), /*
messageDetail ? errdetail("%s", messageDetail) : 0, * If the PGresult did not contain a message, the connection may provide a
messageHint ? errhint("%s", messageHint) : 0, * suitable top level one. At worst, this is an empty string.
messageContext ? errcontext("%s", messageContext) : 0, */
errcontext("while executing command on %s:%d", if (messagePrimary == NULL)
nodeName, nodePort))); {
char *lastNewlineIndex = NULL;
messagePrimary = PQerrorMessage(connection->pgConn);
lastNewlineIndex = strrchr(messagePrimary, '\n');
/* trim trailing newline, if any */
if (lastNewlineIndex != NULL)
{
*lastNewlineIndex = '\0';
}
}
ereport(elevel, (errcode(sqlState), errmsg("%s", messagePrimary),
messageDetail ? errdetail("%s", messageDetail) : 0,
messageHint ? errhint("%s", messageHint) : 0,
messageContext ? errcontext("%s", messageContext) : 0,
errcontext("while executing command on %s:%d",
nodeName, nodePort)));
}
PG_CATCH();
{
PQclear(result);
PG_RE_THROW();
}
PG_END_TRY();
} }