*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/optimizer/plan/createplan.c,v 1.208 2006/03/05 15:58:29 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/optimizer/plan/createplan.c,v 1.209 2006/04/25 16:54:09 tgl Exp $
*
*-------------------------------------------------------------------------
*/
* are not equal to, but are logically implied by, the index quals; so we
* also try a predicate_implied_by() check to see if we can discard quals
* that way. (predicate_implied_by assumes its first input contains only
- * immutable functions, so we have to check that.) We can also discard
- * quals that are implied by a partial index's predicate.
+ * immutable functions, so we have to check that.)
+ *
+ * We can also discard quals that are implied by a partial index's
+ * 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.
*
* While at it, we strip off the RestrictInfos to produce a list of plain
* expressions.
if (predicate_implied_by(clausel, nonlossy_indexquals))
continue;
- if (predicate_implied_by(clausel, best_path->indexinfo->indpred))
- continue;
+ if (best_path->indexinfo->indpred)
+ {
+ if (baserelid != root->parse->resultRelation &&
+ !list_member_int(root->parse->rowMarks, baserelid))
+ if (predicate_implied_by(clausel,
+ best_path->indexinfo->indpred))
+ continue;
+ }
}
qpqual = lappend(qpqual, rinfo->clause);
}
* but are logically implied by, the index quals; so we also try a
* predicate_implied_by() check to see if we can discard quals that way.
* (predicate_implied_by assumes its first input contains only immutable
- * functions, so we have to check that.) We can also discard quals that
- * are implied by a partial index's predicate.
+ * functions, so we have to check that.)
+ *
+ * We can also discard quals that are implied by a partial index's
+ * 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.
*
* XXX For the moment, we only consider partial index predicates in the
* simple single-index-scan case. Is it worth trying to be smart about
{
IndexPath *ipath = (IndexPath *) best_path->bitmapqual;
- if (predicate_implied_by(clausel, ipath->indexinfo->indpred))
- continue;
+ if (ipath->indexinfo->indpred)
+ {
+ if (baserelid != root->parse->resultRelation &&
+ !list_member_int(root->parse->rowMarks, baserelid))
+ if (predicate_implied_by(clausel,
+ ipath->indexinfo->indpred))
+ continue;
+ }
}
}
qpqual = lappend(qpqual, clause);
* join quals; failing to prove that doesn't result in an incorrect
* plan. It is the right way to proceed because adding more quals to
* the stuff we got from the original query would just make it harder
- * to detect duplication.
+ * to detect duplication. (Also, to change this we'd have to be
+ * wary of UPDATE/DELETE/SELECT FOR UPDATE target relations; see
+ * notes above about EvalPlanQual.)
*/
BitmapHeapPath *innerpath = (BitmapHeapPath *) best_path->innerjoinpath;