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

Commit 176961c

Browse files
committed
Fix breakage of bitmap scan plan creation for special index operators such
as LIKE. I oversimplified this code when removing support for plan-time determination of index operator lossiness back in April --- I had thought create_bitmap_subplan could stop returning two separate lists of qual conditions, but it still must so that we can treat special operators correctly in create_bitmap_scan_plan. Per report from Rushabh Lathia.
1 parent 6c3690d commit 176961c

File tree

3 files changed

+86
-19
lines changed

3 files changed

+86
-19
lines changed

src/backend/optimizer/plan/createplan.c

Lines changed: 44 additions & 19 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.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 $
1414
*
1515
*-------------------------------------------------------------------------
1616
*/
@@ -53,7 +53,7 @@ static BitmapHeapScan *create_bitmap_scan_plan(PlannerInfo *root,
5353
BitmapHeapPath *best_path,
5454
List *tlist, List *scan_clauses);
5555
static Plan *create_bitmap_subplan(PlannerInfo *root, Path *bitmapqual,
56-
List **qual);
56+
List **qual, List **indexqual);
5757
static TidScan *create_tidscan_plan(PlannerInfo *root, TidPath *best_path,
5858
List *tlist, List *scan_clauses);
5959
static SubqueryScan *create_subqueryscan_plan(PlannerInfo *root, Path *best_path,
@@ -987,6 +987,7 @@ create_bitmap_scan_plan(PlannerInfo *root,
987987
Index baserelid = best_path->path.parent->relid;
988988
Plan *bitmapqualplan;
989989
List *bitmapqualorig;
990+
List *indexquals;
990991
List *qpqual;
991992
ListCell *l;
992993
BitmapHeapScan *scan_plan;
@@ -995,9 +996,9 @@ create_bitmap_scan_plan(PlannerInfo *root,
995996
Assert(baserelid > 0);
996997
Assert(best_path->path.parent->rtekind == RTE_RELATION);
997998

998-
/* Process the bitmapqual tree into a Plan tree and qual list */
999+
/* Process the bitmapqual tree into a Plan tree and qual lists */
9991000
bitmapqualplan = create_bitmap_subplan(root, best_path->bitmapqual,
1000-
&bitmapqualorig);
1001+
&bitmapqualorig, &indexquals);
10011002

10021003
/* Reduce RestrictInfo list to bare expressions; ignore pseudoconstants */
10031004
scan_clauses = extract_actual_clauses(scan_clauses, false);
@@ -1021,7 +1022,7 @@ create_bitmap_scan_plan(PlannerInfo *root,
10211022
* (either by the index itself, or by nodeBitmapHeapscan.c), but if there
10221023
* are any "special" operators involved then they must be added to qpqual.
10231024
* The upshot is that qpqual must contain scan_clauses minus whatever
1024-
* appears in bitmapqualorig.
1025+
* appears in indexquals.
10251026
*
10261027
* In normal cases simple equal() checks will be enough to spot duplicate
10271028
* clauses, so we try that first. In some situations (particularly with
@@ -1033,22 +1034,22 @@ create_bitmap_scan_plan(PlannerInfo *root,
10331034
*
10341035
* Unlike create_indexscan_plan(), we need take no special thought here
10351036
* 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.
10391040
*/
10401041
qpqual = NIL;
10411042
foreach(l, scan_clauses)
10421043
{
10431044
Node *clause = (Node *) lfirst(l);
10441045

1045-
if (list_member(bitmapqualorig, clause))
1046+
if (list_member(indexquals, clause))
10461047
continue;
10471048
if (!contain_mutable_functions(clause))
10481049
{
10491050
List *clausel = list_make1(clause);
10501051

1051-
if (predicate_implied_by(clausel, bitmapqualorig))
1052+
if (predicate_implied_by(clausel, indexquals))
10521053
continue;
10531054
}
10541055
qpqual = lappend(qpqual, clause);
@@ -1082,19 +1083,21 @@ create_bitmap_scan_plan(PlannerInfo *root,
10821083
/*
10831084
* Given a bitmapqual tree, generate the Plan tree that implements it
10841085
*
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.
10911094
*
10921095
* Note: if you find yourself changing this, you probably need to change
10931096
* make_restrictinfo_from_bitmapqual too.
10941097
*/
10951098
static Plan *
10961099
create_bitmap_subplan(PlannerInfo *root, Path *bitmapqual,
1097-
List **qual)
1100+
List **qual, List **indexqual)
10981101
{
10991102
Plan *plan;
11001103

@@ -1103,6 +1106,7 @@ create_bitmap_subplan(PlannerInfo *root, Path *bitmapqual,
11031106
BitmapAndPath *apath = (BitmapAndPath *) bitmapqual;
11041107
List *subplans = NIL;
11051108
List *subquals = NIL;
1109+
List *subindexquals = NIL;
11061110
ListCell *l;
11071111

11081112
/*
@@ -1116,11 +1120,13 @@ create_bitmap_subplan(PlannerInfo *root, Path *bitmapqual,
11161120
{
11171121
Plan *subplan;
11181122
List *subqual;
1123+
List *subindexqual;
11191124

11201125
subplan = create_bitmap_subplan(root, (Path *) lfirst(l),
1121-
&subqual);
1126+
&subqual, &subindexqual);
11221127
subplans = lappend(subplans, subplan);
11231128
subquals = list_concat_unique(subquals, subqual);
1129+
subindexquals = list_concat_unique(subindexquals, subindexqual);
11241130
}
11251131
plan = (Plan *) make_bitmap_and(subplans);
11261132
plan->startup_cost = apath->path.startup_cost;
@@ -1129,13 +1135,16 @@ create_bitmap_subplan(PlannerInfo *root, Path *bitmapqual,
11291135
clamp_row_est(apath->bitmapselectivity * apath->path.parent->tuples);
11301136
plan->plan_width = 0; /* meaningless */
11311137
*qual = subquals;
1138+
*indexqual = subindexquals;
11321139
}
11331140
else if (IsA(bitmapqual, BitmapOrPath))
11341141
{
11351142
BitmapOrPath *opath = (BitmapOrPath *) bitmapqual;
11361143
List *subplans = NIL;
11371144
List *subquals = NIL;
1145+
List *subindexquals = NIL;
11381146
bool const_true_subqual = false;
1147+
bool const_true_subindexqual = false;
11391148
ListCell *l;
11401149

11411150
/*
@@ -1151,15 +1160,21 @@ create_bitmap_subplan(PlannerInfo *root, Path *bitmapqual,
11511160
{
11521161
Plan *subplan;
11531162
List *subqual;
1163+
List *subindexqual;
11541164

11551165
subplan = create_bitmap_subplan(root, (Path *) lfirst(l),
1156-
&subqual);
1166+
&subqual, &subindexqual);
11571167
subplans = lappend(subplans, subplan);
11581168
if (subqual == NIL)
11591169
const_true_subqual = true;
11601170
else if (!const_true_subqual)
11611171
subquals = lappend(subquals,
11621172
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));
11631178
}
11641179

11651180
/*
@@ -1191,6 +1206,12 @@ create_bitmap_subplan(PlannerInfo *root, Path *bitmapqual,
11911206
*qual = subquals;
11921207
else
11931208
*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));
11941215
}
11951216
else if (IsA(bitmapqual, IndexPath))
11961217
{
@@ -1211,6 +1232,7 @@ create_bitmap_subplan(PlannerInfo *root, Path *bitmapqual,
12111232
clamp_row_est(ipath->indexselectivity * ipath->path.parent->tuples);
12121233
plan->plan_width = 0; /* meaningless */
12131234
*qual = get_actual_clauses(ipath->indexclauses);
1235+
*indexqual = get_actual_clauses(ipath->indexquals);
12141236
foreach(l, ipath->indexinfo->indpred)
12151237
{
12161238
Expr *pred = (Expr *) lfirst(l);
@@ -1222,7 +1244,10 @@ create_bitmap_subplan(PlannerInfo *root, Path *bitmapqual,
12221244
* generating redundant conditions.
12231245
*/
12241246
if (!predicate_implied_by(list_make1(pred), ipath->indexclauses))
1247+
{
12251248
*qual = lappend(*qual, pred);
1249+
*indexqual = lappend(*indexqual, pred);
1250+
}
12261251
}
12271252
}
12281253
else

src/test/regress/expected/btree_index.out

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,3 +98,32 @@ SELECT b.*
9898
4500 | 2080851358
9999
(1 row)
100100

101+
--
102+
-- Check correct optimization of LIKE (special index operator support)
103+
-- for both indexscan and bitmapscan cases
104+
--
105+
set enable_seqscan to false;
106+
set enable_indexscan to true;
107+
set enable_bitmapscan to false;
108+
select proname from pg_proc where proname like E'RI\\_FKey%del' order by 1;
109+
proname
110+
------------------------
111+
RI_FKey_cascade_del
112+
RI_FKey_noaction_del
113+
RI_FKey_restrict_del
114+
RI_FKey_setdefault_del
115+
RI_FKey_setnull_del
116+
(5 rows)
117+
118+
set enable_indexscan to false;
119+
set enable_bitmapscan to true;
120+
select proname from pg_proc where proname like E'RI\\_FKey%del' order by 1;
121+
proname
122+
------------------------
123+
RI_FKey_cascade_del
124+
RI_FKey_noaction_del
125+
RI_FKey_restrict_del
126+
RI_FKey_setdefault_del
127+
RI_FKey_setnull_del
128+
(5 rows)
129+

src/test/regress/sql/btree_index.sql

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,3 +51,16 @@ SELECT b.*
5151
FROM bt_f8_heap b
5252
WHERE b.seqno = '4500'::float8;
5353

54+
--
55+
-- Check correct optimization of LIKE (special index operator support)
56+
-- for both indexscan and bitmapscan cases
57+
--
58+
59+
set enable_seqscan to false;
60+
set enable_indexscan to true;
61+
set enable_bitmapscan to false;
62+
select proname from pg_proc where proname like E'RI\\_FKey%del' order by 1;
63+
64+
set enable_indexscan to false;
65+
set enable_bitmapscan to true;
66+
select proname from pg_proc where proname like E'RI\\_FKey%del' order by 1;

0 commit comments

Comments
 (0)