PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
nodeTidscan.c File Reference
#include "postgres.h"
#include "access/sysattr.h"
#include "catalog/pg_type.h"
#include "executor/execdebug.h"
#include "executor/nodeTidscan.h"
#include "optimizer/clauses.h"
#include "storage/bufmgr.h"
#include "utils/array.h"
#include "utils/rel.h"
Include dependency graph for nodeTidscan.c:

Go to the source code of this file.

Macros

#define IsCTIDVar(node)
 

Functions

static void TidListCreate (TidScanState *tidstate)
 
static int itemptr_comparator (const void *a, const void *b)
 
static TupleTableSlotTidNext (TidScanState *node)
 
static bool TidRecheck (TidScanState *node, TupleTableSlot *slot)
 
TupleTableSlotExecTidScan (TidScanState *node)
 
void ExecReScanTidScan (TidScanState *node)
 
void ExecEndTidScan (TidScanState *node)
 
TidScanStateExecInitTidScan (TidScan *node, EState *estate, int eflags)
 

Macro Definition Documentation

#define IsCTIDVar (   node)
Value:
((node) != NULL && \
IsA((node), Var) && \
((Var *) (node))->varattno == SelfItemPointerAttributeNumber && \
((Var *) (node))->varlevelsup == 0)
#define IsA(nodeptr, _type_)
Definition: nodes.h:560
Definition: primnodes.h:141
struct Var Var
#define NULL
Definition: c.h:226
#define SelfItemPointerAttributeNumber
Definition: sysattr.h:21

Definition at line 35 of file nodeTidscan.c.

Referenced by TidListCreate().

Function Documentation

void ExecEndTidScan ( TidScanState node)

Definition at line 420 of file nodeTidscan.c.

References ExecClearTuple(), ExecCloseScanRelation(), ExecFreeExprContext(), ScanState::ps, PlanState::ps_ResultTupleSlot, TidScanState::ss, ScanState::ss_currentRelation, and ScanState::ss_ScanTupleSlot.

Referenced by ExecEndNode().

421 {
422  /*
423  * Free the exprcontext
424  */
425  ExecFreeExprContext(&node->ss.ps);
426 
427  /*
428  * clear out tuple table slots
429  */
432 
433  /*
434  * close the heap relation.
435  */
437 }
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
ScanState ss
Definition: execnodes.h:1508
void ExecCloseScanRelation(Relation scanrel)
Definition: execUtils.c:830
TidScanState* ExecInitTidScan ( TidScan node,
EState estate,
int  eflags 
)

Definition at line 451 of file nodeTidscan.c.

References ExecAssignExprContext(), ExecAssignResultTypeFromTL(), ExecAssignScanProjectionInfo(), ExecAssignScanType(), ExecInitExpr(), ExecInitResultTupleSlot(), ExecInitScanTupleSlot(), ExecOpenScanRelation(), makeNode, NULL, Scan::plan, PlanState::plan, ScanState::ps, Plan::qual, PlanState::qual, RelationGetDescr, TidScan::scan, Scan::scanrelid, TidScanState::ss, ScanState::ss_currentRelation, ScanState::ss_currentScanDesc, PlanState::state, Plan::targetlist, PlanState::targetlist, TidScan::tidquals, TidScanState::tss_NumTids, TidScanState::tss_TidList, TidScanState::tss_TidPtr, and TidScanState::tss_tidquals.

Referenced by ExecInitNode().

