PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
nodeBitmapHeapscan.c File Reference
#include "postgres.h"
#include <math.h>
#include "access/relscan.h"
#include "access/transam.h"
#include "executor/execdebug.h"
#include "executor/nodeBitmapHeapscan.h"
#include "pgstat.h"
#include "storage/bufmgr.h"
#include "storage/predicate.h"
#include "utils/memutils.h"
#include "utils/rel.h"
#include "utils/spccache.h"
#include "utils/snapmgr.h"
#include "utils/tqual.h"
Include dependency graph for nodeBitmapHeapscan.c:

Go to the source code of this file.

Functions

static TupleTableSlotBitmapHeapNext (BitmapHeapScanState *node)
 
static void bitgetpage (HeapScanDesc scan, TBMIterateResult *tbmres)
 
static bool BitmapHeapRecheck (BitmapHeapScanState *node, TupleTableSlot *slot)
 
TupleTableSlotExecBitmapHeapScan (BitmapHeapScanState *node)
 
void ExecReScanBitmapHeapScan (BitmapHeapScanState *node)
 
void ExecEndBitmapHeapScan (BitmapHeapScanState *node)
 
BitmapHeapScanStateExecInitBitmapHeapScan (BitmapHeapScan *node, EState *estate, int eflags)
 

Function Documentation

static void bitgetpage ( HeapScanDesc  scan,
TBMIterateResult tbmres 
)
static

Definition at line 318 of file nodeBitmapHeapscan.c.

References Assert, TBMIterateResult::blockno, BUFFER_LOCK_SHARE, BUFFER_LOCK_UNLOCK, BufferGetPage, CheckForSerializableConflictOut(), FirstOffsetNumber, heap_hot_search_buffer(), heap_page_prune_opt(), HeapTupleSatisfiesVisibility, ItemIdGetLength, ItemIdIsNormal, ItemPointerGetOffsetNumber, ItemPointerSet, LockBuffer(), MaxHeapTuplesPerPage, TBMIterateResult::ntuples, NULL, OffsetNumberNext, TBMIterateResult::offsets, PageGetItem, PageGetItemId, PageGetMaxOffsetNumber, PredicateLockTuple(), RelationData::rd_id, ReleaseAndReadBuffer(), HeapScanDescData::rs_cbuf, HeapScanDescData::rs_ntuples, HeapScanDescData::rs_rd, HeapScanDescData::rs_snapshot, HeapScanDescData::rs_vistuples, HeapTupleData::t_data, HeapTupleData::t_len, HeapTupleData::t_self, and HeapTupleData::t_tableOid.

Referenced by BitmapHeapNext().

