Clean up data conversion short-lived memory context.
authorJoe Conway <mail@joeconway.com>
Fri, 20 Jun 2014 19:22:50 +0000 (12:22 -0700)
committerJoe Conway <mail@joeconway.com>
Fri, 20 Jun 2014 19:26:43 +0000 (12:26 -0700)
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.

contrib/dblink/dblink.c

index 4688a8d86bf0c599539c7eafd55487422073ed11..b216a7042c535f1d6fe152f35945b160722f6700 100644 (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 */