mirror of https://github.com/citusdata/citus.git
PQclear in ReportResultError to prevent memory leaks
parent
31231ce196
commit
ef326b202a
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue