PostgreSQL Source Code  git master
nodeTidscan.c File Reference
#include "postgres.h"
#include "access/sysattr.h"
#include "access/tableam.h"
#include "catalog/pg_type.h"
#include "executor/execdebug.h"
#include "executor/nodeTidscan.h"
#include "lib/qunique.h"
#include "miscadmin.h"
#include "nodes/nodeFuncs.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.

Data Structures

struct  TidExpr
 

Macros

#define IsCTIDVar(node)
 

Typedefs

typedef struct TidExpr TidExpr
 

Functions

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

Macro Definition Documentation

◆ IsCTIDVar

#define IsCTIDVar (   node)
Value:
((node) != NULL && \
IsA((node), Var) && \
((Var *) (node))->varattno == SelfItemPointerAttributeNumber)
#define IsA(nodeptr, _type_)
Definition: nodes.h:162
struct Var Var
Definition: primnodes.h:205
#define SelfItemPointerAttributeNumber
Definition: sysattr.h:21

Definition at line 44 of file nodeTidscan.c.

Typedef Documentation

◆ TidExpr

typedef struct TidExpr TidExpr

Function Documentation

◆ ExecEndTidScan()

void ExecEndTidScan ( TidScanState node)

Definition at line 471 of file nodeTidscan.c.

472 {
473  if (node->ss.ss_currentScanDesc)
475 
476  /*
477  * Free the exprcontext
478  */
479  ExecFreeExprContext(&node->ss.ps);
480 
481  /*
482  * clear out tuple table slots
483  */
484  if (node->ss.ps.ps_ResultTupleSlot)
487 }
void ExecFreeExprContext(PlanState *planstate)
Definition: execUtils.c:651
TupleTableSlot * ps_ResultTupleSlot
Definition: execnodes.h:1062
TupleTableSlot * ss_ScanTupleSlot
Definition: execnodes.h:1452
PlanState ps
Definition: execnodes.h:1449
struct TableScanDescData * ss_currentScanDesc
Definition: execnodes.h:1451
ScanState ss
Definition: execnodes.h:1737
static void table_endscan(TableScanDesc scan)
Definition: tableam.h:993
static TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition: tuptable.h:433

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

Referenced by ExecEndNode().

◆ ExecInitTidScan()

TidScanState* ExecInitTidScan ( TidScan node,
EState estate,
int  eflags 
)

Definition at line 501 of file nodeTidscan.c.

502 {
503  TidScanState *tidstate;
504  Relation currentRelation;
505 
506  /*
507  * create state structure
508  */
509  tidstate = makeNode(TidScanState);
510  tidstate->ss.ps.plan = (Plan *) node;
511  tidstate->ss.ps.state = estate;
512  tidstate->ss.ps.ExecProcNode = ExecTidScan;
513 
514  /*
515  * Miscellaneous initialization
516  *
517  * create expression context for node
518  */
519  ExecAssignExprContext(estate, &tidstate->ss.ps);
520 
521  /*
522  * mark tid list as not computed yet
523  */
524  tidstate->tss_TidList = NULL;
525  tidstate->tss_NumTids = 0;
526  tidstate->tss_TidPtr = -1;
527 
528  /*
529  * open the scan relation
530  */
531  currentRelation = ExecOpenScanRelation(estate, node->scan.scanrelid, eflags);
532 
533  tidstate->ss.ss_currentRelation = currentRelation;
534  tidstate->ss.ss_currentScanDesc = NULL; /* no heap scan here */
535 
536  /*
537  * get the scan type from the relation descriptor.
538  */
539  ExecInitScanTupleSlot(estate, &tidstate->ss,
540  RelationGetDescr(currentRelation),
541  table_slot_callbacks(currentRelation));
542 
543  /*
544  * Initialize result type and projection.
545  */
546  ExecInitResultTypeTL(&tidstate->ss.ps);
547  ExecAssignScanProjectionInfo(&tidstate->ss);
548 
549  /*
550  * initialize child expressions
551  */
552  tidstate->ss.ps.qual =
553  ExecInitQual(node->scan.plan.qual, (PlanState *) tidstate);
554 
555  TidExprListCreate(tidstate);
556 
557  /*
558  * all done.
559  */
560  return tidstate;
561 }
ExprState * ExecInitQual(List *qual, PlanState *parent)
Definition: execExpr.c:210
void ExecAssignScanProjectionInfo(ScanState *node)
Definition: execScan.c:272
void ExecInitScanTupleSlot(EState *estate, ScanState *scanstate, TupleDesc tupledesc, const TupleTableSlotOps *tts_ops)
Definition: execTuples.c:1811
void ExecInitResultTypeTL(PlanState *planstate)
Definition: execTuples.c:1755
void ExecAssignExprContext(EState *estate, PlanState *planstate)
Definition: execUtils.c:481
Relation ExecOpenScanRelation(EState *estate, Index scanrelid, int eflags)
Definition: execUtils.c:721
static TupleTableSlot * ExecTidScan(PlanState *pstate)
Definition: nodeTidscan.c:434
static void TidExprListCreate(TidScanState *tidstate)
Definition: nodeTidscan.c:71
#define makeNode(_type_)
Definition: nodes.h:159
#define RelationGetDescr(relation)
Definition: rel.h:527
ExprState * qual
Definition: execnodes.h:1045
Plan * plan
Definition: execnodes.h:1024
EState * state
Definition: execnodes.h:1026
ExecProcNodeMtd ExecProcNode
Definition: execnodes.h:1030
Relation ss_currentRelation
Definition: execnodes.h:1450
Index scanrelid
Definition: plannodes.h:384
ItemPointerData * tss_TidList
Definition: execnodes.h:1742
Scan scan
Definition: plannodes.h:549
const TupleTableSlotOps * table_slot_callbacks(Relation relation)
Definition: tableam.c:58