452 {
453  TidScanState *tidstate;
454  Relation currentRelation;
455 
456  /*
457  * create state structure
458  */
459  tidstate = makeNode(TidScanState);
460  tidstate->ss.ps.plan = (Plan *) node;
461  tidstate->ss.ps.state = estate;
462 
463  /*
464  * Miscellaneous initialization
465  *
466  * create expression context for node
467  */
468  ExecAssignExprContext(estate, &tidstate->ss.ps);
469 
470  /*
471  * initialize child expressions
472  */
473  tidstate->ss.ps.targetlist = (List *)
475  (PlanState *) tidstate);
476  tidstate->ss.ps.qual = (List *)
477  ExecInitExpr((Expr *) node->scan.plan.qual,
478  (PlanState *) tidstate);
479 
480  tidstate->tss_tidquals = (List *)
481  ExecInitExpr((Expr *) node->tidquals,
482  (PlanState *) tidstate);
483 
484  /*
485  * tuple table initialization
486  */
487  ExecInitResultTupleSlot(estate, &tidstate->ss.ps);
488  ExecInitScanTupleSlot(estate, &tidstate->ss);
489 
490  /*
491  * mark tid list as not computed yet
492  */
493  tidstate->tss_TidList = NULL;
494  tidstate->tss_NumTids = 0;
495  tidstate->tss_TidPtr = -1;
496 
497  /*
498  * open the base relation and acquire appropriate lock on it.
499  */
500  currentRelation = ExecOpenScanRelation(estate, node->scan.scanrelid, eflags);
501 
502  tidstate->ss.ss_currentRelation = currentRelation;
503  tidstate->ss.ss_currentScanDesc = NULL; /* no heap scan here */
504 
505  /*
506  * get the scan type from the relation descriptor.
507  */
508  ExecAssignScanType(&tidstate->ss, RelationGetDescr(currentRelation));
509 
510  /*
511  * Initialize result tuple type and projection info.
512  */
513  ExecAssignResultTypeFromTL(&tidstate->ss.ps);
514  ExecAssignScanProjectionInfo(&tidstate->ss);
515 
516  /*
517  * all done.
518  */
519  return tidstate;
520 }
List * qual
Definition: plannodes.h:130
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
List * tss_tidquals
Definition: execnodes.h:1509
List * tidquals
Definition: plannodes.h:452
List * qual
Definition: execnodes.h:1062
List * targetlist
Definition: execnodes.h:1061
Relation ss_currentRelation
Definition: execnodes.h:1289
EState * state
Definition: execnodes.h:1049
void ExecAssignResultTypeFromTL(PlanState *planstate)
Definition: execUtils.c:430
PlanState ps
Definition: execnodes.h:1288
ExprState * ExecInitExpr(Expr *node, PlanState *parent)
Definition: execQual.c:4266
ScanState ss
Definition: execnodes.h:1508
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
ItemPointerData * tss_TidList
Definition: execnodes.h:1513
Plan * plan
Definition: execnodes.h:1047
#define makeNode(_type_)
Definition: nodes.h:557
#define NULL
Definition: c.h:226
Scan scan
Definition: plannodes.h:451
void ExecAssignExprContext(EState *estate, PlanState *planstate)
Definition: execUtils.c:408
List * targetlist
Definition: plannodes.h:129
HeapScanDesc ss_currentScanDesc
Definition: execnodes.h:1290
void ExecAssignScanType(ScanState *scanstate, TupleDesc tupDesc)
Definition: execUtils.c:709
Definition: pg_list.h:45
void ExecReScanTidScan ( TidScanState node)

Definition at line 401 of file nodeTidscan.c.

References ExecScanReScan(), NULL, pfree(), TidScanState::ss, TidScanState::tss_NumTids, TidScanState::tss_TidList, and TidScanState::tss_TidPtr.

Referenced by ExecReScan().

402 {
403  if (node->tss_TidList)
404  pfree(node->tss_TidList);
405  node->tss_TidList = NULL;
406  node->tss_NumTids = 0;
407  node->tss_TidPtr = -1;
408 
409  ExecScanReScan(&node->ss);
410 }
void pfree(void *pointer)
Definition: mcxt.c:992
ScanState ss
Definition: execnodes.h:1508
ItemPointerData * tss_TidList
Definition: execnodes.h:1513
#define NULL
Definition: c.h:226
void ExecScanReScan(ScanState *node)
Definition: execScan.c:327
TupleTableSlot* ExecTidScan ( TidScanState node)

Definition at line 389 of file nodeTidscan.c.

References ExecScan(), TidScanState::ss, TidNext(), and TidRecheck().

Referenced by ExecProcNode().

