Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit f323252

Browse files
committed
When a bitmap indexscan is using a partial index, it is necessary to include
the partial index predicate in the scan's "recheck condition". Otherwise, if the scan becomes lossy for lack of bitmap memory, we would fail to enforce that returned rows satisfy the predicate. Noted while studying bug #2441 from Arjen van der Meijden.
1 parent 8d988c7 commit f323252

File tree

1 file changed

+27
-25
lines changed

1 file changed

+27
-25
lines changed

src/backend/optimizer/plan/createplan.c

Lines changed: 27 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
*
1111
*
1212
* 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 $
1414
*
1515
*-------------------------------------------------------------------------
1616
*/
@@ -921,7 +921,7 @@ create_bitmap_scan_plan(PlannerInfo *root,
921921
* by the index. All the predicates in the indexquals will be checked
922922
* (either by the index itself, or by nodeBitmapHeapscan.c), but if there
923923
* 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
925925
* whatever appears in indexquals.
926926
*
927927
* In normal cases simple equal() checks will be enough to spot duplicate
@@ -932,15 +932,11 @@ create_bitmap_scan_plan(PlannerInfo *root,
932932
* (predicate_implied_by assumes its first input contains only immutable
933933
* functions, so we have to check that.)
934934
*
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.
944940
*/
945941
qpqual = NIL;
946942
foreach(l, scan_clauses)
@@ -955,19 +951,6 @@ create_bitmap_scan_plan(PlannerInfo *root,
955951

956952
if (predicate_implied_by(clausel, indexquals))
957953
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-
}
971954
}
972955
qpqual = lappend(qpqual, clause);
973956
}
@@ -1009,7 +992,9 @@ create_bitmap_scan_plan(PlannerInfo *root,
1009992
* As byproducts, we also return in *qual and *indexqual the qual lists
1010993
* (in implicit-AND form, without RestrictInfos) describing the original index
1011994
* 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.
1013998
*
1014999
* Note: if you find yourself changing this, you probably need to change
10151000
* make_restrictinfo_from_bitmapqual too.
@@ -1136,6 +1121,7 @@ create_bitmap_subplan(PlannerInfo *root, Path *bitmapqual,
11361121
IndexPath *ipath = (IndexPath *) bitmapqual;
11371122
IndexScan *iscan;
11381123
List *nonlossy_clauses;
1124+
ListCell *l;
11391125

11401126
/* Use the regular indexscan plan build machinery... */
11411127
iscan = create_indexscan_plan(root, ipath, NIL, NIL,
@@ -1154,6 +1140,22 @@ create_bitmap_subplan(PlannerInfo *root, Path *bitmapqual,
11541140
plan->plan_width = 0; /* meaningless */
11551141
*qual = get_actual_clauses(ipath->indexclauses);
11561142
*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+
}
11571159
}
11581160
else
11591161
{

0 commit comments

Comments
 (0)