Fix EXPLAIN Bitmap heap scan to count pages with no visible tuples
authorHeikki Linnakangas
Mon, 18 Mar 2024 12:04:24 +0000 (14:04 +0200)
committerHeikki Linnakangas
Mon, 18 Mar 2024 12:04:24 +0000 (14:04 +0200)
Previously, bitmap heap scans only counted lossy and exact pages for
explain when there was at least one visible tuple on the page.

heapam_scan_bitmap_next_block() returned true only if there was a
"valid" page with tuples to be processed. However, the lossy and exact
page counters in EXPLAIN should count the number of pages represented
in a lossy or non-lossy way in the constructed bitmap, regardless of
whether or not the pages ultimately contained visible tuples.

Backpatch to all supported versions.

Author: Melanie Plageman
Discussion: https://www.postgresql.org/message-id/CAAKRu_ZwCwWFeL_H3ia26bP2e7HiKLWt0ZmGXPVwPO6uXq0vaA@mail.gmail.com
Discussion: https://www.postgresql.org/message-id/CAAKRu_bxrXeZ2rCnY8LyeC2Ls88KpjWrQ%[email protected]

src/backend/executor/nodeBitmapHeapscan.c
src/test/regress/expected/partition_prune.out

index 5a5c410106ac60e62768c916bc5673d6b7625394..8d1b359000c88f66f3a5cceda5c30e6aac68e65c 100644 (file)
@@ -207,6 +207,11 @@ BitmapHeapNext(BitmapHeapScanState *node)
 
            BitmapAdjustPrefetchIterator(node, tbmres);
 
+           if (tbmres->ntuples >= 0)
+               node->exact_pages++;
+           else
+               node->lossy_pages++;
+
            /*
             * We can skip fetching the heap page if we don't need any fields
             * from the heap, and the bitmap entries don't need rechecking,
@@ -238,11 +243,6 @@ BitmapHeapNext(BitmapHeapScanState *node)
                continue;
            }
 
-           if (tbmres->ntuples >= 0)
-               node->exact_pages++;
-           else
-               node->lossy_pages++;
-
            /* Adjust the prefetch target */
            BitmapAdjustPrefetchTarget(node);
        }
index 92bea8b80ba2c6a39d1c04636143d1bef6f117de..6e80947d8745492c9a40bb2b5aa909e2b08f24f3 100644 (file)
@@ -2830,6 +2830,7 @@ update ab_a1 set b = 3 from ab where ab.a = 1 and ab.a = ab_a1.a;
                            Index Cond: (a = 1)
                ->  Bitmap Heap Scan on ab_a1_b3 ab_3 (actual rows=0 loops=1)
                      Recheck Cond: (a = 1)
+                     Heap Blocks: exact=1
                      ->  Bitmap Index Scan on ab_a1_b3_a_idx (actual rows=1 loops=1)
                            Index Cond: (a = 1)
          ->  Materialize (actual rows=1 loops=1)
@@ -2851,14 +2852,16 @@ update ab_a1 set b = 3 from ab where ab.a = 1 and ab.a = ab_a1.a;
                            Index Cond: (a = 1)
                ->  Bitmap Heap Scan on ab_a1_b3 ab_3 (actual rows=0 loops=1)
                      Recheck Cond: (a = 1)
+                     Heap Blocks: exact=1
                      ->  Bitmap Index Scan on ab_a1_b3_a_idx (actual rows=1 loops=1)
                            Index Cond: (a = 1)
          ->  Materialize (actual rows=0 loops=1)
                ->  Bitmap Heap Scan on ab_a1_b3 ab_a1_3 (actual rows=0 loops=1)
                      Recheck Cond: (a = 1)
+                     Heap Blocks: exact=1
                      ->  Bitmap Index Scan on ab_a1_b3_a_idx (actual rows=1 loops=1)
                            Index Cond: (a = 1)
-(65 rows)
+(68 rows)
 
 table ab;
  a | b