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.
This commit is contained in:
Tom Lane 2011-09-26 12:44:17 -04:00
parent 2a571bc233
commit 21fb95da46

View File

@ -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;
}
}