aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2014-12-11 21:02:38 -0500
committerTom Lane <tgl@sss.pgh.pa.us>2014-12-11 21:02:38 -0500
commitbca39b5788ae94a37e827e5b51c69cf2cf331d05 (patch)
tree5209d6f9134be28751c3e5d9b6ac6b2145a83e22
parent21946ac9b61bbd3257449ce7ad511618e1a5d695 (diff)
downloadpostgresql-bca39b5788ae94a37e827e5b51c69cf2cf331d05.tar.gz
postgresql-bca39b5788ae94a37e827e5b51c69cf2cf331d05.zip
Fix planning of SELECT FOR UPDATE on child table with partial index.
Ordinarily we can omit checking of a WHERE condition that matches a partial index's condition, when we are using an indexscan on that partial index. However, in SELECT FOR UPDATE we must include the "redundant" filter condition in the plan so that it gets checked properly in an EvalPlanQual recheck. The planner got this mostly right, but improperly omitted the filter condition if the index in question was on an inheritance child table. In READ COMMITTED mode, this could result in incorrectly returning just-updated rows that no longer satisfy the filter condition. The cause of the error is using get_parse_rowmark() when get_plan_rowmark() is what should be used during planning. In 9.3 and up, also fix the same mistake in contrib/postgres_fdw. It's currently harmless there (for lack of inheritance support) but wrong is wrong, and the incorrect code might get copied to someplace where it's more significant. Report and fix by Kyotaro Horiguchi. Back-patch to all supported branches.
-rw-r--r--src/backend/optimizer/plan/createplan.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c
index 682217d1503..77cf33d1f79 100644
--- a/src/backend/optimizer/plan/createplan.c
+++ b/src/backend/optimizer/plan/createplan.c
@@ -31,6 +31,7 @@
#include "optimizer/plancat.h"
#include "optimizer/planmain.h"
#include "optimizer/predtest.h"
+#include "optimizer/prep.h"
#include "optimizer/restrictinfo.h"
#include "optimizer/subselect.h"
#include "optimizer/tlist.h"
@@ -1159,7 +1160,7 @@ create_indexscan_plan(PlannerInfo *root,
if (best_path->indexinfo->indpred)
{
if (baserelid != root->parse->resultRelation &&
- get_parse_rowmark(root->parse, baserelid) == NULL)
+ get_plan_rowmark(root->rowMarks, baserelid) == NULL)
if (predicate_implied_by(clausel,
best_path->indexinfo->indpred))
continue;