Clean up data conversion short-lived memory context.

dblink uses a short-lived data conversion memory context. However it
was not deleted when no longer needed, leading to a noticeable memory
leak under some circumstances. Plug the hole, along with minor
refactoring. Backpatch to 9.2 where the leak was introduced.

Report and initial patch by MauMau. Reviewed/modified slightly by
Tom Lane and me.
This commit is contained in:
Joe Conway 2014-06-20 12:22:13 -07:00
parent ecac0e2b9e
commit 1dde5782e3

View File

@ -977,6 +977,13 @@ materializeQueryResult(FunctionCallInfo fcinfo,
PG_TRY();
{
/* Create short-lived memory context for data conversions */
sinfo.tmpcontext = AllocSetContextCreate(CurrentMemoryContext,
"dblink temporary context",
ALLOCSET_DEFAULT_MINSIZE,
ALLOCSET_DEFAULT_INITSIZE,
ALLOCSET_DEFAULT_MAXSIZE);
/* execute query, collecting any tuples into the tuplestore */
res = storeQueryResult(&sinfo, conn, sql);
@ -1041,6 +1048,12 @@ materializeQueryResult(FunctionCallInfo fcinfo,
PQclear(res);
res = NULL;
}
/* clean up data conversion short-lived memory context */
if (sinfo.tmpcontext != NULL)
MemoryContextDelete(sinfo.tmpcontext);
sinfo.tmpcontext = NULL;
PQclear(sinfo.last_res);
sinfo.last_res = NULL;
PQclear(sinfo.cur_res);
@ -1204,15 +1217,6 @@ storeRow(storeInfo *sinfo, PGresult *res, bool first)
if (sinfo->cstrs)
pfree(sinfo->cstrs);
sinfo->cstrs = (char **) palloc(nfields * sizeof(char *));
/* Create short-lived memory context for data conversions */
if (!sinfo->tmpcontext)
sinfo->tmpcontext =
AllocSetContextCreate(CurrentMemoryContext,
"dblink temporary context",
ALLOCSET_DEFAULT_MINSIZE,
ALLOCSET_DEFAULT_INITSIZE,
ALLOCSET_DEFAULT_MAXSIZE);
}
/* Should have a single-row result if we get here */