diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2011-09-26 12:44:17 -0400 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2011-09-26 12:44:17 -0400 |
commit | 21fb95da46bce8de3e149707c680d489b8a5ffb0 (patch) | |
tree | d8592e7c92adbe249d0e4478f31128026fbf7363 | |
parent | 2a571bc233821023afdf8729a3ae5071b2343f65 (diff) | |
download | postgresql-21fb95da46bce8de3e149707c680d489b8a5ffb0.tar.gz postgresql-21fb95da46bce8de3e149707c680d489b8a5ffb0.zip |
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.
-rw-r--r-- | src/backend/utils/cache/plancache.c | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/src/backend/utils/cache/plancache.c b/src/backend/utils/cache/plancache.c index cfeb8245b8c..56dace0e89c 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; } } |