diff options
Diffstat (limited to 'src/backend/executor/nodeBitmapHeapscan.c')
-rw-r--r-- | src/backend/executor/nodeBitmapHeapscan.c | 100 |
1 files changed, 41 insertions, 59 deletions
diff --git a/src/backend/executor/nodeBitmapHeapscan.c b/src/backend/executor/nodeBitmapHeapscan.c index f1e30aeb8f0..87e0063a03a 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.19 2007/09/12 22:10:26 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/executor/nodeBitmapHeapscan.c,v 1.20 2007/09/20 17:56:31 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -240,12 +240,7 @@ bitgetpage(HeapScanDesc scan, TBMIterateResult *tbmres) BlockNumber page = tbmres->blockno; Buffer buffer; Snapshot snapshot; - Page dp; int ntup; - int curslot; - int minslot; - int maxslot; - int maxoff; /* * Acquire pin on the target heap page, trading in any pin we held before. @@ -258,6 +253,13 @@ bitgetpage(HeapScanDesc scan, TBMIterateResult *tbmres) buffer = scan->rs_cbuf; snapshot = scan->rs_snapshot; + ntup = 0; + + /* + * Prune and repair fragmentation for the whole page, if possible. + */ + heap_page_prune_opt(scan->rs_rd, buffer, RecentGlobalXmin); + /* * We must hold share lock on the buffer content while examining tuple * visibility. Afterwards, however, the tuples we have found to be @@ -265,71 +267,51 @@ bitgetpage(HeapScanDesc scan, TBMIterateResult *tbmres) */ LockBuffer(buffer, BUFFER_LOCK_SHARE); - dp = (Page) BufferGetPage(buffer); - maxoff = PageGetMaxOffsetNumber(dp); - /* - * Determine how many entries we need to look at on this page. If the - * bitmap is lossy then we need to look at each physical item pointer; - * otherwise we just look through the offsets listed in tbmres. + * We need two separate strategies for lossy and non-lossy cases. */ if (tbmres->ntuples >= 0) { - /* non-lossy case */ - minslot = 0; - maxslot = tbmres->ntuples - 1; - } - else - { - /* lossy case */ - minslot = FirstOffsetNumber; - maxslot = maxoff; - } - - ntup = 0; - for (curslot = minslot; curslot <= maxslot; curslot++) - { - OffsetNumber targoffset; - ItemId lp; - HeapTupleData loctup; - bool valid; - - if (tbmres->ntuples >= 0) - { - /* non-lossy case */ - targoffset = tbmres->offsets[curslot]; - } - else - { - /* lossy case */ - targoffset = (OffsetNumber) curslot; - } - /* - * We'd better check for out-of-range offnum in case of VACUUM since - * the TID was obtained. + * Bitmap is non-lossy, so we just look through the offsets listed in + * tbmres; but we have to follow any HOT chain starting at each such + * offset. */ - if (targoffset < FirstOffsetNumber || targoffset > maxoff) - continue; + int curslot; - lp = PageGetItemId(dp, targoffset); + for (curslot = 0; curslot < tbmres->ntuples; curslot++) + { + OffsetNumber offnum = tbmres->offsets[curslot]; + ItemPointerData tid; + ItemPointerSet(&tid, page, offnum); + if (heap_hot_search_buffer(&tid, buffer, snapshot, NULL)) + scan->rs_vistuples[ntup++] = ItemPointerGetOffsetNumber(&tid); + } + } + else + { /* - * Must check for deleted tuple. + * Bitmap is lossy, so we must examine each item pointer on the page. + * But we can ignore HOT chains, since we'll check each tuple anyway. */ - if (!ItemIdIsNormal(lp)) - continue; + Page dp = (Page) BufferGetPage(buffer); + OffsetNumber maxoff = PageGetMaxOffsetNumber(dp); + OffsetNumber offnum; - /* - * check time qualification of tuple, remember it if valid - */ - loctup.t_data = (HeapTupleHeader) PageGetItem((Page) dp, lp); - loctup.t_len = ItemIdGetLength(lp); - ItemPointerSet(&(loctup.t_self), page, targoffset); + for (offnum = FirstOffsetNumber; offnum <= maxoff; offnum++) + { + ItemId lp; + HeapTupleData loctup; - valid = HeapTupleSatisfiesVisibility(&loctup, snapshot, buffer); - if (valid) - scan->rs_vistuples[ntup++] = targoffset; + lp = PageGetItemId(dp, offnum); + if (!ItemIdIsNormal(lp)) + continue; + loctup.t_data = (HeapTupleHeader) PageGetItem((Page) dp, lp); + loctup.t_len = ItemIdGetLength(lp); + if (HeapTupleSatisfiesVisibility(&loctup, snapshot, buffer)) + scan->rs_vistuples[ntup++] = offnum; + } } LockBuffer(buffer, BUFFER_LOCK_UNLOCK); |