10
10
*
11
11
*
12
12
* IDENTIFICATION
13
- * $PostgreSQL: pgsql/src/backend/optimizer/plan/createplan.c,v 1.251 2008/10/21 20:42:53 tgl Exp $
13
+ * $PostgreSQL: pgsql/src/backend/optimizer/plan/createplan.c,v 1.252 2008/11/20 19:52:54 tgl Exp $
14
14
*
15
15
*-------------------------------------------------------------------------
16
16
*/
@@ -53,7 +53,7 @@ static BitmapHeapScan *create_bitmap_scan_plan(PlannerInfo *root,
53
53
BitmapHeapPath * best_path ,
54
54
List * tlist , List * scan_clauses );
55
55
static Plan * create_bitmap_subplan (PlannerInfo * root , Path * bitmapqual ,
56
- List * * qual );
56
+ List * * qual , List * * indexqual );
57
57
static TidScan * create_tidscan_plan (PlannerInfo * root , TidPath * best_path ,
58
58
List * tlist , List * scan_clauses );
59
59
static SubqueryScan * create_subqueryscan_plan (PlannerInfo * root , Path * best_path ,
@@ -987,6 +987,7 @@ create_bitmap_scan_plan(PlannerInfo *root,
987
987
Index baserelid = best_path -> path .parent -> relid ;
988
988
Plan * bitmapqualplan ;
989
989
List * bitmapqualorig ;
990
+ List * indexquals ;
990
991
List * qpqual ;
991
992
ListCell * l ;
992
993
BitmapHeapScan * scan_plan ;
@@ -995,9 +996,9 @@ create_bitmap_scan_plan(PlannerInfo *root,
995
996
Assert (baserelid > 0 );
996
997
Assert (best_path -> path .parent -> rtekind == RTE_RELATION );
997
998
998
- /* Process the bitmapqual tree into a Plan tree and qual list */
999
+ /* Process the bitmapqual tree into a Plan tree and qual lists */
999
1000
bitmapqualplan = create_bitmap_subplan (root , best_path -> bitmapqual ,
1000
- & bitmapqualorig );
1001
+ & bitmapqualorig , & indexquals );
1001
1002
1002
1003
/* Reduce RestrictInfo list to bare expressions; ignore pseudoconstants */
1003
1004
scan_clauses = extract_actual_clauses (scan_clauses , false);
@@ -1021,7 +1022,7 @@ create_bitmap_scan_plan(PlannerInfo *root,
1021
1022
* (either by the index itself, or by nodeBitmapHeapscan.c), but if there
1022
1023
* are any "special" operators involved then they must be added to qpqual.
1023
1024
* The upshot is that qpqual must contain scan_clauses minus whatever
1024
- * appears in bitmapqualorig .
1025
+ * appears in indexquals .
1025
1026
*
1026
1027
* In normal cases simple equal() checks will be enough to spot duplicate
1027
1028
* clauses, so we try that first. In some situations (particularly with
@@ -1033,22 +1034,22 @@ create_bitmap_scan_plan(PlannerInfo *root,
1033
1034
*
1034
1035
* Unlike create_indexscan_plan(), we need take no special thought here
1035
1036
* for partial index predicates; this is because the predicate conditions
1036
- * are already listed in bitmapqualorig. Bitmap scans have to do it that
1037
- * way because predicate conditions need to be rechecked if the scan's
1038
- * bitmap becomes lossy.
1037
+ * are already listed in bitmapqualorig and indexquals . Bitmap scans have
1038
+ * to do it that way because predicate conditions need to be rechecked if
1039
+ * the scan becomes lossy.
1039
1040
*/
1040
1041
qpqual = NIL ;
1041
1042
foreach (l , scan_clauses )
1042
1043
{
1043
1044
Node * clause = (Node * ) lfirst (l );
1044
1045
1045
- if (list_member (bitmapqualorig , clause ))
1046
+ if (list_member (indexquals , clause ))
1046
1047
continue ;
1047
1048
if (!contain_mutable_functions (clause ))
1048
1049
{
1049
1050
List * clausel = list_make1 (clause );
1050
1051
1051
- if (predicate_implied_by (clausel , bitmapqualorig ))
1052
+ if (predicate_implied_by (clausel , indexquals ))
1052
1053
continue ;
1053
1054
}
1054
1055
qpqual = lappend (qpqual , clause );
@@ -1082,19 +1083,21 @@ create_bitmap_scan_plan(PlannerInfo *root,
1082
1083
/*
1083
1084
* Given a bitmapqual tree, generate the Plan tree that implements it
1084
1085
*
1085
- * As a byproduct, we also return in *qual a qual list (in implicit-AND
1086
- * form, without RestrictInfos) describing the generated indexqual
1087
- * conditions, as needed for rechecking heap tuples in lossy cases.
1088
- * This list also includes partial-index predicates, because we have to
1089
- * recheck predicates as well as index conditions if the scan's bitmap
1090
- * becomes lossy.
1086
+ * As byproducts, we also return in *qual and *indexqual the qual lists
1087
+ * (in implicit-AND form, without RestrictInfos) describing the original index
1088
+ * conditions and the generated indexqual conditions. (These are the same in
1089
+ * simple cases, but when special index operators are involved, the former
1090
+ * list includes the special conditions while the latter includes the actual
1091
+ * indexable conditions derived from them.) Both lists include partial-index
1092
+ * predicates, because we have to recheck predicates as well as index
1093
+ * conditions if the bitmap scan becomes lossy.
1091
1094
*
1092
1095
* Note: if you find yourself changing this, you probably need to change
1093
1096
* make_restrictinfo_from_bitmapqual too.
1094
1097
*/
1095
1098
static Plan *
1096
1099
create_bitmap_subplan (PlannerInfo * root , Path * bitmapqual ,
1097
- List * * qual )
1100
+ List * * qual , List * * indexqual )
1098
1101
{
1099
1102
Plan * plan ;
1100
1103
@@ -1103,6 +1106,7 @@ create_bitmap_subplan(PlannerInfo *root, Path *bitmapqual,
1103
1106
BitmapAndPath * apath = (BitmapAndPath * ) bitmapqual ;
1104
1107
List * subplans = NIL ;
1105
1108
List * subquals = NIL ;
1109
+ List * subindexquals = NIL ;
1106
1110
ListCell * l ;
1107
1111
1108
1112
/*
@@ -1116,11 +1120,13 @@ create_bitmap_subplan(PlannerInfo *root, Path *bitmapqual,
1116
1120
{
1117
1121
Plan * subplan ;
1118
1122
List * subqual ;
1123
+ List * subindexqual ;
1119
1124
1120
1125
subplan = create_bitmap_subplan (root , (Path * ) lfirst (l ),
1121
- & subqual );
1126
+ & subqual , & subindexqual );
1122
1127
subplans = lappend (subplans , subplan );
1123
1128
subquals = list_concat_unique (subquals , subqual );
1129
+ subindexquals = list_concat_unique (subindexquals , subindexqual );
1124
1130
}
1125
1131
plan = (Plan * ) make_bitmap_and (subplans );
1126
1132
plan -> startup_cost = apath -> path .startup_cost ;
@@ -1129,13 +1135,16 @@ create_bitmap_subplan(PlannerInfo *root, Path *bitmapqual,
1129
1135
clamp_row_est (apath -> bitmapselectivity * apath -> path .parent -> tuples );
1130
1136
plan -> plan_width = 0 ; /* meaningless */
1131
1137
* qual = subquals ;
1138
+ * indexqual = subindexquals ;
1132
1139
}
1133
1140
else if (IsA (bitmapqual , BitmapOrPath ))
1134
1141
{
1135
1142
BitmapOrPath * opath = (BitmapOrPath * ) bitmapqual ;
1136
1143
List * subplans = NIL ;
1137
1144
List * subquals = NIL ;
1145
+ List * subindexquals = NIL ;
1138
1146
bool const_true_subqual = false;
1147
+ bool const_true_subindexqual = false;
1139
1148
ListCell * l ;
1140
1149
1141
1150
/*
@@ -1151,15 +1160,21 @@ create_bitmap_subplan(PlannerInfo *root, Path *bitmapqual,
1151
1160
{
1152
1161
Plan * subplan ;
1153
1162
List * subqual ;
1163
+ List * subindexqual ;
1154
1164
1155
1165
subplan = create_bitmap_subplan (root , (Path * ) lfirst (l ),
1156
- & subqual );
1166
+ & subqual , & subindexqual );
1157
1167
subplans = lappend (subplans , subplan );
1158
1168
if (subqual == NIL )
1159
1169
const_true_subqual = true;
1160
1170
else if (!const_true_subqual )
1161
1171
subquals = lappend (subquals ,
1162
1172
make_ands_explicit (subqual ));
1173
+ if (subindexqual == NIL )
1174
+ const_true_subindexqual = true;
1175
+ else if (!const_true_subindexqual )
1176
+ subindexquals = lappend (subindexquals ,
1177
+ make_ands_explicit (subindexqual ));
1163
1178
}
1164
1179
1165
1180
/*
@@ -1191,6 +1206,12 @@ create_bitmap_subplan(PlannerInfo *root, Path *bitmapqual,
1191
1206
* qual = subquals ;
1192
1207
else
1193
1208
* qual = list_make1 (make_orclause (subquals ));
1209
+ if (const_true_subindexqual )
1210
+ * indexqual = NIL ;
1211
+ else if (list_length (subindexquals ) <= 1 )
1212
+ * indexqual = subindexquals ;
1213
+ else
1214
+ * indexqual = list_make1 (make_orclause (subindexquals ));
1194
1215
}
1195
1216
else if (IsA (bitmapqual , IndexPath ))
1196
1217
{
@@ -1211,6 +1232,7 @@ create_bitmap_subplan(PlannerInfo *root, Path *bitmapqual,
1211
1232
clamp_row_est (ipath -> indexselectivity * ipath -> path .parent -> tuples );
1212
1233
plan -> plan_width = 0 ; /* meaningless */
1213
1234
* qual = get_actual_clauses (ipath -> indexclauses );
1235
+ * indexqual = get_actual_clauses (ipath -> indexquals );
1214
1236
foreach (l , ipath -> indexinfo -> indpred )
1215
1237
{
1216
1238
Expr * pred = (Expr * ) lfirst (l );
@@ -1222,7 +1244,10 @@ create_bitmap_subplan(PlannerInfo *root, Path *bitmapqual,
1222
1244
* generating redundant conditions.
1223
1245
*/
1224
1246
if (!predicate_implied_by (list_make1 (pred ), ipath -> indexclauses ))
1247
+ {
1225
1248
* qual = lappend (* qual , pred );
1249
+ * indexqual = lappend (* indexqual , pred );
1250
+ }
1226
1251
}
1227
1252
}
1228
1253
else
0 commit comments