diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index a0b561c209..2c9dc9a949 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/access/heap/heapam.c,v 1.235 2007/06/08 18:23:52 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/access/heap/heapam.c,v 1.236 2007/06/09 18:49:54 tgl Exp $ * * * INTERFACE ROUTINES @@ -58,6 +58,10 @@ #include "utils/syscache.h" +static HeapScanDesc heap_beginscan_internal(Relation relation, + Snapshot snapshot, + int nkeys, ScanKey key, + bool is_bitmapscan); static XLogRecPtr log_heap_update(Relation reln, Buffer oldbuf, ItemPointerData from, Buffer newbuf, HeapTuple newtup, bool move); @@ -95,8 +99,9 @@ initscan(HeapScanDesc scan, ScanKey key) * * During a rescan, don't make a new strategy object if we don't have to. */ - if (scan->rs_nblocks > NBuffers / 4 && - !scan->rs_rd->rd_istemp) + if (!scan->rs_bitmapscan && + !scan->rs_rd->rd_istemp && + scan->rs_nblocks > NBuffers / 4) { if (scan->rs_strategy == NULL) scan->rs_strategy = GetAccessStrategy(BAS_BULKREAD); @@ -114,8 +119,6 @@ initscan(HeapScanDesc scan, ScanKey key) scan->rs_startblock = 0; } - /* rs_pageatatime was set when the snapshot was filled in */ - scan->rs_inited = false; scan->rs_ctup.t_data = NULL; ItemPointerSetInvalid(&scan->rs_ctup.t_self); @@ -133,7 +136,12 @@ initscan(HeapScanDesc scan, ScanKey key) if (key != NULL) memcpy(scan->rs_key, key, scan->rs_nkeys * sizeof(ScanKeyData)); - pgstat_count_heap_scan(scan->rs_rd); + /* + * Currently, we don't have a stats counter for bitmap heap scans + * (but the underlying bitmap index scans will be counted). + */ + if (!scan->rs_bitmapscan) + pgstat_count_heap_scan(scan->rs_rd); } /* @@ -1037,11 +1045,30 @@ heap_openrv(const RangeVar *relation, LOCKMODE lockmode) /* ---------------- * heap_beginscan - begin relation scan + * + * heap_beginscan_bm is an alternate entry point for setting up a HeapScanDesc + * for a bitmap heap scan. Although that scan technology is really quite + * unlike a standard seqscan, there is just enough commonality to make it + * worth using the same data structure. * ---------------- */ HeapScanDesc heap_beginscan(Relation relation, Snapshot snapshot, int nkeys, ScanKey key) +{ + return heap_beginscan_internal(relation, snapshot, nkeys, key, false); +} + +HeapScanDesc +heap_beginscan_bm(Relation relation, Snapshot snapshot, + int nkeys, ScanKey key) +{ + return heap_beginscan_internal(relation, snapshot, nkeys, key, true); +} + +static HeapScanDesc +heap_beginscan_internal(Relation relation, Snapshot snapshot, + int nkeys, ScanKey key, bool is_bitmapscan) { HeapScanDesc scan; @@ -1062,6 +1089,7 @@ heap_beginscan(Relation relation, Snapshot snapshot, scan->rs_rd = relation; scan->rs_snapshot = snapshot; scan->rs_nkeys = nkeys; + scan->rs_bitmapscan = is_bitmapscan; scan->rs_strategy = NULL; /* set in initscan */ /* diff --git a/src/backend/executor/nodeBitmapHeapscan.c b/src/backend/executor/nodeBitmapHeapscan.c index 07729da2be..c2ae755e01 100644 --- a/src/backend/executor/nodeBitmapHeapscan.c +++ b/src/backend/executor/nodeBitmapHeapscan.c @@ -21,7 +21,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/executor/nodeBitmapHeapscan.c,v 1.17 2007/05/27 03:50:39 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/executor/nodeBitmapHeapscan.c,v 1.18 2007/06/09 18:49:55 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -388,9 +388,6 @@ ExecBitmapHeapReScan(BitmapHeapScanState *node, ExprContext *exprCtxt) /* rescan to release any page pin */ heap_rescan(node->ss.ss_currentScanDesc, NULL); - /* undo bogus "seq scan" count (see notes in ExecInitBitmapHeapScan) */ - pgstat_discount_heap_scan(node->ss.ss_currentScanDesc->rs_rd); - if (node->tbm) tbm_free(node->tbm); node->tbm = NULL; @@ -522,20 +519,12 @@ ExecInitBitmapHeapScan(BitmapHeapScan *node, EState *estate, int eflags) /* * Even though we aren't going to do a conventional seqscan, it is useful - * to create a HeapScanDesc --- this checks the relation size and sets up - * statistical infrastructure for us. + * to create a HeapScanDesc --- most of the fields in it are usable. */ - scanstate->ss.ss_currentScanDesc = heap_beginscan(currentRelation, - estate->es_snapshot, - 0, - NULL); - - /* - * One problem is that heap_beginscan counts a "sequential scan" start, - * when we actually aren't doing any such thing. Reverse out the added - * scan count. (Eventually we may want to count bitmap scans separately.) - */ - pgstat_discount_heap_scan(scanstate->ss.ss_currentScanDesc->rs_rd); + scanstate->ss.ss_currentScanDesc = heap_beginscan_bm(currentRelation, + estate->es_snapshot, + 0, + NULL); /* * get the scan type from the relation descriptor. diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h index 206159bdad..cade6a26aa 100644 --- a/src/include/access/heapam.h +++ b/src/include/access/heapam.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/access/heapam.h,v 1.125 2007/06/08 18:23:53 tgl Exp $ + * $PostgreSQL: pgsql/src/include/access/heapam.h,v 1.126 2007/06/09 18:49:55 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -141,6 +141,8 @@ extern Relation heap_openrv(const RangeVar *relation, LOCKMODE lockmode); extern HeapScanDesc heap_beginscan(Relation relation, Snapshot snapshot, int nkeys, ScanKey key); +extern HeapScanDesc heap_beginscan_bm(Relation relation, Snapshot snapshot, + int nkeys, ScanKey key); extern void heap_rescan(HeapScanDesc scan, ScanKey key); extern void heap_endscan(HeapScanDesc scan); extern HeapTuple heap_getnext(HeapScanDesc scan, ScanDirection direction); diff --git a/src/include/access/relscan.h b/src/include/access/relscan.h index b45b2caabf..15b9b8a337 100644 --- a/src/include/access/relscan.h +++ b/src/include/access/relscan.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/access/relscan.h,v 1.55 2007/06/08 18:23:53 tgl Exp $ + * $PostgreSQL: pgsql/src/include/access/relscan.h,v 1.56 2007/06/09 18:49:55 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -26,12 +26,13 @@ typedef struct HeapScanDescData Snapshot rs_snapshot; /* snapshot to see */ int rs_nkeys; /* number of scan keys */ ScanKey rs_key; /* array of scan key descriptors */ + bool rs_bitmapscan; /* true if this is really a bitmap scan */ + bool rs_pageatatime; /* verify visibility page-at-a-time? */ /* state set up at initscan time */ BlockNumber rs_nblocks; /* number of blocks to scan */ BlockNumber rs_startblock; /* block # to start at */ BufferAccessStrategy rs_strategy; /* access strategy for reads */ - bool rs_pageatatime; /* verify visibility page-at-a-time? */ bool rs_syncscan; /* report location to syncscan logic? */ /* scan current state */ @@ -42,7 +43,7 @@ typedef struct HeapScanDescData /* NB: if rs_cbuf is not InvalidBuffer, we hold a pin on that buffer */ ItemPointerData rs_mctid; /* marked scan position, if any */ - /* these fields only used in page-at-a-time mode */ + /* these fields only used in page-at-a-time mode and for bitmap scans */ int rs_cindex; /* current tuple's index in vistuples */ int rs_mindex; /* marked tuple's saved index */ int rs_ntuples; /* number of visible tuples on page */ diff --git a/src/include/pgstat.h b/src/include/pgstat.h index ff050e6e45..da91033353 100644 --- a/src/include/pgstat.h +++ b/src/include/pgstat.h @@ -5,7 +5,7 @@ * * Copyright (c) 2001-2007, PostgreSQL Global Development Group * - * $PostgreSQL: pgsql/src/include/pgstat.h,v 1.61 2007/05/27 17:28:36 tgl Exp $ + * $PostgreSQL: pgsql/src/include/pgstat.h,v 1.62 2007/06/09 18:49:55 tgl Exp $ * ---------- */ #ifndef PGSTAT_H @@ -518,12 +518,6 @@ extern void pgstat_initstats(Relation rel); if (pgstat_collect_tuplelevel && (rel)->pgstat_info != NULL) \ (rel)->pgstat_info->t_counts.t_numscans++; \ } while (0) -/* kluge for bitmap scans: */ -#define pgstat_discount_heap_scan(rel) \ - do { \ - if (pgstat_collect_tuplelevel && (rel)->pgstat_info != NULL) \ - (rel)->pgstat_info->t_counts.t_numscans--; \ - } while (0) #define pgstat_count_heap_getnext(rel) \ do { \ if (pgstat_collect_tuplelevel && (rel)->pgstat_info != NULL) \