319 {
320  BlockNumber page = tbmres->blockno;
321  Buffer buffer;
322  Snapshot snapshot;
323  int ntup;
324 
325  /*
326  * Acquire pin on the target heap page, trading in any pin we held before.
327  */
328  Assert(page < scan->rs_nblocks);
329 
330  scan->rs_cbuf = ReleaseAndReadBuffer(scan->rs_cbuf,
331  scan->rs_rd,
332  page);
333  buffer = scan->rs_cbuf;
334  snapshot = scan->rs_snapshot;
335 
336  ntup = 0;
337 
338  /*
339  * Prune and repair fragmentation for the whole page, if possible.
340  */
341  heap_page_prune_opt(scan->rs_rd, buffer);
342 
343  /*
344  * We must hold share lock on the buffer content while examining tuple
345  * visibility. Afterwards, however, the tuples we have found to be
346  * visible are guaranteed good as long as we hold the buffer pin.
347  */
348  LockBuffer(buffer, BUFFER_LOCK_SHARE);
349 
350  /*
351  * We need two separate strategies for lossy and non-lossy cases.
352  */
353  if (tbmres->ntuples >= 0)
354  {
355  /*
356  * Bitmap is non-lossy, so we just look through the offsets listed in
357  * tbmres; but we have to follow any HOT chain starting at each such
358  * offset.
359  */
360  int curslot;
361 
362  for (curslot = 0; curslot < tbmres->ntuples; curslot++)
363  {
364  OffsetNumber offnum = tbmres->offsets[curslot];
365  ItemPointerData tid;
366  HeapTupleData heapTuple;
367 
368  ItemPointerSet(&tid, page, offnum);
369  if (heap_hot_search_buffer(&tid, scan->rs_rd, buffer, snapshot,
370  &heapTuple, NULL, true))
371  scan->rs_vistuples[ntup++] = ItemPointerGetOffsetNumber(&tid);
372  }
373  }
374  else
375  {
376  /*
377  * Bitmap is lossy, so we must examine each item pointer on the page.
378  * But we can ignore HOT chains, since we'll check each tuple anyway.
379  */
380  Page dp = (Page) BufferGetPage(buffer);
382  OffsetNumber offnum;
383 
384  for (offnum = FirstOffsetNumber; offnum <= maxoff; offnum = OffsetNumberNext(offnum))
385  {
386  ItemId lp;
387  HeapTupleData loctup;
388  bool valid;
389 
390  lp = PageGetItemId(dp, offnum);
391  if (!ItemIdIsNormal(lp))
392  continue;
393  loctup.t_data = (HeapTupleHeader) PageGetItem((Page) dp, lp);
394  loctup.t_len = ItemIdGetLength(lp);
395  loctup.t_tableOid = scan->rs_rd->rd_id;
396  ItemPointerSet(&loctup.t_self, page, offnum);
397  valid = HeapTupleSatisfiesVisibility(&loctup, snapshot, buffer);
398  if (valid)
399  {
400  scan->rs_vistuples[ntup++] = offnum;
401  PredicateLockTuple(scan->rs_rd, &loctup, snapshot);
402  }
403  CheckForSerializableConflictOut(valid, scan->rs_rd, &loctup,
404  buffer, snapshot);
405  }
406  }
407 
409 
410  Assert(ntup <= MaxHeapTuplesPerPage);
411  scan->rs_ntuples = ntup;
412 }
#define BUFFER_LOCK_UNLOCK
Definition: bufmgr.h:87
HeapTupleHeaderData * HeapTupleHeader
Definition: htup.h:23
#define MaxHeapTuplesPerPage
Definition: htup_details.h:575
uint32 BlockNumber
Definition: block.h:31
#define PageGetMaxOffsetNumber(page)
Definition: bufpage.h:354
void CheckForSerializableConflictOut(bool visible, Relation relation, HeapTuple tuple, Buffer buffer, Snapshot snapshot)
Definition: predicate.c:3862
#define HeapTupleSatisfiesVisibility(tuple, snapshot, buffer)
Definition: tqual.h:45
uint16 OffsetNumber
Definition: off.h:24
HeapTupleHeader t_data
Definition: htup.h:67
BlockNumber blockno
Definition: tidbitmap.h:40
bool heap_hot_search_buffer(ItemPointer tid, Relation relation, Buffer buffer, Snapshot snapshot, HeapTuple heapTuple, bool *all_dead, bool first_call)
Definition: heapam.c:1984
#define ItemIdGetLength(itemId)
Definition: itemid.h:58
ItemPointerData t_self
Definition: htup.h:65
uint32 t_len
Definition: htup.h:64
OffsetNumber offsets[FLEXIBLE_ARRAY_MEMBER]
Definition: tidbitmap.h:44
#define FirstOffsetNumber
Definition: off.h:27
Snapshot rs_snapshot
Definition: relscan.h:48
Oid t_tableOid
Definition: htup.h:66
#define BufferGetPage(buffer)
Definition: bufmgr.h:160
Oid rd_id
Definition: rel.h:115
#define PageGetItemId(page, offsetNumber)
Definition: bufpage.h:232
void LockBuffer(Buffer buffer, int mode)
Definition: bufmgr.c:3529
Relation rs_rd
Definition: relscan.h:47
Buffer rs_cbuf
Definition: relscan.h:70
#define NULL
Definition: c.h:226
#define Assert(condition)
Definition: c.h:671
OffsetNumber rs_vistuples[MaxHeapTuplesPerPage]
Definition: relscan.h:77
#define ItemIdIsNormal(itemId)
Definition: itemid.h:98
#define OffsetNumberNext(offsetNumber)
Definition: off.h:53
Buffer ReleaseAndReadBuffer(Buffer buffer, Relation relation, BlockNumber blockNum)
Definition: bufmgr.c:1508
#define ItemPointerGetOffsetNumber(pointer)
Definition: itemptr.h:76
void PredicateLockTuple(Relation relation, HeapTuple tuple, Snapshot snapshot)
Definition: predicate.c:2460
#define BUFFER_LOCK_SHARE
Definition: bufmgr.h:88
void heap_page_prune_opt(Relation relation, Buffer buffer)
Definition: pruneheap.c:75
int Buffer
Definition: buf.h:23
#define PageGetItem(page, itemId)
Definition: bufpage.h:337
Pointer Page
Definition: bufpage.h:74
#define ItemPointerSet(pointer, blockNumber, offNum)
Definition: itemptr.h:86
static TupleTableSlot * BitmapHeapNext ( BitmapHeapScanState node)
static

Definition at line 65 of file nodeBitmapHeapscan.c.

