1010 *
1111 *
1212 * IDENTIFICATION
13- * $PostgreSQL: pgsql/src/backend/optimizer/plan/createplan.c,v 1.208 2006/03/05 15:58:29 momjian Exp $
13+ * $PostgreSQL: pgsql/src/backend/optimizer/plan/createplan.c,v 1.209 2006/04/25 16:54:09 tgl Exp $
1414 *
1515 *-------------------------------------------------------------------------
1616 */
@@ -816,8 +816,12 @@ create_indexscan_plan(PlannerInfo *root,
816816 * are not equal to, but are logically implied by, the index quals; so we
817817 * also try a predicate_implied_by() check to see if we can discard quals
818818 * that way. (predicate_implied_by assumes its first input contains only
819- * immutable functions, so we have to check that.) We can also discard
820- * quals that are implied by a partial index's predicate.
819+ * immutable functions, so we have to check that.)
820+ *
821+ * We can also discard quals that are implied by a partial index's
822+ * predicate, but only in a plain SELECT; when scanning a target relation
823+ * of UPDATE/DELETE/SELECT FOR UPDATE, we must leave such quals in the
824+ * plan so that they'll be properly rechecked by EvalPlanQual testing.
821825 *
822826 * While at it, we strip off the RestrictInfos to produce a list of plain
823827 * expressions.
@@ -836,8 +840,14 @@ create_indexscan_plan(PlannerInfo *root,
836840
837841 if (predicate_implied_by (clausel , nonlossy_indexquals ))
838842 continue ;
839- if (predicate_implied_by (clausel , best_path -> indexinfo -> indpred ))
840- continue ;
843+ if (best_path -> indexinfo -> indpred )
844+ {
845+ if (baserelid != root -> parse -> resultRelation &&
846+ !list_member_int (root -> parse -> rowMarks , baserelid ))
847+ if (predicate_implied_by (clausel ,
848+ best_path -> indexinfo -> indpred ))
849+ continue ;
850+ }
841851 }
842852 qpqual = lappend (qpqual , rinfo -> clause );
843853 }
@@ -920,8 +930,12 @@ create_bitmap_scan_plan(PlannerInfo *root,
920930 * but are logically implied by, the index quals; so we also try a
921931 * predicate_implied_by() check to see if we can discard quals that way.
922932 * (predicate_implied_by assumes its first input contains only immutable
923- * functions, so we have to check that.) We can also discard quals that
924- * are implied by a partial index's predicate.
933+ * functions, so we have to check that.)
934+ *
935+ * We can also discard quals that are implied by a partial index's
936+ * predicate, but only in a plain SELECT; when scanning a target relation
937+ * of UPDATE/DELETE/SELECT FOR UPDATE, we must leave such quals in the
938+ * plan so that they'll be properly rechecked by EvalPlanQual testing.
925939 *
926940 * XXX For the moment, we only consider partial index predicates in the
927941 * simple single-index-scan case. Is it worth trying to be smart about
@@ -945,8 +959,14 @@ create_bitmap_scan_plan(PlannerInfo *root,
945959 {
946960 IndexPath * ipath = (IndexPath * ) best_path -> bitmapqual ;
947961
948- if (predicate_implied_by (clausel , ipath -> indexinfo -> indpred ))
949- continue ;
962+ if (ipath -> indexinfo -> indpred )
963+ {
964+ if (baserelid != root -> parse -> resultRelation &&
965+ !list_member_int (root -> parse -> rowMarks , baserelid ))
966+ if (predicate_implied_by (clausel ,
967+ ipath -> indexinfo -> indpred ))
968+ continue ;
969+ }
950970 }
951971 }
952972 qpqual = lappend (qpqual , clause );
@@ -1303,7 +1323,9 @@ create_nestloop_plan(PlannerInfo *root,
13031323 * join quals; failing to prove that doesn't result in an incorrect
13041324 * plan. It is the right way to proceed because adding more quals to
13051325 * the stuff we got from the original query would just make it harder
1306- * to detect duplication.
1326+ * to detect duplication. (Also, to change this we'd have to be
1327+ * wary of UPDATE/DELETE/SELECT FOR UPDATE target relations; see
1328+ * notes above about EvalPlanQual.)
13071329 */
13081330 BitmapHeapPath * innerpath = (BitmapHeapPath * ) best_path -> innerjoinpath ;
13091331
0 commit comments