Commit 7c85aa39 authored by Tom Lane's avatar Tom Lane

Fix oversight in recent parameterized-path patch.

bitmap_scan_cost_est() has to be able to cope with a BitmapOrPath, but
I'd taken a shortcut that didn't work for that case.  Noted by Heikki.
Add some regression tests since this area is evidently under-covered.
parent ba3e4157
...@@ -1317,28 +1317,31 @@ path_usage_comparator(const void *a, const void *b) ...@@ -1317,28 +1317,31 @@ path_usage_comparator(const void *a, const void *b)
/* /*
* Estimate the cost of actually executing a bitmap scan with a single * Estimate the cost of actually executing a bitmap scan with a single
* index path (no BitmapAnd, at least not at this level). * index path (no BitmapAnd, at least not at this level; but it could be
* a BitmapOr).
*/ */
static Cost static Cost
bitmap_scan_cost_est(PlannerInfo *root, RelOptInfo *rel, Path *ipath) bitmap_scan_cost_est(PlannerInfo *root, RelOptInfo *rel, Path *ipath)
{ {
BitmapHeapPath bpath; BitmapHeapPath bpath;
Relids required_outer;
/* Must be a simple IndexPath so that we can just copy its param_info */ /* Identify required outer rels, in case it's a parameterized scan */
Assert(IsA(ipath, IndexPath)); required_outer = get_bitmap_tree_required_outer(ipath);
/* Set up a dummy BitmapHeapPath */ /* Set up a dummy BitmapHeapPath */
bpath.path.type = T_BitmapHeapPath; bpath.path.type = T_BitmapHeapPath;
bpath.path.pathtype = T_BitmapHeapScan; bpath.path.pathtype = T_BitmapHeapScan;
bpath.path.parent = rel; bpath.path.parent = rel;
bpath.path.param_info = ipath->param_info; bpath.path.param_info = get_baserel_parampathinfo(root, rel,
required_outer);
bpath.path.pathkeys = NIL; bpath.path.pathkeys = NIL;
bpath.bitmapqual = ipath; bpath.bitmapqual = ipath;
cost_bitmap_heap_scan(&bpath.path, root, rel, cost_bitmap_heap_scan(&bpath.path, root, rel,
bpath.path.param_info, bpath.path.param_info,
ipath, ipath,
get_loop_count(root, PATH_REQ_OUTER(ipath))); get_loop_count(root, required_outer));
return bpath.path.total_cost; return bpath.path.total_cost;
} }
......
...@@ -2599,6 +2599,57 @@ RESET enable_seqscan; ...@@ -2599,6 +2599,57 @@ RESET enable_seqscan;
RESET enable_indexscan; RESET enable_indexscan;
RESET enable_bitmapscan; RESET enable_bitmapscan;
DROP TABLE onek_with_null; DROP TABLE onek_with_null;
--
-- Check bitmap index path planning
--
EXPLAIN (COSTS OFF)
SELECT * FROM tenk1
WHERE thousand = 42 AND (tenthous = 1 OR tenthous = 3 OR tenthous = 42);
QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------------------------
Bitmap Heap Scan on tenk1
Recheck Cond: (((thousand = 42) AND (tenthous = 1)) OR ((thousand = 42) AND (tenthous = 3)) OR ((thousand = 42) AND (tenthous = 42)))
-> BitmapOr
-> Bitmap Index Scan on tenk1_thous_tenthous
Index Cond: ((thousand = 42) AND (tenthous = 1))
-> Bitmap Index Scan on tenk1_thous_tenthous
Index Cond: ((thousand = 42) AND (tenthous = 3))
-> Bitmap Index Scan on tenk1_thous_tenthous
Index Cond: ((thousand = 42) AND (tenthous = 42))
(9 rows)
SELECT * FROM tenk1
WHERE thousand = 42 AND (tenthous = 1 OR tenthous = 3 OR tenthous = 42);
unique1 | unique2 | two | four | ten | twenty | hundred | thousand | twothousand | fivethous | tenthous | odd | even | stringu1 | stringu2 | string4
---------+---------+-----+------+-----+--------+---------+----------+-------------+-----------+----------+-----+------+----------+----------+---------
42 | 5530 | 0 | 2 | 2 | 2 | 42 | 42 | 42 | 42 | 42 | 84 | 85 | QBAAAA | SEIAAA | OOOOxx
(1 row)
EXPLAIN (COSTS OFF)
SELECT count(*) FROM tenk1
WHERE hundred = 42 AND (thousand = 42 OR thousand = 99);
QUERY PLAN
---------------------------------------------------------------------------------
Aggregate
-> Bitmap Heap Scan on tenk1
Recheck Cond: ((hundred = 42) AND ((thousand = 42) OR (thousand = 99)))
-> BitmapAnd
-> Bitmap Index Scan on tenk1_hundred
Index Cond: (hundred = 42)
-> BitmapOr
-> Bitmap Index Scan on tenk1_thous_tenthous
Index Cond: (thousand = 42)
-> Bitmap Index Scan on tenk1_thous_tenthous
Index Cond: (thousand = 99)
(11 rows)
SELECT count(*) FROM tenk1
WHERE hundred = 42 AND (thousand = 42 OR thousand = 99);
count
-------
10
(1 row)
-- --
-- Check behavior with duplicate index column contents -- Check behavior with duplicate index column contents
-- --
......
...@@ -858,6 +858,22 @@ RESET enable_bitmapscan; ...@@ -858,6 +858,22 @@ RESET enable_bitmapscan;
DROP TABLE onek_with_null; DROP TABLE onek_with_null;
--
-- Check bitmap index path planning
--
EXPLAIN (COSTS OFF)
SELECT * FROM tenk1
WHERE thousand = 42 AND (tenthous = 1 OR tenthous = 3 OR tenthous = 42);
SELECT * FROM tenk1
WHERE thousand = 42 AND (tenthous = 1 OR tenthous = 3 OR tenthous = 42);
EXPLAIN (COSTS OFF)
SELECT count(*) FROM tenk1
WHERE hundred = 42 AND (thousand = 42 OR thousand = 99);
SELECT count(*) FROM tenk1
WHERE hundred = 42 AND (thousand = 42 OR thousand = 99);
-- --
-- Check behavior with duplicate index column contents -- Check behavior with duplicate index column contents
-- --
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment