10
10
*
11
11
*
12
12
* 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 $
14
14
*
15
15
*-------------------------------------------------------------------------
16
16
*/
@@ -816,8 +816,12 @@ create_indexscan_plan(PlannerInfo *root,
816
816
* are not equal to, but are logically implied by, the index quals; so we
817
817
* also try a predicate_implied_by() check to see if we can discard quals
818
818
* 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.
821
825
*
822
826
* While at it, we strip off the RestrictInfos to produce a list of plain
823
827
* expressions.
@@ -836,8 +840,14 @@ create_indexscan_plan(PlannerInfo *root,
836
840
837
841
if (predicate_implied_by (clausel , nonlossy_indexquals ))
838
842
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
+ }
841
851
}
842
852
qpqual = lappend (qpqual , rinfo -> clause );
843
853
}
@@ -920,8 +930,12 @@ create_bitmap_scan_plan(PlannerInfo *root,
920
930
* but are logically implied by, the index quals; so we also try a
921
931
* predicate_implied_by() check to see if we can discard quals that way.
922
932
* (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.
925
939
*
926
940
* XXX For the moment, we only consider partial index predicates in the
927
941
* simple single-index-scan case. Is it worth trying to be smart about
@@ -945,8 +959,14 @@ create_bitmap_scan_plan(PlannerInfo *root,
945
959
{
946
960
IndexPath * ipath = (IndexPath * ) best_path -> bitmapqual ;
947
961
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
+ }
950
970
}
951
971
}
952
972
qpqual = lappend (qpqual , clause );
@@ -1303,7 +1323,9 @@ create_nestloop_plan(PlannerInfo *root,
1303
1323
* join quals; failing to prove that doesn't result in an incorrect
1304
1324
* plan. It is the right way to proceed because adding more quals to
1305
1325
* 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.)
1307
1329
*/
1308
1330
BitmapHeapPath * innerpath = (BitmapHeapPath * ) best_path -> innerjoinpath ;
1309
1331
0 commit comments