References Assert, bitgetpage(), BitmapHeapScanState::bitmapqualorig, TBMIterateResult::blockno, BufferGetPage, ExprContext::ecxt_scantuple, elog, ERROR, BitmapHeapScanState::exact_pages, ExecClearTuple(), ExecQual(), ExecStoreTuple(), InstrCountFiltered2, IsA, ItemIdGetLength, ItemIdIsNormal, ItemPointerSet, BitmapHeapScanState::lossy_pages, MAIN_FORKNUM, MultiExecProcNode(), TBMIterateResult::ntuples, NULL, outerPlanState, PageGetItem, PageGetItemId, pgstat_count_heap_fetch, BitmapHeapScanState::prefetch_iterator, BitmapHeapScanState::prefetch_maximum, BitmapHeapScanState::prefetch_pages, BitmapHeapScanState::prefetch_target, PrefetchBuffer(), ScanState::ps, PlanState::ps_ExprContext, RelationData::rd_id, TBMIterateResult::recheck, ResetExprContext, HeapScanDescData::rs_cbuf, HeapScanDescData::rs_cindex, HeapScanDescData::rs_ctup, HeapScanDescData::rs_nblocks, HeapScanDescData::rs_ntuples, HeapScanDescData::rs_rd, HeapScanDescData::rs_vistuples, BitmapHeapScanState::ss, ScanState::ss_currentScanDesc, ScanState::ss_ScanTupleSlot, HeapTupleData::t_data, HeapTupleData::t_len, HeapTupleData::t_self, HeapTupleData::t_tableOid, BitmapHeapScanState::tbm, tbm_begin_iterate(), tbm_end_iterate(), tbm_iterate(), BitmapHeapScanState::tbmiterator, and BitmapHeapScanState::tbmres.

Referenced by ExecBitmapHeapScan().

66 {
67  ExprContext *econtext;
68  HeapScanDesc scan;
69  TIDBitmap *tbm;
70  TBMIterator *tbmiterator;
71  TBMIterateResult *tbmres;
72 
73 #ifdef USE_PREFETCH
74  TBMIterator *prefetch_iterator;
75 #endif
76  OffsetNumber targoffset;
77  TupleTableSlot *slot;
78 
79  /*
80  * extract necessary information from index scan node
81  */
82  econtext = node->ss.ps.ps_ExprContext;
83  slot = node->ss.ss_ScanTupleSlot;
84  scan = node->ss.ss_currentScanDesc;
85  tbm = node->tbm;
86  tbmiterator = node->tbmiterator;
87  tbmres = node->tbmres;
88 #ifdef USE_PREFETCH
89  prefetch_iterator = node->prefetch_iterator;
90 #endif
91 
92  /*
93  * If we haven't yet performed the underlying index scan, do it, and begin
94  * the iteration over the bitmap.
95  *
96  * For prefetching, we use *two* iterators, one for the pages we are
97  * actually scanning and another that runs ahead of the first for
98  * prefetching. node->prefetch_pages tracks exactly how many pages ahead
99  * the prefetch iterator is. Also, node->prefetch_target tracks the
100  * desired prefetch distance, which starts small and increases up to the
101  * node->prefetch_maximum. This is to avoid doing a lot of prefetching in
102  * a scan that stops after a few tuples because of a LIMIT.
103  */
104  if (tbm == NULL)
105  {
106  tbm = (TIDBitmap *) MultiExecProcNode(outerPlanState(node));
107 
108  if (!tbm || !IsA(tbm, TIDBitmap))
109  elog(ERROR, "unrecognized result from subplan");
110 
111  node->tbm = tbm;
112  node->tbmiterator = tbmiterator = tbm_begin_iterate(tbm);
113  node->tbmres = tbmres = NULL;
114 
115 #ifdef USE_PREFETCH
116  if (node->prefetch_maximum > 0)
117  {
118  node->prefetch_iterator = prefetch_iterator = tbm_begin_iterate(tbm);
119  node->prefetch_pages = 0;
120  node->prefetch_target = -1;
121  }
122 #endif /* USE_PREFETCH */
123  }
124 
125  for (;;)
126  {
127  Page dp;
128  ItemId lp;
129 
130  /*
131  * Get next page of results if needed
132  */
133  if (tbmres == NULL)
134  {
135  node->tbmres = tbmres = tbm_iterate(tbmiterator);
136  if (tbmres == NULL)
137  {
138  /* no more entries in the bitmap */
139  break;
140  }
141 
142 #ifdef USE_PREFETCH
143  if (node->prefetch_pages > 0)
144  {
145  /* The main iterator has closed the distance by one page */
146  node->prefetch_pages--;
147  }
148  else if (prefetch_iterator)
149  {
150  /* Do not let the prefetch iterator get behind the main one */
151  TBMIterateResult *tbmpre = tbm_iterate(prefetch_iterator);
152 
153  if (tbmpre == NULL || tbmpre->blockno != tbmres->blockno)
154  elog(ERROR, "prefetch and main iterators are out of sync");
155  }
156 #endif /* USE_PREFETCH */
157 
158  /*
159  * Ignore any claimed entries past what we think is the end of the
160  * relation. (This is probably not necessary given that we got at
161  * least AccessShareLock on the table before performing any of the
162  * indexscans, but let's be safe.)
163  */
164  if (tbmres->blockno >= scan->rs_nblocks)
165  {
166  node->tbmres = tbmres = NULL;
167  continue;
168  }
169 
170  /*
171  * Fetch the current heap page and identify candidate tuples.
172  */
173  bitgetpage(scan, tbmres);
174 
175  if (tbmres->ntuples >= 0)
176  node->exact_pages++;
177  else
178  node->lossy_pages++;
179 
180  /*
181  * Set rs_cindex to first slot to examine
182  */
183  scan->rs_cindex = 0;
184 
185 #ifdef USE_PREFETCH
186 
187  /*
188  * Increase prefetch target if it's not yet at the max. Note that
189  * we will increase it to zero after fetching the very first
190  * page/tuple, then to one after the second tuple is fetched, then
191  * it doubles as later pages are fetched.
192  */
193  if (node->prefetch_target >= node->prefetch_maximum)
194  /* don't increase any further */ ;
195  else if (node->prefetch_target >= node->prefetch_maximum / 2)
196  node->prefetch_target = node->prefetch_maximum;
197  else if (node->prefetch_target > 0)
198  node->prefetch_target *= 2;
199  else
200  node->prefetch_target++;
201 #endif /* USE_PREFETCH */
202  }
203  else
204  {
205  /*
206  * Continuing in previously obtained page; advance rs_cindex
207  */
208  scan->rs_cindex++;
209 
210 #ifdef USE_PREFETCH
211 
212  /*
213  * Try to prefetch at least a few pages even before we get to the
214  * second page if we don't stop reading after the first tuple.
215  */
216  if (node->prefetch_target < node->prefetch_maximum)
217  node->prefetch_target++;
218 #endif /* USE_PREFETCH */
219  }
220 
221  /*
222  * Out of range? If so, nothing more to look at on this page
223  */
224  if (scan->rs_cindex < 0 || scan->rs_cindex >= scan->rs_ntuples)
225  {
226  node->tbmres = tbmres = NULL;
227  continue;
228  }
229 
230 #ifdef USE_PREFETCH
231 
232  /*
233  * We issue prefetch requests *after* fetching the current page to try
234  * to avoid having prefetching interfere with the main I/O. Also, this
235  * should happen only when we have determined there is still something
236  * to do on the current page, else we may uselessly prefetch the same
237  * page we are just about to request for real.
238  */
239  if (prefetch_iterator)
240  {
241  while (node->prefetch_pages < node->prefetch_target)
242  {
243  TBMIterateResult *tbmpre = tbm_iterate(prefetch_iterator);
244 
245  if (tbmpre == NULL)
246  {
247  /* No more pages to prefetch */
248  tbm_end_iterate(prefetch_iterator);
249  node->prefetch_iterator = prefetch_iterator = NULL;
250  break;
251  }
252  node->prefetch_pages++;
253  PrefetchBuffer(scan->rs_rd, MAIN_FORKNUM, tbmpre->blockno);
254  }
255  }
256 #endif /* USE_PREFETCH */
257 
258  /*
259  * Okay to fetch the tuple
260  */
261  targoffset = scan->rs_vistuples[scan->rs_cindex];
262  dp = (Page) BufferGetPage(scan->rs_cbuf);
263  lp = PageGetItemId(dp, targoffset);
264  Assert(ItemIdIsNormal(lp));
265 
266  scan->rs_ctup.t_data = (HeapTupleHeader) PageGetItem((Page) dp, lp);
267  scan->rs_ctup.t_len = ItemIdGetLength(lp);
268  scan->rs_ctup.t_tableOid = scan->rs_rd->rd_id;
269  ItemPointerSet(&scan->rs_ctup.t_self, tbmres->blockno, targoffset);
270 
272 
273  /*
274  * Set up the result slot to point to this tuple. Note that the slot
275  * acquires a pin on the buffer.
276  */
277  ExecStoreTuple(&scan->rs_ctup,
278  slot,
279  scan->rs_cbuf,
280  false);
281 
282  /*
283  * If we are using lossy info, we have to recheck the qual conditions
284  * at every tuple.
285  */
286  if (tbmres->recheck)
287  {
288  econtext->ecxt_scantuple = slot;
289  ResetExprContext(econtext);
290 
291  if (!ExecQual(node->bitmapqualorig, econtext, false))
292  {
293  /* Fails recheck, so drop it and loop back for another */
294  InstrCountFiltered2(node, 1);
295  ExecClearTuple(slot);
296  continue;
297  }
298  }
299 
300  /* OK to return this tuple */
301  return slot;
302  }
303 
304  /*
305  * if we get here it means we are at the end of the scan..
306  */
307  return ExecClearTuple(slot);
308 }
TupleTableSlot * ExecStoreTuple(HeapTuple tuple, TupleTableSlot *slot, Buffer buffer, bool shouldFree)
Definition: execTuples.c:320
void tbm_end_iterate(TBMIterator *iterator)
Definition: tidbitmap.c:787
#define IsA(nodeptr, _type_)
Definition: nodes.h:559
HeapTupleHeaderData * HeapTupleHeader
Definition: htup.h:23
static void bitgetpage(HeapScanDesc scan, TBMIterateResult *tbmres)
ExprContext * ps_ExprContext
Definition: execnodes.h:1078
TIDBitmap * tbm
Definition: execnodes.h:1486
TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition: execTuples.c:439
TupleTableSlot * ss_ScanTupleSlot
Definition: execnodes.h:1291
HeapTupleData rs_ctup
Definition: relscan.h:68
uint16 OffsetNumber
Definition: off.h:24
HeapTupleHeader t_data
Definition: htup.h:67
BlockNumber blockno
Definition: tidbitmap.h:40
PlanState ps
Definition: execnodes.h:1288
#define ItemIdGetLength(itemId)
Definition: itemid.h:58
#define ERROR
Definition: elog.h:43
ItemPointerData t_self
Definition: htup.h:65
#define pgstat_count_heap_fetch(rel)
Definition: pgstat.h:1150
#define outerPlanState(node)
Definition: execnodes.h:1090
uint32 t_len
Definition: htup.h:64
bool ExecQual(List *qual, ExprContext *econtext, bool resultForNull)
Definition: execQual.c:5055
Oid t_tableOid
Definition: htup.h:66
#define BufferGetPage(buffer)
Definition: bufmgr.h:160
TBMIterateResult * tbmres
Definition: execnodes.h:1488
Oid rd_id
Definition: rel.h:115
#define PageGetItemId(page, offsetNumber)
Definition: bufpage.h:232
BlockNumber rs_nblocks
Definition: relscan.h:59
void PrefetchBuffer(Relation reln, ForkNumber forkNum, BlockNumber blockNum)
Definition: bufmgr.c:529
Relation rs_rd
Definition: relscan.h:47
TBMIterateResult * tbm_iterate(TBMIterator *iterator)
Definition: tidbitmap.c:680
Buffer rs_cbuf
Definition: relscan.h:70
#define NULL
Definition: c.h:226
#define Assert(condition)
Definition: c.h:671
OffsetNumber rs_vistuples[MaxHeapTuplesPerPage]
Definition: relscan.h:77
#define ItemIdIsNormal(itemId)
Definition: itemid.h:98
#define InstrCountFiltered2(node, delta)
Definition: execnodes.h:1098
TBMIterator * tbm_begin_iterate(TIDBitmap *tbm)
Definition: tidbitmap.c:602
TupleTableSlot * ecxt_scantuple
Definition: execnodes.h:128
TBMIterator * tbmiterator
Definition: execnodes.h:1487
HeapScanDesc ss_currentScanDesc
Definition: execnodes.h:1290
Node * MultiExecProcNode(PlanState *node)
Definition: execProcnode.c:571
TBMIterator * prefetch_iterator
Definition: execnodes.h:1491
#define elog
Definition: elog.h:219
#define PageGetItem(page, itemId)
Definition: bufpage.h:337
Pointer Page
Definition: bufpage.h:74
#define ResetExprContext(econtext)
Definition: executor.h:332
#define ItemPointerSet(pointer, blockNumber, offNum)
Definition: itemptr.h:86
static bool BitmapHeapRecheck ( BitmapHeapScanState node,
TupleTableSlot slot 
)
static

