]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Silence complaints about leaks in PlanCacheComputeResultDesc.
authorTom Lane <tgl@sss.pgh.pa.us>
Sat, 2 Aug 2025 23:44:10 +0000 (19:44 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Sun, 3 Aug 2025 01:59:46 +0000 (21:59 -0400)
CompleteCachedPlan intentionally doesn't worry about small
leaks from PlanCacheComputeResultDesc.  However, Valgrind
knows nothing of engineering tradeoffs and complains anyway.
Silence it by doing things the hard way if USE_VALGRIND.

I don't really love this patch, because it makes the handling
of plansource->resultDesc different from the handling of query
dependencies and search_path just above, which likewise are willing
to accept small leaks into the cached plan's context.  However,
those cases aren't provoking Valgrind complaints.  (Perhaps in a
CLOBBER_CACHE_ALWAYS build, they would?)  For the moment, this
makes the src/pl/plpgsql tests leak-free according to Valgrind.

Author: Tom Lane <tgl@sss.pgh.pa.us>
Reviewed-by: Andres Freund <andres@anarazel.de>
Discussion: https://postgr.es/m/285483.1746756246@sss.pgh.pa.us

src/backend/utils/cache/plancache.c

index 0c506d320b137a74097b906ebb6eca2ce3ef2f10..6661d2c6b7391bd573d588b6d9a6c8646507ab5b 100644 (file)
@@ -463,8 +463,7 @@ CompleteCachedPlan(CachedPlanSource *plansource,
 
        /*
         * Save the final parameter types (or other parameter specification data)
-        * into the source_context, as well as our other parameters.  Also save
-        * the result tuple descriptor.
+        * into the source_context, as well as our other parameters.
         */
        MemoryContextSwitchTo(source_context);
 
@@ -480,9 +479,25 @@ CompleteCachedPlan(CachedPlanSource *plansource,
        plansource->parserSetupArg = parserSetupArg;
        plansource->cursor_options = cursor_options;
        plansource->fixed_result = fixed_result;
-       plansource->resultDesc = PlanCacheComputeResultDesc(querytree_list);
 
+       /*
+        * Also save the result tuple descriptor.  PlanCacheComputeResultDesc may
+        * leak some cruft; normally we just accept that to save a copy step, but
+        * in USE_VALGRIND mode be tidy by running it in the caller's context.
+        */
+#ifdef USE_VALGRIND
+       MemoryContextSwitchTo(oldcxt);
+       plansource->resultDesc = PlanCacheComputeResultDesc(querytree_list);
+       if (plansource->resultDesc)
+       {
+               MemoryContextSwitchTo(source_context);
+               plansource->resultDesc = CreateTupleDescCopy(plansource->resultDesc);
+               MemoryContextSwitchTo(oldcxt);
+       }
+#else
+       plansource->resultDesc = PlanCacheComputeResultDesc(querytree_list);
        MemoryContextSwitchTo(oldcxt);
+#endif
 
        plansource->is_complete = true;
        plansource->is_valid = true;