390 {
391  return ExecScan(&node->ss,
394 }
static TupleTableSlot * TidNext(TidScanState *node)
Definition: nodeTidscan.c:249
TupleTableSlot * ExecScan(ScanState *node, ExecScanAccessMtd accessMtd, ExecScanRecheckMtd recheckMtd)
Definition: execScan.c:121
static bool TidRecheck(TidScanState *node, TupleTableSlot *slot)
Definition: nodeTidscan.c:359
TupleTableSlot *(* ExecScanAccessMtd)(ScanState *node)
Definition: executor.h:271
bool(* ExecScanRecheckMtd)(ScanState *node, TupleTableSlot *slot)
Definition: executor.h:272
ScanState ss
Definition: execnodes.h:1508
static int itemptr_comparator ( const void *  a,
const void *  b 
)
static

Definition at line 220 of file nodeTidscan.c.

References ItemPointerGetBlockNumber, and ItemPointerGetOffsetNumber.

Referenced by TidListCreate().

221 {
222  const ItemPointerData *ipa = (const ItemPointerData *) a;
223  const ItemPointerData *ipb = (const ItemPointerData *) b;
228 
229  if (ba < bb)
230  return -1;
231  if (ba > bb)
232  return 1;
233  if (oa < ob)
234  return -1;
235  if (oa > ob)
236  return 1;
237  return 0;
238 }
uint32 BlockNumber
Definition: block.h:31
uint16 OffsetNumber
Definition: off.h:24
#define ItemPointerGetOffsetNumber(pointer)
Definition: itemptr.h:76
#define ItemPointerGetBlockNumber(pointer)
Definition: itemptr.h:66
static void TidListCreate ( TidScanState tidstate)
static

Definition at line 53 of file nodeTidscan.c.

References FuncExprState::args, Assert, DatumGetArrayTypeP, DatumGetPointer, deconstruct_array(), elog, ERROR, execCurrentOf(), ExecEvalExprSwitchContext(), ExprState::expr, ScalarArrayOpExprState::fxprstate, get_leftop(), get_rightop(), i, is_opclause, IsA, IsCTIDVar, ItemPointerEquals(), ItemPointerGetBlockNumber, ItemPointerIsValid, itemptr_comparator(), lfirst, linitial, list_length(), lsecond, palloc(), pfree(), ScanState::ps, PlanState::ps_ExprContext, qsort, RelationGetNumberOfBlocks, RelationGetRelid, repalloc(), TidScanState::ss, ScanState::ss_currentRelation, TIDOID, TidScanState::tss_isCurrentOf, TidScanState::tss_NumTids, TidScanState::tss_TidList, TidScanState::tss_TidPtr, and TidScanState::tss_tidquals.

Referenced by TidNext().

54 {
55  List *evalList = tidstate->tss_tidquals;
56  ExprContext *econtext = tidstate->ss.ps.ps_ExprContext;
57  BlockNumber nblocks;
58  ItemPointerData *tidList;
59  int numAllocTids;
60  int numTids;
61  ListCell *l;
62 
63  /*
64  * We silently discard any TIDs that are out of range at the time of scan
65  * start. (Since we hold at least AccessShareLock on the table, it won't
66  * be possible for someone to truncate away the blocks we intend to
67  * visit.)
68  */
69  nblocks = RelationGetNumberOfBlocks(tidstate->ss.ss_currentRelation);
70 
71  /*
72  * We initialize the array with enough slots for the case that all quals
73  * are simple OpExprs or CurrentOfExprs. If there are any
74  * ScalarArrayOpExprs, we may have to enlarge the array.
75  */
76  numAllocTids = list_length(evalList);
77  tidList = (ItemPointerData *)
78  palloc(numAllocTids * sizeof(ItemPointerData));
79  numTids = 0;
80  tidstate->tss_isCurrentOf = false;
81 
82  foreach(l, evalList)
83  {
84  ExprState *exstate = (ExprState *) lfirst(l);
85  Expr *expr = exstate->expr;
86  ItemPointer itemptr;
87  bool isNull;
88 
89  if (is_opclause(expr))
90  {
91  FuncExprState *fexstate = (FuncExprState *) exstate;
92  Node *arg1;
93  Node *arg2;
94 
95  arg1 = get_leftop(expr);
96  arg2 = get_rightop(expr);
97  if (IsCTIDVar(arg1))
98  exstate = (ExprState *) lsecond(fexstate->args);
99  else if (IsCTIDVar(arg2))
100  exstate = (ExprState *) linitial(fexstate->args);
101  else
102  elog(ERROR, "could not identify CTID variable");
103 
104  itemptr = (ItemPointer)
106  econtext,
107  &isNull));
108  if (!isNull &&
109  ItemPointerIsValid(itemptr) &&
110  ItemPointerGetBlockNumber(itemptr) < nblocks)
111  {
112  if (numTids >= numAllocTids)
113  {
114  numAllocTids *= 2;
115  tidList = (ItemPointerData *)
116  repalloc(tidList,
117  numAllocTids * sizeof(ItemPointerData));
118  }
119  tidList[numTids++] = *itemptr;
120  }
121  }
122  else if (expr && IsA(expr, ScalarArrayOpExpr))
123  {
124  ScalarArrayOpExprState *saexstate = (ScalarArrayOpExprState *) exstate;
125  Datum arraydatum;
126  ArrayType *itemarray;
127  Datum *ipdatums;
128  bool *ipnulls;
129  int ndatums;
130  int i;
131 
132  exstate = (ExprState *) lsecond(saexstate->fxprstate.args);
133  arraydatum = ExecEvalExprSwitchContext(exstate,
134  econtext,
135  &isNull);
136  if (isNull)
137  continue;
138  itemarray = DatumGetArrayTypeP(arraydatum);
139  deconstruct_array(itemarray,
140  TIDOID, sizeof(ItemPointerData), false, 's',
141  &ipdatums, &ipnulls, &ndatums);
142  if (numTids + ndatums > numAllocTids)
143  {
144  numAllocTids = numTids + ndatums;
145  tidList = (ItemPointerData *)
146  repalloc(tidList,
147  numAllocTids * sizeof(ItemPointerData));
148  }
149  for (i = 0; i < ndatums; i++)
150  {
151  if (!ipnulls[i])
152  {
153  itemptr = (ItemPointer) DatumGetPointer(ipdatums[i]);
154  if (ItemPointerIsValid(itemptr) &&
155  ItemPointerGetBlockNumber(itemptr) < nblocks)
156  tidList[numTids++] = *itemptr;
157  }
158  }
159  pfree(ipdatums);
160  pfree(ipnulls);
161  }
162  else if (expr && IsA(expr, CurrentOfExpr))
163  {
164  CurrentOfExpr *cexpr = (CurrentOfExpr *) expr;
165  ItemPointerData cursor_tid;
166 
167  if (execCurrentOf(cexpr, econtext,
169  &cursor_tid))
170  {
171  if (numTids >= numAllocTids)
172  {
173  numAllocTids *= 2;
174  tidList = (ItemPointerData *)
175  repalloc(tidList,
176  numAllocTids * sizeof(ItemPointerData));
177  }
178  tidList[numTids++] = cursor_tid;
179  tidstate->tss_isCurrentOf = true;
180  }
181  }
182  else
183  elog(ERROR, "could not identify CTID expression");
184  }
185 
186  /*
187  * Sort the array of TIDs into order, and eliminate duplicates.
188  * Eliminating duplicates is necessary since we want OR semantics across
189  * the list. Sorting makes it easier to detect duplicates, and as a bonus
190  * ensures that we will visit the heap in the most efficient way.
191  */
192  if (numTids > 1)
193  {
194  int lastTid;
195  int i;
196 
197  /* CurrentOfExpr could never appear OR'd with something else */
198  Assert(!tidstate->tss_isCurrentOf);
199 
200  qsort((void *) tidList, numTids, sizeof(ItemPointerData),
202  lastTid = 0;
203  for (i = 1; i < numTids; i++)
204  {
205  if (!ItemPointerEquals(&tidList[lastTid], &tidList[i]))
206  tidList[++lastTid] = tidList[i];
207  }
208  numTids = lastTid + 1;
209  }
210 
211  tidstate->tss_TidList = tidList;
212  tidstate->tss_NumTids = numTids;
213  tidstate->tss_TidPtr = -1;
214 }
#define ItemPointerIsValid(pointer)
Definition: itemptr.h:59
#define IsA(nodeptr, _type_)
Definition: nodes.h:560
List * tss_tidquals
Definition: execnodes.h:1509
List * args
Definition: execnodes.h:697
ExprContext * ps_ExprContext
Definition: execnodes.h:1078
Definition: nodes.h:509
uint32 BlockNumber
Definition: block.h:31
Relation ss_currentRelation
Definition: execnodes.h:1289
#define lsecond(l)
Definition: pg_list.h:114
Datum ExecEvalExprSwitchContext(ExprState *expression, ExprContext *econtext, bool *isNull)
Definition: execQual.c:4219
ItemPointerData * ItemPointer
Definition: itemptr.h:48
PlanState ps
Definition: execnodes.h:1288
#define TIDOID
Definition: pg_type.h:332
void pfree(void *pointer)
Definition: mcxt.c:992
#define linitial(l)
Definition: pg_list.h:110
#define ERROR
Definition: elog.h:43
ScanState ss
Definition: execnodes.h:1508
Expr * expr
Definition: execnodes.h:598
#define is_opclause(clause)
Definition: clauses.h:20
Node * get_leftop(const Expr *clause)
Definition: clauses.c:198
ItemPointerData * tss_TidList
Definition: execnodes.h:1513
bool tss_isCurrentOf
Definition: execnodes.h:1510
static int itemptr_comparator(const void *a, const void *b)
Definition: nodeTidscan.c:220
uintptr_t Datum
Definition: postgres.h:374
#define RelationGetNumberOfBlocks(reln)
Definition: bufmgr.h:199
#define Assert(condition)
Definition: c.h:671
#define lfirst(lc)
Definition: pg_list.h:106
FuncExprState fxprstate
Definition: execnodes.h:761
static int list_length(const List *l)
Definition: pg_list.h:89
#define IsCTIDVar(node)
Definition: nodeTidscan.c:35
bool ItemPointerEquals(ItemPointer pointer1, ItemPointer pointer2)
Definition: itemptr.c:29
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1021
Node * get_rightop(const Expr *clause)
Definition: clauses.c:215
bool execCurrentOf(CurrentOfExpr *cexpr, ExprContext *econtext, Oid table_oid, ItemPointer current_tid)
Definition: execCurrent.c:41
#define DatumGetPointer(X)
Definition: postgres.h:557
void deconstruct_array(ArrayType *array, Oid elmtype, int elmlen, bool elmbyval, char elmalign, Datum **elemsp, bool **nullsp, int *nelemsp)
Definition: arrayfuncs.c:3475
void * palloc(Size size)
Definition: mcxt.c:891
int i
#define elog
Definition: elog.h:219
#define ItemPointerGetBlockNumber(pointer)
Definition: itemptr.h:66
#define qsort(a, b, c, d)
Definition: port.h:440
Definition: pg_list.h:45
#define RelationGetRelid(relation)
Definition: rel.h:413
#define DatumGetArrayTypeP(X)
Definition: array.h:242
static TupleTableSlot * TidNext ( TidScanState node)
static