Definition at line 418 of file nodeBitmapHeapscan.c.

References BitmapHeapScanState::bitmapqualorig, ExprContext::ecxt_scantuple, ExecQual(), ScanState::ps, PlanState::ps_ExprContext, ResetExprContext, and BitmapHeapScanState::ss.

Referenced by ExecBitmapHeapScan().

419 {
420  ExprContext *econtext;
421 
422  /*
423  * extract necessary information from index scan node
424  */
425  econtext = node->ss.ps.ps_ExprContext;
426 
427  /* Does the tuple meet the original qual conditions? */
428  econtext->ecxt_scantuple = slot;
429 
430  ResetExprContext(econtext);
431 
432  return ExecQual(node->bitmapqualorig, econtext, false);
433 }
ExprContext * ps_ExprContext
Definition: execnodes.h:1078
PlanState ps
Definition: execnodes.h:1288
bool ExecQual(List *qual, ExprContext *econtext, bool resultForNull)
Definition: execQual.c:5055
TupleTableSlot * ecxt_scantuple
Definition: execnodes.h:128
#define ResetExprContext(econtext)
Definition: executor.h:332
TupleTableSlot* ExecBitmapHeapScan ( BitmapHeapScanState node)

Definition at line 440 of file nodeBitmapHeapscan.c.

References BitmapHeapNext(), BitmapHeapRecheck(), ExecScan(), and BitmapHeapScanState::ss.

