Fix oversight in recent parameterized-path patch.
authorTom Lane <tgl@sss.pgh.pa.us>
Thu, 26 Apr 2012 18:17:13 +0000 (14:17 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Thu, 26 Apr 2012 18:17:44 +0000 (14:17 -0400)
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.

src/backend/optimizer/path/indxpath.c
src/test/regress/expected/create_index.out
src/test/regress/sql/create_index.sql

index 8f0eaf448c654194a38073110a26dabf958aa6fd..05530054e1388652e4c23381d037129067460a61 100644 (file)
@@ -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
- * 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
 bitmap_scan_cost_est(PlannerInfo *root, RelOptInfo *rel, Path *ipath)
 {
    BitmapHeapPath bpath;
+   Relids      required_outer;
 
-   /* Must be a simple IndexPath so that we can just copy its param_info */
-   Assert(IsA(ipath, IndexPath));
+   /* Identify required outer rels, in case it's a parameterized scan */
+   required_outer = get_bitmap_tree_required_outer(ipath);
 
    /* Set up a dummy BitmapHeapPath */
    bpath.path.type = T_BitmapHeapPath;
    bpath.path.pathtype = T_BitmapHeapScan;
    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.bitmapqual = ipath;
 
    cost_bitmap_heap_scan(&bpath.path, root, rel,
                          bpath.path.param_info,
                          ipath,
-                         get_loop_count(root, PATH_REQ_OUTER(ipath)));
+                         get_loop_count(root, required_outer));
 
    return bpath.path.total_cost;
 }
index 4411d250a71d168f83bffd3059ac6180eece4ecf..1f27b8e75f6b55a69003bc0ad3adfc5577c2b582 100644 (file)
@@ -2599,6 +2599,57 @@ RESET enable_seqscan;
 RESET enable_indexscan;
 RESET enable_bitmapscan;
 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
 --
index 62d05d06058e6e4b03e21f3cc15876da1efac62d..f8edb7ee76607ac3d0c4ce0260d234436405a0d5 100644 (file)
@@ -858,6 +858,22 @@ RESET enable_bitmapscan;
 
 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
 --