aboutsummaryrefslogtreecommitdiff
path: root/src/backend/optimizer/plan/createplan.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2015-03-03 21:19:42 -0500
committerTom Lane <tgl@sss.pgh.pa.us>2015-03-03 21:19:42 -0500
commit497bac7d290df13d8b00ba48653a96015ff4741b (patch)
treec235b150d121248841f7747ee97e0022a8df7e4d /src/backend/optimizer/plan/createplan.c
parent5223ddacdc737b401ed58184e321f354bdf46686 (diff)
downloadpostgresql-497bac7d290df13d8b00ba48653a96015ff4741b.tar.gz
postgresql-497bac7d290df13d8b00ba48653a96015ff4741b.zip
Fix long-obsolete code for separating filter conditions in cost_index().
This code relied on pointer equality to identify which restriction clauses also appear in the indexquals (and, therefore, don't need to be applied as simple filter conditions). That was okay once upon a time, years ago, before we introduced the equivalence-class machinery. Now there's about a 50-50 chance that an equality clause appearing in the indexquals will be the mirror image (commutator) of its mate in the restriction list. When that happens, we'd erroneously think that the clause would be re-evaluated at each visited row, and therefore inflate the cost estimate for the indexscan by the clause's cost. Add some logic to catch this case. It seems to me that it continues not to be worthwhile to expend the extra predicate-proof work that createplan.c will do on the finally-selected plan, but this case is common enough and cheap enough to handle that we should do so. This will make a small difference (about one cpu_operator_cost per row) in simple cases; but in situations where there's an expensive function in the indexquals, it can make a very large difference, as seen in recent example from Jeff Janes. This is a long-standing bug, but I'm hesitant to back-patch because of the possibility of destabilizing plan choices that people may be happy with.
Diffstat (limited to 'src/backend/optimizer/plan/createplan.c')
-rw-r--r--src/backend/optimizer/plan/createplan.c3
1 files changed, 3 insertions, 0 deletions
diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c
index 76ba1bfa8d2..cb69c03df00 100644
--- a/src/backend/optimizer/plan/createplan.c
+++ b/src/backend/optimizer/plan/createplan.c
@@ -1210,6 +1210,9 @@ create_indexscan_plan(PlannerInfo *root,
* predicate, but only in a plain SELECT; when scanning a target relation
* of UPDATE/DELETE/SELECT FOR UPDATE, we must leave such quals in the
* plan so that they'll be properly rechecked by EvalPlanQual testing.
+ *
+ * Note: if you change this bit of code you should also look at
+ * extract_nonindex_conditions() in costsize.c.
*/
qpqual = NIL;
foreach(l, scan_clauses)