Referenced by ExecProcNode().

441 {
442  return ExecScan(&node->ss,
445 }
TupleTableSlot * ExecScan(ScanState *node, ExecScanAccessMtd accessMtd, ExecScanRecheckMtd recheckMtd)
Definition: execScan.c:121
TupleTableSlot *(* ExecScanAccessMtd)(ScanState *node)
Definition: executor.h:271
bool(* ExecScanRecheckMtd)(ScanState *node, TupleTableSlot *slot)
Definition: executor.h:272
static TupleTableSlot * BitmapHeapNext(BitmapHeapScanState *node)
static bool BitmapHeapRecheck(BitmapHeapScanState *node, TupleTableSlot *slot)
void ExecEndBitmapHeapScan ( BitmapHeapScanState node)

Definition at line 485 of file nodeBitmapHeapscan.c.

References ExecClearTuple(), ExecCloseScanRelation(), ExecEndNode(), ExecFreeExprContext(), heap_endscan(), outerPlanState, BitmapHeapScanState::prefetch_iterator, ScanState::ps, PlanState::ps_ResultTupleSlot, BitmapHeapScanState::ss, ScanState::ss_currentRelation, ScanState::ss_currentScanDesc, ScanState::ss_ScanTupleSlot, BitmapHeapScanState::tbm, tbm_end_iterate(), tbm_free(), and BitmapHeapScanState::tbmiterator.

Referenced by ExecEndNode().

486 {
487  Relation relation;
488  HeapScanDesc scanDesc;
489 
490  /*
491  * extract information from the node
492  */
493  relation = node->ss.ss_currentRelation;
494  scanDesc = node->ss.ss_currentScanDesc;
495 
496  /*
497  * Free the exprcontext
498  */
499  ExecFreeExprContext(&node->ss.ps);
500 
501  /*
502  * clear out tuple table slots
503  */
506 
507  /*
508  * close down subplans
509  */
511 
512  /*
513  * release bitmap if any
514  */
515  if (node->tbmiterator)
517  if (node->prefetch_iterator)
519  if (node->tbm)
520  tbm_free(node->tbm);
521 
522  /*
523  * close heap scan
524  */
525  heap_endscan(scanDesc);
526 
527  /*
528  * close the heap relation.
529  */
530  ExecCloseScanRelation(relation);
531 }
void tbm_end_iterate(TBMIterator *iterator)
Definition: tidbitmap.c:787
void heap_endscan(HeapScanDesc scan)
Definition: heapam.c:1581
void ExecEndNode(PlanState *node)
Definition: execProcnode.c:624
TIDBitmap * tbm
Definition: execnodes.h:1486
TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition: execTuples.c:439
TupleTableSlot * ss_ScanTupleSlot
Definition: execnodes.h:1291
Relation ss_currentRelation
Definition: execnodes.h:1289
void ExecFreeExprContext(PlanState *planstate)
Definition: execUtils.c:685
PlanState ps
Definition: execnodes.h:1288
TupleTableSlot * ps_ResultTupleSlot
Definition: execnodes.h:1077
#define outerPlanState(node)
Definition: execnodes.h:1090
void tbm_free(TIDBitmap *tbm)
Definition: tidbitmap.c:272
void ExecCloseScanRelation(Relation scanrel)
Definition: execUtils.c:830
TBMIterator * tbmiterator
Definition: execnodes.h:1487
HeapScanDesc ss_currentScanDesc
Definition: execnodes.h:1290
TBMIterator * prefetch_iterator
Definition: execnodes.h:1491
BitmapHeapScanState* ExecInitBitmapHeapScan ( BitmapHeapScan node,
EState estate,
int  eflags 
)

Definition at line 540 of file nodeBitmapHeapscan.c.

References Assert, BitmapHeapScan::bitmapqualorig, BitmapHeapScanState::bitmapqualorig, ComputeIoConcurrency(), effective_io_concurrency, EState::es_snapshot, BitmapHeapScanState::exact_pages, EXEC_FLAG_BACKWARD, EXEC_FLAG_MARK, ExecAssignExprContext(), ExecAssignResultTypeFromTL(), ExecAssignScanProjectionInfo(), ExecAssignScanType(), ExecInitExpr(), ExecInitNode(), ExecInitResultTupleSlot(), ExecInitScanTupleSlot(), ExecOpenScanRelation(), get_tablespace_io_concurrency(), heap_beginscan_bm(), IsMVCCSnapshot, BitmapHeapScanState::lossy_pages, makeNode, NULL, outerPlan, outerPlanState, Scan::plan, PlanState::plan, BitmapHeapScanState::prefetch_iterator, BitmapHeapScanState::prefetch_maximum, BitmapHeapScanState::prefetch_pages, BitmapHeapScanState::prefetch_target, ScanState::ps, Plan::qual, PlanState::qual, RelationData::rd_rel, RelationGetDescr, rint(), BitmapHeapScan::scan, Scan::scanrelid, BitmapHeapScanState::ss, ScanState::ss_currentRelation, ScanState::ss_currentScanDesc, PlanState::state, target_prefetch_pages, Plan::targetlist, PlanState::targetlist, BitmapHeapScanState::tbm, BitmapHeapScanState::tbmiterator, and BitmapHeapScanState::tbmres.

Referenced by ExecInitNode().

541 {
542  BitmapHeapScanState *scanstate;
543  Relation currentRelation;
544  int io_concurrency;
545 
546  /* check for unsupported flags */
547  Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK)));
548 
549  /*
550  * Assert caller didn't ask for an unsafe snapshot --- see comments at
551  * head of file.
552  */
554 
555  /*
556  * create state structure
557  */
558  scanstate = makeNode(BitmapHeapScanState);
559  scanstate->ss.ps.plan = (Plan *) node;
560  scanstate->ss.ps.state = estate;
561 
562  scanstate->tbm = NULL;
563  scanstate->tbmiterator = NULL;
564  scanstate->tbmres = NULL;
565  scanstate->exact_pages = 0;
566  scanstate->lossy_pages = 0;
567  scanstate->prefetch_iterator = NULL;
568  scanstate->prefetch_pages = 0;
569  scanstate->prefetch_target = 0;
570  /* may be updated below */
572 
573  /*
574  * Miscellaneous initialization
575  *
576  * create expression context for node
577  */
578  ExecAssignExprContext(estate, &scanstate->ss.ps);
579 
580  /*
581  * initialize child expressions
582  */
583  scanstate->ss.ps.targetlist = (List *)
585  (PlanState *) scanstate);
586  scanstate->ss.ps.qual = (List *)
587  ExecInitExpr((Expr *) node->scan.plan.qual,
588  (PlanState *) scanstate);
589  scanstate->bitmapqualorig = (List *)
590  ExecInitExpr((Expr *) node->bitmapqualorig,
591  (PlanState *) scanstate);
592 
593  /*
594  * tuple table initialization
595  */
596  ExecInitResultTupleSlot(estate, &scanstate->ss.ps);
597  ExecInitScanTupleSlot(estate, &scanstate->ss);
598 
599  /*
600  * open the base relation and acquire appropriate lock on it.
601  */
602  currentRelation = ExecOpenScanRelation(estate, node->scan.scanrelid, eflags);
603 
604  /*
605  * Determine the maximum for prefetch_target. If the tablespace has a
606  * specific IO concurrency set, use that to compute the corresponding
607  * maximum value; otherwise, we already initialized to the value computed
608  * by the GUC machinery.
609  */
610  io_concurrency =
611  get_tablespace_io_concurrency(currentRelation->rd_rel->reltablespace);
612  if (io_concurrency != effective_io_concurrency)
613  {
614  double maximum;
615 
616  if (ComputeIoConcurrency(io_concurrency, &maximum))
617  scanstate->prefetch_maximum = rint(maximum);
618  }
619 
620  scanstate->ss.ss_currentRelation = currentRelation;
621 
622  /*
623  * Even though we aren't going to do a conventional seqscan, it is useful
624  * to create a HeapScanDesc --- most of the fields in it are usable.
625  */
626  scanstate->ss.ss_currentScanDesc = heap_beginscan_bm(currentRelation,
627  estate->es_snapshot,
628  0,
629  NULL);
630 
631  /*
632  * get the scan type from the relation descriptor.
633  */
634  ExecAssignScanType(&scanstate->ss, RelationGetDescr(currentRelation));
635 
636  /*
637  * Initialize result tuple type and projection info.
638  */
639  ExecAssignResultTypeFromTL(&scanstate->ss.ps);
640  ExecAssignScanProjectionInfo(&scanstate->ss);
641 
642  /*
643  * initialize child nodes
644  *
645  * We do this last because the child nodes will open indexscans on our
646  * relation's indexes, and we want to be sure we have acquired a lock on
647  * the relation first.
648  */
649  outerPlanState(scanstate) = ExecInitNode(outerPlan(node), estate, eflags);
650 
651  /*
652  * all done.
653  */
654  return scanstate;
655 }
List * qual
Definition: plannodes.h:130
int target_prefetch_pages
Definition: bufmgr.c:129
Plan plan
Definition: plannodes.h:305
void ExecInitScanTupleSlot(EState *estate, ScanState *scanstate)
Definition: execTuples.c:842
Index scanrelid
Definition: plannodes.h:306
#define RelationGetDescr(relation)
Definition: rel.h:425
TIDBitmap * tbm
Definition: execnodes.h:1486
List * qual
Definition: execnodes.h:1062
int get_tablespace_io_concurrency(Oid spcid)
Definition: spccache.c:204
List * targetlist
Definition: execnodes.h:1061
Snapshot es_snapshot
Definition: execnodes.h:370
Relation ss_currentRelation
Definition: execnodes.h:1289
EState * state
Definition: execnodes.h:1049
Form_pg_class rd_rel
Definition: rel.h:113
int effective_io_concurrency
Definition: bufmgr.c:112
void ExecAssignResultTypeFromTL(PlanState *planstate)
Definition: execUtils.c:430
bool ComputeIoConcurrency(int io_concurrency, double *target)
Definition: bufmgr.c:467
PlanState ps
Definition: execnodes.h:1288
ExprState * ExecInitExpr(Expr *node, PlanState *parent)
Definition: execQual.c:4266
void ExecAssignScanProjectionInfo(ScanState *node)
Definition: execScan.c:235
void ExecInitResultTupleSlot(EState *estate, PlanState *planstate)
Definition: execTuples.c:832
Relation ExecOpenScanRelation(EState *estate, Index scanrelid, int eflags)
Definition: execUtils.c:772
#define EXEC_FLAG_BACKWARD
Definition: executor.h:60
#define outerPlanState(node)
Definition: execnodes.h:1090
double rint(double x)
Definition: rint.c:22
List * bitmapqualorig
Definition: plannodes.h:439
TBMIterateResult * tbmres
Definition: execnodes.h:1488
#define outerPlan(node)
Definition: plannodes.h:159
HeapScanDesc heap_beginscan_bm(Relation relation, Snapshot snapshot, int nkeys, ScanKey key)
Definition: heapam.c:1422
Plan * plan
Definition: execnodes.h:1047
#define makeNode(_type_)
Definition: nodes.h:556
#define NULL
Definition: c.h:226
#define Assert(condition)
Definition: c.h:671
#define IsMVCCSnapshot(snapshot)
Definition: tqual.h:31
#define EXEC_FLAG_MARK
Definition: executor.h:61
void ExecAssignExprContext(EState *estate, PlanState *planstate)
Definition: execUtils.c:408
TBMIterator * tbmiterator
Definition: execnodes.h:1487
List * targetlist
Definition: plannodes.h:129
HeapScanDesc ss_currentScanDesc
Definition: execnodes.h:1290
TBMIterator * prefetch_iterator
Definition: execnodes.h:1491
void ExecAssignScanType(ScanState *scanstate, TupleDesc tupDesc)
Definition: execUtils.c:709
PlanState * ExecInitNode(Plan *node, EState *estate, int eflags)
Definition: execProcnode.c:137
Definition: pg_list.h:45
void ExecReScanBitmapHeapScan ( BitmapHeapScanState node)