Definition at line 249 of file nodeTidscan.c.

References EState::es_direction, EState::es_snapshot, ExecClearTuple(), ExecStoreTuple(), heap_fetch(), heap_get_latest_tid(), InvalidBuffer, NULL, ScanState::ps, ReleaseBuffer(), ScanDirectionIsBackward, TidScanState::ss, ScanState::ss_currentRelation, ScanState::ss_ScanTupleSlot, PlanState::state, HeapTupleData::t_self, TidListCreate(), TidScanState::tss_htup, TidScanState::tss_isCurrentOf, TidScanState::tss_NumTids, TidScanState::tss_TidList, and TidScanState::tss_TidPtr.

Referenced by ExecTidScan().

250 {
251  EState *estate;
252  ScanDirection direction;
253  Snapshot snapshot;
254  Relation heapRelation;
255  HeapTuple tuple;
256  TupleTableSlot *slot;
257  Buffer buffer = InvalidBuffer;
258  ItemPointerData *tidList;
259  int numTids;
260  bool bBackward;
261 
262  /*
263  * extract necessary information from tid scan node
264  */
265  estate = node->ss.ps.state;
266  direction = estate->es_direction;
267  snapshot = estate->es_snapshot;
268  heapRelation = node->ss.ss_currentRelation;
269  slot = node->ss.ss_ScanTupleSlot;
270 
271  /*
272  * First time through, compute the list of TIDs to be visited
273  */
274  if (node->tss_TidList == NULL)
275  TidListCreate(node);
276 
277  tidList = node->tss_TidList;
278  numTids = node->tss_NumTids;
279 
280  tuple = &(node->tss_htup);
281 
282  /*
283  * Initialize or advance scan position, depending on direction.
284  */
285  bBackward = ScanDirectionIsBackward(direction);
286  if (bBackward)
287  {
288  if (node->tss_TidPtr < 0)
289  {
290  /* initialize for backward scan */
291  node->tss_TidPtr = numTids - 1;
292  }
293  else
294  node->tss_TidPtr--;
295  }
296  else
297  {
298  if (node->tss_TidPtr < 0)
299  {
300  /* initialize for forward scan */
301  node->tss_TidPtr = 0;
302  }
303  else
304  node->tss_TidPtr++;
305  }
306 
307  while (node->tss_TidPtr >= 0 && node->tss_TidPtr < numTids)
308  {
309  tuple->t_self = tidList[node->tss_TidPtr];
310 
311  /*
312  * For WHERE CURRENT OF, the tuple retrieved from the cursor might
313  * since have been updated; if so, we should fetch the version that is
314  * current according to our snapshot.
315  */
316  if (node->tss_isCurrentOf)
317  heap_get_latest_tid(heapRelation, snapshot, &tuple->t_self);
318 
319  if (heap_fetch(heapRelation, snapshot, tuple, &buffer, false, NULL))
320  {
321  /*
322  * store the scanned tuple in the scan tuple slot of the scan
323  * state. Eventually we will only do this and not return a tuple.
324  * Note: we pass 'false' because tuples returned by amgetnext are
325  * pointers onto disk pages and were not created with palloc() and
326  * so should not be pfree()'d.
327  */
328  ExecStoreTuple(tuple, /* tuple to store */
329  slot, /* slot to store in */
330  buffer, /* buffer associated with tuple */
331  false); /* don't pfree */
332 
333  /*
334  * At this point we have an extra pin on the buffer, because
335  * ExecStoreTuple incremented the pin count. Drop our local pin.
336  */
337  ReleaseBuffer(buffer);
338 
339  return slot;
340  }
341  /* Bad TID or failed snapshot qual; try next */
342  if (bBackward)
343  node->tss_TidPtr--;
344  else
345  node->tss_TidPtr++;
346  }
347 
348  /*
349  * if we get here it means the tid scan failed so we are at the end of the
350  * scan..
351  */
352  return ExecClearTuple(slot);
353 }
TupleTableSlot * ExecStoreTuple(HeapTuple tuple, TupleTableSlot *slot, Buffer buffer, bool shouldFree)
Definition: execTuples.c:320
bool heap_fetch(Relation relation, Snapshot snapshot, HeapTuple tuple, Buffer *userbuf, bool keep_buf, Relation stats_relation)
Definition: heapam.c:1849
TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition: execTuples.c:439
void heap_get_latest_tid(Relation relation, Snapshot snapshot, ItemPointer tid)
Definition: heapam.c:2154
#define InvalidBuffer
Definition: buf.h:25
Snapshot es_snapshot
Definition: execnodes.h:370
TupleTableSlot * ss_ScanTupleSlot
Definition: execnodes.h:1291
void ReleaseBuffer(Buffer buffer)
Definition: bufmgr.c:3292
Relation ss_currentRelation
Definition: execnodes.h:1289
EState * state
Definition: execnodes.h:1049
ScanDirection es_direction
Definition: execnodes.h:369
HeapTupleData tss_htup
Definition: execnodes.h:1514
PlanState ps
Definition: execnodes.h:1288
#define ScanDirectionIsBackward(direction)
Definition: sdir.h:41
ScanState ss
Definition: execnodes.h:1508
ItemPointerData t_self
Definition: htup.h:65
ItemPointerData * tss_TidList
Definition: execnodes.h:1513
ScanDirection
Definition: sdir.h:22
bool tss_isCurrentOf
Definition: execnodes.h:1510
static void TidListCreate(TidScanState *tidstate)
Definition: nodeTidscan.c:53
#define NULL
Definition: c.h:226
int Buffer
Definition: buf.h:23
static bool TidRecheck ( TidScanState node,
TupleTableSlot slot 
)
static

Definition at line 359 of file nodeTidscan.c.

Referenced by ExecTidScan().

360 {
361  /*
362  * XXX shouldn't we check here to make sure tuple matches TID list? In
363  * runtime-key case this is not certain, is it? However, in the WHERE
364  * CURRENT OF case it might not match anyway ...
365  */
366  return true;
367 }