From df2655612a0a32d33fa144f3e48d0a2c63505e62 Mon Sep 17 00:00:00 2001 From: Melanie Plageman Date: Sat, 6 Apr 2024 08:51:40 -0400 Subject: [PATCH v24 01/12] table_scan_bitmap_next_block implementations count lossy and exact pages Keep track of whether or not individual TBMIterateResult's blocks were represented lossily in the bitmap in table AM-specific code. These counters are used for EXPLAIN. This is a step toward removing TBMIterateResults as a flow control mechanism in BitmapHeapNext(), which is required for a more asynchronous design. It also is more table AM-agnostic. Author: Melanie Plageman Reviewed-by: Tomas Vondra, Heikki Linnakangas Discussion: https://postgr.es/m/063e4eb4-32d9-439e-a0b1-75565a9835a8%40iki.fi --- src/backend/access/heap/heapam_handler.c | 8 +++++++- src/backend/executor/nodeBitmapHeapscan.c | 12 ++---------- src/include/access/tableam.h | 23 ++++++++++++++++++----- 3 files changed, 27 insertions(+), 16 deletions(-) diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c index 1c6da286d4..0ab3526d95 100644 --- a/src/backend/access/heap/heapam_handler.c +++ b/src/backend/access/heap/heapam_handler.c @@ -2116,7 +2116,8 @@ heapam_estimate_rel_size(Relation rel, int32 *attr_widths, static bool heapam_scan_bitmap_next_block(TableScanDesc scan, - TBMIterateResult *tbmres) + TBMIterateResult *tbmres, + uint64 *lossy_pages, uint64 *exact_pages) { HeapScanDesc hscan = (HeapScanDesc) scan; BlockNumber block = tbmres->blockno; @@ -2244,6 +2245,11 @@ heapam_scan_bitmap_next_block(TableScanDesc scan, Assert(ntup <= MaxHeapTuplesPerPage); hscan->rs_ntuples = ntup; + if (tbmres->ntuples >= 0) + (*exact_pages)++; + else + (*lossy_pages)++; + return ntup > 0; } diff --git a/src/backend/executor/nodeBitmapHeapscan.c b/src/backend/executor/nodeBitmapHeapscan.c index 3c63bdd93d..988fac261e 100644 --- a/src/backend/executor/nodeBitmapHeapscan.c +++ b/src/backend/executor/nodeBitmapHeapscan.c @@ -212,8 +212,6 @@ BitmapHeapNext(BitmapHeapScanState *node) for (;;) { - bool valid_block; - CHECK_FOR_INTERRUPTS(); /* @@ -233,14 +231,8 @@ BitmapHeapNext(BitmapHeapScanState *node) BitmapAdjustPrefetchIterator(node, tbmres->blockno); - valid_block = table_scan_bitmap_next_block(scan, tbmres); - - if (tbmres->ntuples >= 0) - node->stats.exact_pages++; - else - node->stats.lossy_pages++; - - if (!valid_block) + if (!table_scan_bitmap_next_block(scan, tbmres, + &node->stats.lossy_pages, &node->stats.exact_pages)) { /* AM doesn't think this block is valid, skip */ continue; diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h index da661289c1..f87688c480 100644 --- a/src/include/access/tableam.h +++ b/src/include/access/tableam.h @@ -796,6 +796,10 @@ typedef struct TableAmRoutine * on the page have to be returned, otherwise the tuples at offsets in * `tbmres->offsets` need to be returned. * + * `lossy_pages` and `exact_pages` are EXPLAIN counters that can be + * incremented by the table AM to indicate whether or not the block's + * representation in the bitmap is lossy. + * * XXX: Currently this may only be implemented if the AM uses md.c as its * storage manager, and uses ItemPointer->ip_blkid in a manner that maps * blockids directly to the underlying storage. nodeBitmapHeapscan.c @@ -811,7 +815,8 @@ typedef struct TableAmRoutine * scan_bitmap_next_tuple need to exist, or neither. */ bool (*scan_bitmap_next_block) (TableScanDesc scan, - struct TBMIterateResult *tbmres); + struct TBMIterateResult *tbmres, + uint64 *lossy_pages, uint64 *exact_pages); /* * Fetch the next tuple of a bitmap table scan into `slot` and return true @@ -1949,17 +1954,23 @@ table_relation_estimate_size(Relation rel, int32 *attr_widths, */ /* - * Prepare to fetch / check / return tuples from `tbmres->blockno` as part of - * a bitmap table scan. `scan` needs to have been started via + * Prepare to fetch / check / return tuples from `tbmres->blockno` as part of a + * bitmap table scan. `scan` needs to have been started via * table_beginscan_bm(). Returns false if there are no tuples to be found on * the page, true otherwise. * + * `lossy_pages` and `exact_pages` are EXPLAIN counters that can be incremented + * by the table AM to indicate whether or not the block's representation in the + * bitmap is lossy. + * * Note, this is an optionally implemented function, therefore should only be * used after verifying the presence (at plan time or such). */ static inline bool table_scan_bitmap_next_block(TableScanDesc scan, - struct TBMIterateResult *tbmres) + struct TBMIterateResult *tbmres, + uint64 *lossy_pages, + uint64 *exact_pages) { /* * We don't expect direct calls to table_scan_bitmap_next_block with valid @@ -1970,7 +1981,9 @@ table_scan_bitmap_next_block(TableScanDesc scan, elog(ERROR, "unexpected table_scan_bitmap_next_block call during logical decoding"); return scan->rs_rd->rd_tableam->scan_bitmap_next_block(scan, - tbmres); + tbmres, + lossy_pages, + exact_pages); } /* -- 2.45.2