References ExecAssignExprContext(), ExecAssignScanProjectionInfo(), ExecInitQual(), ExecInitResultTypeTL(), ExecInitScanTupleSlot(), ExecOpenScanRelation(), PlanState::ExecProcNode, ExecTidScan(), makeNode, PlanState::plan, ScanState::ps, PlanState::qual, RelationGetDescr, TidScan::scan, Scan::scanrelid, TidScanState::ss, ScanState::ss_currentRelation, ScanState::ss_currentScanDesc, PlanState::state, table_slot_callbacks(), TidExprListCreate(), TidScanState::tss_NumTids, TidScanState::tss_TidList, and TidScanState::tss_TidPtr.

Referenced by ExecInitNode().

◆ ExecReScanTidScan()

void ExecReScanTidScan ( TidScanState node)

Definition at line 448 of file nodeTidscan.c.

449 {
450  if (node->tss_TidList)
451  pfree(node->tss_TidList);
452  node->tss_TidList = NULL;
453  node->tss_NumTids = 0;
454  node->tss_TidPtr = -1;
455 
456  /* not really necessary, but seems good form */
457  if (node->ss.ss_currentScanDesc)
458  table_rescan(node->ss.ss_currentScanDesc, NULL);
459 
460  ExecScanReScan(&node->ss);
461 }
void ExecScanReScan(ScanState *node)
Definition: execScan.c:299
void pfree(void *pointer)
Definition: mcxt.c:1306
static void table_rescan(TableScanDesc scan, struct ScanKeyData *key)
Definition: tableam.h:1002

References ExecScanReScan(), pfree(), TidScanState::ss, ScanState::ss_currentScanDesc, table_rescan(), TidScanState::tss_NumTids, TidScanState::tss_TidList, and TidScanState::tss_TidPtr.

Referenced by ExecReScan().

◆ ExecTidScan()

static TupleTableSlot* ExecTidScan ( PlanState pstate)
static

Definition at line 434 of file nodeTidscan.c.

