From 21fb95da46bce8de3e149707c680d489b8a5ffb0 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Mon, 26 Sep 2011 12:44:17 -0400 Subject: [PATCH] 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. --- src/backend/utils/cache/plancache.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) 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; } } -- 2.40.0