Silence complaints about leaks in PlanCacheComputeResultDesc.

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
This commit is contained in:
Tom Lane 2025-08-02 19:44:10 -04:00
parent 7f6ededa76
commit b102c8c473

View 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;