435 {
436  TidScanState *node = castNode(TidScanState, pstate);
437 
438  return ExecScan(&node->ss,
441 }
TupleTableSlot * ExecScan(ScanState *node, ExecScanAccessMtd accessMtd, ExecScanRecheckMtd recheckMtd)
Definition: execScan.c:158
TupleTableSlot *(* ExecScanAccessMtd)(ScanState *node)
Definition: executor.h:458
bool(* ExecScanRecheckMtd)(ScanState *node, TupleTableSlot *slot)
Definition: executor.h:459
static bool TidRecheck(TidScanState *node, TupleTableSlot *slot)
Definition: nodeTidscan.c:404
static TupleTableSlot * TidNext(TidScanState *node)
Definition: nodeTidscan.c:313
#define castNode(_type_, nodeptr)
Definition: nodes.h:180

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

Referenced by ExecInitTidScan().

◆ itemptr_comparator()

static int itemptr_comparator ( const void *  a,
const void *  b 
)
static

Definition at line 284 of file nodeTidscan.c.

285 {
286  const ItemPointerData *ipa = (const ItemPointerData *) a;
287  const ItemPointerData *ipb = (const ItemPointerData *) b;
292 
293  if (ba < bb)
294  return -1;
295  if (ba > bb)
296  return 1;
297  if (oa < ob)
298  return -1;
299  if (oa > ob)
300  return 1;
301  return 0;
302 }
uint32 BlockNumber
Definition: block.h:31
int b
Definition: isn.c:70
int a
Definition: isn.c:69
static OffsetNumber ItemPointerGetOffsetNumber(const ItemPointerData *pointer)
Definition: itemptr.h:124
static BlockNumber ItemPointerGetBlockNumber(const ItemPointerData *pointer)
Definition: itemptr.h:103
uint16 OffsetNumber
Definition: off.h:24

References a, b, ItemPointerGetBlockNumber(), and ItemPointerGetOffsetNumber().

Referenced by TidListEval().

◆ TidExprListCreate()

static void TidExprListCreate ( TidScanState tidstate)
static

Definition at line 71 of file nodeTidscan.c.

72 {
73  TidScan *node = (TidScan *) tidstate->ss.ps.plan;
74  ListCell *l;
75 
76  tidstate->tss_tidexprs = NIL;
77  tidstate->tss_isCurrentOf = false;
78 
79  foreach(l, node->tidquals)
80  {
81  Expr *expr = (Expr *) lfirst(l);
82  TidExpr *tidexpr = (TidExpr *) palloc0(sizeof(TidExpr));
83 
84  if (is_opclause(expr))
85  {
86  Node *arg1;
87  Node *arg2;
88 
89  arg1 = get_leftop(expr);
90  arg2 = get_rightop(expr);
91  if (IsCTIDVar(arg1))
92  tidexpr->exprstate = ExecInitExpr((Expr *) arg2,
93  &tidstate->ss.ps);
94  else if (IsCTIDVar(arg2))
95  tidexpr->exprstate = ExecInitExpr((Expr *) arg1,
96  &tidstate->ss.ps);
97  else
98  elog(ERROR, "could not identify CTID variable");
99  tidexpr->isarray = false;
100  }
101  else if (expr && IsA(expr, ScalarArrayOpExpr))
102  {
103  ScalarArrayOpExpr *saex = (ScalarArrayOpExpr *) expr;
104 
105  Assert(IsCTIDVar(linitial(saex->args)));
106  tidexpr->exprstate = ExecInitExpr(lsecond(saex->args),
107  &tidstate->ss.ps);
108  tidexpr->isarray = true;
109  }
110  else if (expr && IsA(expr, CurrentOfExpr))
111  {
112  CurrentOfExpr *cexpr = (CurrentOfExpr *) expr;
113 
114  tidexpr->cexpr = cexpr;
115  tidstate->tss_isCurrentOf = true;
116  }
117  else
118  elog(ERROR, "could not identify CTID expression");
119 
120  tidstate->tss_tidexprs = lappend(tidstate->tss_tidexprs, tidexpr);
121  }
122 
123  /* CurrentOfExpr could never appear OR'd with something else */
124  Assert(list_length(tidstate->tss_tidexprs) == 1 ||
125  !tidstate->tss_isCurrentOf);
126 }
#define ERROR
Definition: elog.h:35
ExprState * ExecInitExpr(Expr *node, PlanState *parent)
Definition: execExpr.c:124
Assert(fmt[strlen(fmt) - 1] !='\n')
List * lappend(List *list, void *datum)
Definition: list.c:338
void * palloc0(Size size)
Definition: mcxt.c:1230
static bool is_opclause(const void *clause)
Definition: nodeFuncs.h:74
static Node * get_rightop(const void *clause)
Definition: nodeFuncs.h:93
static Node * get_leftop(const void *clause)
Definition: nodeFuncs.h:81
#define IsCTIDVar(node)
Definition: nodeTidscan.c:44
#define lfirst(lc)
Definition: pg_list.h:170
static int list_length(const List *l)
Definition: pg_list.h:150
#define NIL
Definition: pg_list.h:66
#define linitial(l)
Definition: pg_list.h:176
#define lsecond(l)
Definition: pg_list.h:181
Definition: nodes.h:112
CurrentOfExpr * cexpr
Definition: nodeTidscan.c:54
ExprState * exprstate
Definition: nodeTidscan.c:52
bool isarray
Definition: nodeTidscan.c:53
bool tss_isCurrentOf
Definition: execnodes.h:1739
List * tss_tidexprs
Definition: execnodes.h:1738
List * tidquals
Definition: plannodes.h:550

References ScalarArrayOpExpr::args, Assert(), TidExpr::cexpr, elog(), ERROR, ExecInitExpr(), TidExpr::exprstate, get_leftop(), get_rightop(), is_opclause(), IsA, TidExpr::isarray, IsCTIDVar, lappend(), lfirst, linitial, list_length(), lsecond, NIL, palloc0(), PlanState::plan, ScanState::ps, TidScanState::ss, TidScan::tidquals, TidScanState::tss_isCurrentOf, and TidScanState::tss_tidexprs.

Referenced by ExecInitTidScan().

◆ TidListEval()

static void TidListEval ( TidScanState tidstate)
static

Definition at line 135 of file nodeTidscan.c.

136 {
137  ExprContext *econtext = tidstate->ss.ps.ps_ExprContext;
138  TableScanDesc scan;
139  ItemPointerData *tidList;
140  int numAllocTids;
141  int numTids;
142  ListCell *l;
143 
144  /*
145  * Start scan on-demand - initializing a scan isn't free (e.g. heap stats
146  * the size of the table), so it makes sense to delay that until needed -
147  * the node might never get executed.
148  */
149  if (tidstate->ss.ss_currentScanDesc == NULL)
150  tidstate->ss.ss_currentScanDesc =
152  tidstate->ss.ps.state->es_snapshot);
153  scan = tidstate->ss.ss_currentScanDesc;
154 
155  /*
156  * We initialize the array with enough slots for the case that all quals
157  * are simple OpExprs or CurrentOfExprs. If there are any
158  * ScalarArrayOpExprs, we may have to enlarge the array.
159  */
160  numAllocTids = list_length(tidstate->tss_tidexprs);
161  tidList = (ItemPointerData *)
162  palloc(numAllocTids * sizeof(ItemPointerData));
163  numTids = 0;
164 
165  foreach(l, tidstate->tss_tidexprs)
166  {
167  TidExpr *tidexpr = (TidExpr *) lfirst(l);
168  ItemPointer itemptr;
169  bool isNull;
170 
171  if (tidexpr->exprstate && !tidexpr->isarray)
172  {
173  itemptr = (ItemPointer)
175  econtext,
176  &isNull));
177  if (isNull)
178  continue;
179 
180  /*
181  * We silently discard any TIDs that the AM considers invalid
182  * (E.g. for heap, they could be out of range at the time of scan
183  * start. Since we hold at least AccessShareLock on the table, it
184  * won't be possible for someone to truncate away the blocks we
185  * intend to visit.).
186  */
187  if (!table_tuple_tid_valid(scan, itemptr))
188  continue;
189 
190  if (numTids >= numAllocTids)
191  {
192  numAllocTids *= 2;
193  tidList = (ItemPointerData *)
194  repalloc(tidList,
195  numAllocTids * sizeof(ItemPointerData));
196  }
197  tidList[numTids++] = *itemptr;
198  }
199  else if (tidexpr->exprstate && tidexpr->isarray)
200  {
201  Datum arraydatum;
202  ArrayType *itemarray;
203  Datum *ipdatums;
204  bool *ipnulls;
205  int ndatums;
206  int i;
207 
208  arraydatum = ExecEvalExprSwitchContext(tidexpr->exprstate,
209  econtext,
210  &isNull);
211  if (isNull)
212  continue;
213  itemarray = DatumGetArrayTypeP(arraydatum);
214  deconstruct_array_builtin(itemarray, TIDOID, &ipdatums, &ipnulls, &ndatums);
215  if (numTids + ndatums > numAllocTids)
216  {
217  numAllocTids = numTids + ndatums;
218  tidList = (ItemPointerData *)
219  repalloc(tidList,
220  numAllocTids * sizeof(ItemPointerData));
221  }
222  for (i = 0; i < ndatums; i++)
223  {
224  if (ipnulls[i])
225  continue;
226 
227  itemptr = (ItemPointer) DatumGetPointer(ipdatums[i]);
228 
229  if (!table_tuple_tid_valid(scan, itemptr))
230  continue;
231 
232  tidList[numTids++] = *itemptr;
233  }
234  pfree(ipdatums);
235  pfree(ipnulls);
236  }
237  else
238  {
239  ItemPointerData cursor_tid;
240 
241  Assert(tidexpr->cexpr);
242  if (execCurrentOf(tidexpr->cexpr, econtext,
244  &cursor_tid))
245  {
246  if (numTids >= numAllocTids)
247  {
248  numAllocTids *= 2;
249  tidList = (ItemPointerData *)
250  repalloc(tidList,
251  numAllocTids * sizeof(ItemPointerData));
252  }
253  tidList[numTids++] = cursor_tid;
254  }
255  }
256  }
257 
258  /*
259  * Sort the array of TIDs into order, and eliminate duplicates.
260  * Eliminating duplicates is necessary since we want OR semantics across
261  * the list. Sorting makes it easier to detect duplicates, and as a bonus
262  * ensures that we will visit the heap in the most efficient way.
263  */
264  if (numTids > 1)
265  {
266  /* CurrentOfExpr could never appear OR'd with something else */
267  Assert(!tidstate->tss_isCurrentOf);
268 
269  qsort((void *) tidList, numTids, sizeof(ItemPointerData),
271  numTids = qunique(tidList, numTids, sizeof(ItemPointerData),
273  }
274 
275  tidstate->tss_TidList = tidList;
276  tidstate->tss_NumTids = numTids;
277  tidstate->tss_TidPtr = -1;
278 }
#define DatumGetArrayTypeP(X)
Definition: array.h:254
void deconstruct_array_builtin(ArrayType *array, Oid elmtype, Datum **elemsp, bool **nullsp, int *nelemsp)
Definition: arrayfuncs.c:3642
bool execCurrentOf(CurrentOfExpr *cexpr, ExprContext *econtext, Oid table_oid, ItemPointer current_tid)
Definition: execCurrent.c:44
static Datum ExecEvalExprSwitchContext(ExprState *state, ExprContext *econtext, bool *isNull)
Definition: executor.h:333
int i
Definition: isn.c:73
ItemPointerData * ItemPointer
Definition: itemptr.h:49
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1321
void * palloc(Size size)
Definition: mcxt.c:1199
static int itemptr_comparator(const void *a, const void *b)
Definition: nodeTidscan.c:284
#define qsort(a, b, c, d)
Definition: port.h:445
uintptr_t Datum
Definition: postgres.h:412
static Pointer DatumGetPointer(Datum X)
Definition: postgres.h:660
static size_t qunique(void *array, size_t elements, size_t width, int(*compare)(const void *, const void *))
Definition: qunique.h:21
#define RelationGetRelid(relation)
Definition: rel.h:501
Snapshot es_snapshot
Definition: execnodes.h:608
ExprContext * ps_ExprContext
Definition: execnodes.h:1063
static bool table_tuple_tid_valid(TableScanDesc scan, ItemPointer tid)
Definition: tableam.h:1285
static TableScanDesc table_beginscan_tid(Relation rel, Snapshot snapshot)
Definition: tableam.h:969

References Assert(), TidExpr::cexpr, DatumGetArrayTypeP, DatumGetPointer(), deconstruct_array_builtin(), EState::es_snapshot, execCurrentOf(), ExecEvalExprSwitchContext(), TidExpr::exprstate, i, TidExpr::isarray, itemptr_comparator(), lfirst, list_length(), palloc(), pfree(), ScanState::ps, PlanState::ps_ExprContext, qsort, qunique(), RelationGetRelid, repalloc(), TidScanState::ss, ScanState::ss_currentRelation, ScanState::ss_currentScanDesc, PlanState::state, table_beginscan_tid(), table_tuple_tid_valid(), TidScanState::tss_isCurrentOf, TidScanState::tss_NumTids, TidScanState::tss_tidexprs, TidScanState::tss_TidList, and TidScanState::tss_TidPtr.

Referenced by TidNext().

◆ TidNext()

static TupleTableSlot * TidNext ( TidScanState node)
static

Definition at line 313 of file nodeTidscan.c.

314 {
315  EState *estate;
316  ScanDirection direction;
317  Snapshot snapshot;
318  TableScanDesc scan;
319  Relation heapRelation;
320  TupleTableSlot *slot;
321  ItemPointerData *tidList;
322  int numTids;
323  bool bBackward;
324 
325  /*
326  * extract necessary information from tid scan node
327  */
328  estate = node->ss.ps.state;
329  direction = estate->es_direction;
330  snapshot = estate->es_snapshot;
331  heapRelation = node->ss.ss_currentRelation;
332  slot = node->ss.ss_ScanTupleSlot;
333 
334  /*
335  * First time through, compute the list of TIDs to be visited
336  */
337  if (node->tss_TidList == NULL)
338  TidListEval(node);
339 
340  scan = node->ss.ss_currentScanDesc;
341  tidList = node->tss_TidList;
342  numTids = node->tss_NumTids;
343 
344  /*
345  * Initialize or advance scan position, depending on direction.
346  */
347  bBackward = ScanDirectionIsBackward(direction);
348  if (bBackward)
349  {
350  if (node->tss_TidPtr < 0)
351  {
352  /* initialize for backward scan */
353  node->tss_TidPtr = numTids - 1;
354  }
355  else
356  node->tss_TidPtr--;
357  }
358  else
359  {
360  if (node->tss_TidPtr < 0)
361  {
362  /* initialize for forward scan */
363  node->tss_TidPtr = 0;
364  }
365  else
366  node->tss_TidPtr++;
367  }
368 
369  while (node->tss_TidPtr >= 0 && node->tss_TidPtr < numTids)
370  {
371  ItemPointerData tid = tidList[node->tss_TidPtr];
372 
373  /*
374  * For WHERE CURRENT OF, the tuple retrieved from the cursor might
375  * since have been updated; if so, we should fetch the version that is
376  * current according to our snapshot.
377  */
378  if (node->tss_isCurrentOf)
379  table_tuple_get_latest_tid(scan, &tid);
380 
381  if (table_tuple_fetch_row_version(heapRelation, &tid, snapshot, slot))
382  return slot;
383 
384  /* Bad TID or failed snapshot qual; try next */
385  if (bBackward)
386  node->tss_TidPtr--;
387  else
388  node->tss_TidPtr++;
389 
391  }
392 
393  /*
394  * if we get here it means the tid scan failed so we are at the end of the
395  * scan..
396  */
397  return ExecClearTuple(slot);
398 }
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:121
static void TidListEval(TidScanState *tidstate)
Definition: nodeTidscan.c:135
#define ScanDirectionIsBackward(direction)
Definition: sdir.h:41
ScanDirection
Definition: sdir.h:23
ScanDirection es_direction
Definition: execnodes.h:607
void table_tuple_get_latest_tid(TableScanDesc scan, ItemPointer tid)
Definition: tableam.c:245
static bool table_tuple_fetch_row_version(Relation rel, ItemPointer tid, Snapshot snapshot, TupleTableSlot *slot)
Definition: tableam.h:1259

References CHECK_FOR_INTERRUPTS, EState::es_direction, EState::es_snapshot, ExecClearTuple(), ScanState::ps, ScanDirectionIsBackward, TidScanState::ss, ScanState::ss_currentRelation, ScanState::ss_currentScanDesc, ScanState::ss_ScanTupleSlot, PlanState::state, table_tuple_fetch_row_version(), table_tuple_get_latest_tid(), TidListEval(), TidScanState::tss_isCurrentOf, TidScanState::tss_NumTids, TidScanState::tss_TidList, and TidScanState::tss_TidPtr.

Referenced by ExecTidScan().

◆ TidRecheck()

static bool TidRecheck ( TidScanState node,
TupleTableSlot slot 
)
static

Definition at line 404 of file nodeTidscan.c.

405 {
406  /*
407  * XXX shouldn't we check here to make sure tuple matches TID list? In
408  * runtime-key case this is not certain, is it? However, in the WHERE
409  * CURRENT OF case it might not match anyway ...
410  */
411  return true;
412 }

Referenced by ExecTidScan().