10
10
*
11
11
*
12
12
* IDENTIFICATION
13
- * $PostgreSQL: pgsql/src/backend/optimizer/plan/createplan.c,v 1.210 2006/04/30 18:30:39 tgl Exp $
13
+ * $PostgreSQL: pgsql/src/backend/optimizer/plan/createplan.c,v 1.211 2006/05/18 18:57:31 tgl Exp $
14
14
*
15
15
*-------------------------------------------------------------------------
16
16
*/
@@ -921,7 +921,7 @@ create_bitmap_scan_plan(PlannerInfo *root,
921
921
* by the index. All the predicates in the indexquals will be checked
922
922
* (either by the index itself, or by nodeBitmapHeapscan.c), but if there
923
923
* are any "special" or lossy operators involved then they must be added
924
- * to qpqual. The upshot is that qpquals must contain scan_clauses minus
924
+ * to qpqual. The upshot is that qpqual must contain scan_clauses minus
925
925
* whatever appears in indexquals.
926
926
*
927
927
* In normal cases simple equal() checks will be enough to spot duplicate
@@ -932,15 +932,11 @@ create_bitmap_scan_plan(PlannerInfo *root,
932
932
* (predicate_implied_by assumes its first input contains only immutable
933
933
* functions, so we have to check that.)
934
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.
939
- *
940
- * XXX For the moment, we only consider partial index predicates in the
941
- * simple single-index-scan case. Is it worth trying to be smart about
942
- * more complex cases? Perhaps create_bitmap_subplan should be made to
943
- * include predicate info in what it constructs.
935
+ * Unlike create_indexscan_plan(), we need take no special thought here
936
+ * for partial index predicates; this is because the predicate conditions
937
+ * are already listed in bitmapqualorig and indexquals. Bitmap scans
938
+ * have to do it that way because predicate conditions need to be rechecked
939
+ * if the scan becomes lossy.
944
940
*/
945
941
qpqual = NIL ;
946
942
foreach (l , scan_clauses )
@@ -955,19 +951,6 @@ create_bitmap_scan_plan(PlannerInfo *root,
955
951
956
952
if (predicate_implied_by (clausel , indexquals ))
957
953
continue ;
958
- if (IsA (best_path -> bitmapqual , IndexPath ))
959
- {
960
- IndexPath * ipath = (IndexPath * ) best_path -> bitmapqual ;
961
-
962
- if (ipath -> indexinfo -> indpred )
963
- {
964
- if (baserelid != root -> parse -> resultRelation &&
965
- get_rowmark (root -> parse , baserelid ) == NULL )
966
- if (predicate_implied_by (clausel ,
967
- ipath -> indexinfo -> indpred ))
968
- continue ;
969
- }
970
- }
971
954
}
972
955
qpqual = lappend (qpqual , clause );
973
956
}
@@ -1009,7 +992,9 @@ create_bitmap_scan_plan(PlannerInfo *root,
1009
992
* As byproducts, we also return in *qual and *indexqual the qual lists
1010
993
* (in implicit-AND form, without RestrictInfos) describing the original index
1011
994
* conditions and the generated indexqual conditions. The latter is made to
1012
- * exclude lossy index operators.
995
+ * exclude lossy index operators. Both lists include partial-index predicates,
996
+ * because we have to recheck predicates as well as index conditions if the
997
+ * bitmap scan becomes lossy.
1013
998
*
1014
999
* Note: if you find yourself changing this, you probably need to change
1015
1000
* make_restrictinfo_from_bitmapqual too.
@@ -1136,6 +1121,7 @@ create_bitmap_subplan(PlannerInfo *root, Path *bitmapqual,
1136
1121
IndexPath * ipath = (IndexPath * ) bitmapqual ;
1137
1122
IndexScan * iscan ;
1138
1123
List * nonlossy_clauses ;
1124
+ ListCell * l ;
1139
1125
1140
1126
/* Use the regular indexscan plan build machinery... */
1141
1127
iscan = create_indexscan_plan (root , ipath , NIL , NIL ,
@@ -1154,6 +1140,22 @@ create_bitmap_subplan(PlannerInfo *root, Path *bitmapqual,
1154
1140
plan -> plan_width = 0 ; /* meaningless */
1155
1141
* qual = get_actual_clauses (ipath -> indexclauses );
1156
1142
* indexqual = get_actual_clauses (nonlossy_clauses );
1143
+ foreach (l , ipath -> indexinfo -> indpred )
1144
+ {
1145
+ Expr * pred = (Expr * ) lfirst (l );
1146
+
1147
+ /*
1148
+ * We know that the index predicate must have been implied by
1149
+ * the query condition as a whole, but it may or may not be
1150
+ * implied by the conditions that got pushed into the
1151
+ * bitmapqual. Avoid generating redundant conditions.
1152
+ */
1153
+ if (!predicate_implied_by (list_make1 (pred ), ipath -> indexclauses ))
1154
+ {
1155
+ * qual = lappend (* qual , pred );
1156
+ * indexqual = lappend (* indexqual , pred );
1157
+ }
1158
+ }
1157
1159
}
1158
1160
else
1159
1161
{
0 commit comments