aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2011-09-26 12:44:17 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2011-09-26 12:44:17 -0400
commit21fb95da46bce8de3e149707c680d489b8a5ffb0 (patch)
treed8592e7c92adbe249d0e4478f31128026fbf7363
parent2a571bc233821023afdf8729a3ae5071b2343f65 (diff)
downloadpostgresql-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.c10
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;
}
}