Definition at line 452 of file nodeBitmapHeapscan.c.

References PlanState::chgParam, ExecReScan(), ExecScanReScan(), heap_rescan(), NULL, outerPlan, outerPlanState, BitmapHeapScanState::prefetch_iterator, BitmapHeapScanState::ss, ScanState::ss_currentScanDesc, BitmapHeapScanState::tbm, tbm_end_iterate(), tbm_free(), BitmapHeapScanState::tbmiterator, and BitmapHeapScanState::tbmres.

Referenced by ExecReScan().

453 {
455 
456  /* rescan to release any page pin */
458 
459  if (node->tbmiterator)
461  if (node->prefetch_iterator)
463  if (node->tbm)
464  tbm_free(node->tbm);
465  node->tbm = NULL;
466  node->tbmiterator = NULL;
467  node->tbmres = NULL;
468  node->prefetch_iterator = NULL;
469 
470  ExecScanReScan(&node->ss);
471 
472  /*
473  * if chgParam of subnode is not null then plan will be re-scanned by
474  * first ExecProcNode.
475  */
476  if (outerPlan->chgParam == NULL)
477  ExecReScan(outerPlan);
478 }
void tbm_end_iterate(TBMIterator *iterator)
Definition: tidbitmap.c:787
TIDBitmap * tbm
Definition: execnodes.h:1486
void ExecReScan(PlanState *node)
Definition: execAmi.c:73
#define outerPlanState(node)
Definition: execnodes.h:1090
void tbm_free(TIDBitmap *tbm)
Definition: tidbitmap.c:272
void heap_rescan(HeapScanDesc scan, ScanKey key)
Definition: heapam.c:1518
TBMIterateResult * tbmres
Definition: execnodes.h:1488
Bitmapset * chgParam
Definition: execnodes.h:1072
#define outerPlan(node)
Definition: plannodes.h:159
#define NULL
Definition: c.h:226
TBMIterator * tbmiterator
Definition: execnodes.h:1487
HeapScanDesc ss_currentScanDesc
Definition: execnodes.h:1290
TBMIterator * prefetch_iterator
Definition: execnodes.h:1491
void ExecScanReScan(ScanState *node)
Definition: execScan.c:327