From: Tom Lane Date: Mon, 26 Sep 2011 16:44:17 +0000 (-0400) Subject: Use a fresh copy of query_list when making a second plan in GetCachedPlan. X-Git-Tag: REL9_2_BETA1~1060 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=21fb95da46bce8de3e149707c680d489b8a5ffb0;p=postgresql Use a fresh copy of query_list when making a second plan in GetCachedPlan. The code path that tried a generic plan, didn't like it, and then made a custom plan was mistakenly passing the same copy of the query_list to the planner both times. This doesn't work too well for nontrivial queries, since the planner tends to scribble on its input. Diagnosis and fix by Yamamoto Takashi. --- diff --git a/src/backend/utils/cache/plancache.c b/src/backend/utils/cache/plancache.c index cfeb8245b8..56dace0e89 100644 --- a/src/backend/utils/cache/plancache.c +++ b/src/backend/utils/cache/plancache.c @@ -697,7 +697,8 @@ CheckCachedPlan(CachedPlanSource *plansource) /* * BuildCachedPlan: construct a new CachedPlan from a CachedPlanSource. * - * qlist should be the result value from a previous RevalidateCachedQuery. + * qlist should be the result value from a previous RevalidateCachedQuery, + * or it can be set to NIL if we need to re-copy the plansource's query_list. * * To build a generic, parameter-value-independent plan, pass NULL for * boundParams. To build a custom plan, pass the actual parameter values via @@ -980,6 +981,13 @@ GetCachedPlan(CachedPlanSource *plansource, ParamListInfo boundParams, * plan. */ customplan = choose_custom_plan(plansource, boundParams); + + /* + * If we choose to plan again, we need to re-copy the query_list, + * since the planner probably scribbled on it. We can force + * BuildCachedPlan to do that by passing NIL. + */ + qlist = NIL; } }