PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
execAmi.c File Reference
#include "postgres.h"
#include "access/amapi.h"
#include "access/htup_details.h"
#include "executor/execdebug.h"
#include "executor/nodeAgg.h"
#include "executor/nodeAppend.h"
#include "executor/nodeBitmapAnd.h"
#include "executor/nodeBitmapHeapscan.h"
#include "executor/nodeBitmapIndexscan.h"
#include "executor/nodeBitmapOr.h"
#include "executor/nodeCtescan.h"
#include "executor/nodeCustom.h"
#include "executor/nodeForeignscan.h"
#include "executor/nodeFunctionscan.h"
#include "executor/nodeGather.h"
#include "executor/nodeGatherMerge.h"
#include "executor/nodeGroup.h"
#include "executor/nodeHash.h"
#include "executor/nodeHashjoin.h"
#include "executor/nodeIndexonlyscan.h"
#include "executor/nodeIndexscan.h"
#include "executor/nodeLimit.h"
#include "executor/nodeLockRows.h"
#include "executor/nodeMaterial.h"
#include "executor/nodeMergeAppend.h"
#include "executor/nodeMergejoin.h"
#include "executor/nodeModifyTable.h"
#include "executor/nodeNamedtuplestorescan.h"
#include "executor/nodeNestloop.h"
#include "executor/nodeProjectSet.h"
#include "executor/nodeRecursiveunion.h"
#include "executor/nodeResult.h"
#include "executor/nodeSamplescan.h"
#include "executor/nodeSeqscan.h"
#include "executor/nodeSetOp.h"
#include "executor/nodeSort.h"
#include "executor/nodeSubplan.h"
#include "executor/nodeSubqueryscan.h"
#include "executor/nodeTableFuncscan.h"
#include "executor/nodeTidscan.h"
#include "executor/nodeUnique.h"
#include "executor/nodeValuesscan.h"
#include "executor/nodeWindowAgg.h"
#include "executor/nodeWorktablescan.h"
#include "nodes/nodeFuncs.h"
#include "nodes/relation.h"
#include "utils/rel.h"
#include "utils/syscache.h"
Include dependency graph for execAmi.c:

Go to the source code of this file.

Functions

static bool IndexSupportsBackwardScan (Oid indexid)
 
void ExecReScan (PlanState *node)
 
void ExecMarkPos (PlanState *node)
 
void ExecRestrPos (PlanState *node)
 
bool ExecSupportsMarkRestore (Path *pathnode)
 
bool ExecSupportsBackwardScan (Plan *node)
 
bool ExecMaterializesOutput (NodeTag plantype)
 

Function Documentation

void ExecMarkPos ( PlanState node)

Definition at line 314 of file execAmi.c.

References DEBUG2, elog, ExecCustomMarkPos(), ExecIndexMarkPos(), ExecIndexOnlyMarkPos(), ExecMaterialMarkPos(), ExecResultMarkPos(), ExecSortMarkPos(), nodeTag, T_CustomScanState, T_IndexOnlyScanState, T_IndexScanState, T_MaterialState, T_ResultState, and T_SortState.

Referenced by ExecMergeJoin(), and ExecResultMarkPos().

315 {
316  switch (nodeTag(node))
317  {
318  case T_IndexScanState:
320  break;
321 
324  break;
325 
326  case T_CustomScanState:
328  break;
329 
330  case T_MaterialState:
332  break;
333 
334  case T_SortState:
335  ExecSortMarkPos((SortState *) node);
336  break;
337 
338  case T_ResultState:
339  ExecResultMarkPos((ResultState *) node);
340  break;
341 
342  default:
343  /* don't make hard error unless caller asks to restore... */
344  elog(DEBUG2, "unrecognized node type: %d", (int) nodeTag(node));
345  break;
346  }
347 }
void ExecIndexOnlyMarkPos(IndexOnlyScanState *node)
#define DEBUG2
Definition: elog.h:24
void ExecSortMarkPos(SortState *node)
Definition: nodeSort.c:273
void ExecIndexMarkPos(IndexScanState *node)
void ExecCustomMarkPos(CustomScanState *node)
Definition: nodeCustom.c:147
void ExecResultMarkPos(ResultState *node)
Definition: nodeResult.c:147
#define nodeTag(nodeptr)
Definition: nodes.h:514
void ExecMaterialMarkPos(MaterialState *node)
Definition: nodeMaterial.c:271
#define elog
Definition: elog.h:219
bool ExecMaterializesOutput ( NodeTag  plantype)

Definition at line 577 of file execAmi.c.

References T_CteScan, T_FunctionScan, T_Material, T_NamedTuplestoreScan, T_Sort, T_TableFuncScan, and T_WorkTableScan.

Referenced by build_subplan(), cost_subplan(), and match_unsorted_outer().

578 {
579  switch (plantype)
580  {
581  case T_Material:
582  case T_FunctionScan:
583  case T_TableFuncScan:
584  case T_CteScan:
586  case T_WorkTableScan:
587  case T_Sort:
588  return true;
589 
590  default:
591  break;
592  }
593 
594  return false;
595 }
Definition: nodes.h:75
void ExecReScan ( PlanState node)

Definition at line 76 of file execAmi.c.

References bms_free(), PlanState::chgParam, elog, ERROR, ExecReScanAgg(), ExecReScanAppend(), ExecReScanBitmapAnd(), ExecReScanBitmapHeapScan(), ExecReScanBitmapIndexScan(), ExecReScanBitmapOr(), ExecReScanCteScan(), ExecReScanCustomScan(), ExecReScanForeignScan(), ExecReScanFunctionScan(), ExecReScanGather(), ExecReScanGatherMerge(), ExecReScanGroup(), ExecReScanHash(), ExecReScanHashJoin(), ExecReScanIndexOnlyScan(), ExecReScanIndexScan(), ExecReScanLimit(), ExecReScanLockRows(), ExecReScanMaterial(), ExecReScanMergeAppend(), ExecReScanMergeJoin(), ExecReScanModifyTable(), ExecReScanNamedTuplestoreScan(), ExecReScanNestLoop(), ExecReScanProjectSet(), ExecReScanRecursiveUnion(), ExecReScanResult(), ExecReScanSampleScan(), ExecReScanSeqScan(), ExecReScanSetOp(), ExecReScanSetParamPlan(), ExecReScanSort(), ExecReScanSubqueryScan(), ExecReScanTableFuncScan(), ExecReScanTidScan(), ExecReScanUnique(), ExecReScanValuesScan(), ExecReScanWindowAgg(), ExecReScanWorkTableScan(), Plan::extParam, PlanState::initPlan, InstrEndLoop(), PlanState::instrument, PlanState::lefttree, lfirst, nodeTag, PlanState::plan, SubPlanState::planstate, PlanState::ps_ExprContext, ReScanExprContext(), PlanState::righttree, splan, PlanState::subPlan, T_AggState, T_AppendState, T_BitmapAndState, T_BitmapHeapScanState, T_BitmapIndexScanState, T_BitmapOrState, T_CteScanState, T_CustomScanState, T_ForeignScanState, T_FunctionScanState, T_GatherMergeState, T_GatherState, T_GroupState, T_HashJoinState, T_HashState, T_IndexOnlyScanState, T_IndexScanState, T_LimitState, T_LockRowsState, T_MaterialState, T_MergeAppendState, T_MergeJoinState, T_ModifyTableState, T_NamedTuplestoreScanState, T_NestLoopState, T_ProjectSetState, T_RecursiveUnionState, T_ResultState, T_SampleScanState, T_SeqScanState, T_SetOpState, T_SortState, T_SubqueryScanState, T_TableFuncScanState, T_TidScanState, T_UniqueState, T_ValuesScanState, T_WindowAggState, T_WorkTableScanState, and UpdateChangedParamSet().

Referenced by buildSubPlanHash(), ExecIndexOnlyScan(), ExecIndexScan(), ExecNestLoop(), ExecProcNode(), ExecReScanAgg(), ExecReScanAppend(), ExecReScanBitmapAnd(), ExecReScanBitmapHeapScan(), ExecReScanBitmapOr(), ExecReScanForeignScan(), ExecReScanGather(), ExecReScanGatherMerge(), ExecReScanGroup(), ExecReScanHash(), ExecReScanHashJoin(), ExecReScanLimit(), ExecReScanLockRows(), ExecReScanMaterial(), ExecReScanMergeAppend(), ExecReScanMergeJoin(), ExecReScanNestLoop(), ExecReScanProjectSet(), ExecReScanRecursiveUnion(), ExecReScanResult(), ExecReScanSetOp(), ExecReScanSort(), ExecReScanSubqueryScan(), ExecReScanUnique(), ExecReScanWindowAgg(), ExecScanSubPlan(), ExecutorRewind(), MultiExecBitmapIndexScan(), and MultiExecProcNode().

77 {
78  /* If collecting timing stats, update them */
79  if (node->instrument)
80  InstrEndLoop(node->instrument);
81 
82  /*
83  * If we have changed parameters, propagate that info.
84  *
85  * Note: ExecReScanSetParamPlan() can add bits to node->chgParam,
86  * corresponding to the output param(s) that the InitPlan will update.
87  * Since we make only one pass over the list, that means that an InitPlan
88  * can depend on the output param(s) of a sibling InitPlan only if that
89  * sibling appears earlier in the list. This is workable for now given
90  * the limited ways in which one InitPlan could depend on another, but
91  * eventually we might need to work harder (or else make the planner
92  * enlarge the extParam/allParam sets to include the params of depended-on
93  * InitPlans).
94  */
95  if (node->chgParam != NULL)
96  {
97  ListCell *l;
98 
99  foreach(l, node->initPlan)
100  {
101  SubPlanState *sstate = (SubPlanState *) lfirst(l);
102  PlanState *splan = sstate->planstate;
103 
104  if (splan->plan->extParam != NULL) /* don't care about child
105  * local Params */
106  UpdateChangedParamSet(splan, node->chgParam);
107  if (splan->chgParam != NULL)
108  ExecReScanSetParamPlan(sstate, node);
109  }
110  foreach(l, node->subPlan)
111  {
112  SubPlanState *sstate = (SubPlanState *) lfirst(l);
113  PlanState *splan = sstate->planstate;
114 
115  if (splan->plan->extParam != NULL)
116  UpdateChangedParamSet(splan, node->chgParam);
117  }
118  /* Well. Now set chgParam for left/right trees. */
119  if (node->lefttree != NULL)
121  if (node->righttree != NULL)
123  }
124 
125  /* Call expression callbacks */
126  if (node->ps_ExprContext)
128 
129  /* And do node-type-specific processing */
130  switch (nodeTag(node))
131  {
132  case T_ResultState:
133  ExecReScanResult((ResultState *) node);
134  break;
135 
136  case T_ProjectSetState:
138  break;
139 
140  case T_ModifyTableState:
142  break;
143 
144  case T_AppendState:
145  ExecReScanAppend((AppendState *) node);
146  break;
147 
148  case T_MergeAppendState:
150  break;
151 
154  break;
155 
156  case T_BitmapAndState:
158  break;
159 
160  case T_BitmapOrState:
162  break;
163 
164  case T_SeqScanState:
166  break;
167 
168  case T_SampleScanState:
170  break;
171 
172  case T_GatherState:
173  ExecReScanGather((GatherState *) node);
174  break;
175 
176  case T_GatherMergeState:
178  break;
179 
180  case T_IndexScanState:
182  break;
183 
186  break;
187 
190  break;
191 
194  break;
195 
196  case T_TidScanState:
198  break;
199 
200  case T_SubqueryScanState:
202  break;
203 
204  case T_FunctionScanState:
206  break;
207 
210  break;
211 
212  case T_ValuesScanState:
214  break;
215 
216  case T_CteScanState:
218  break;
219 
222  break;
223 
226  break;
227 
228  case T_ForeignScanState:
230  break;
231 
232  case T_CustomScanState:
234  break;
235 
236  case T_NestLoopState:
238  break;
239 
240  case T_MergeJoinState:
242  break;
243 
244  case T_HashJoinState:
246  break;
247 
248  case T_MaterialState:
250  break;
251 
252  case T_SortState:
253  ExecReScanSort((SortState *) node);
254  break;
255 
256  case T_GroupState:
257  ExecReScanGroup((GroupState *) node);
258  break;
259 
260  case T_AggState:
261  ExecReScanAgg((AggState *) node);
262  break;
263 
264  case T_WindowAggState:
266  break;
267 
268  case T_UniqueState:
269  ExecReScanUnique((UniqueState *) node);
270  break;
271 
272  case T_HashState:
273  ExecReScanHash((HashState *) node);
274  break;
275 
276  case T_SetOpState:
277  ExecReScanSetOp((SetOpState *) node);
278  break;
279 
280  case T_LockRowsState:
282  break;
283 
284  case T_LimitState:
285  ExecReScanLimit((LimitState *) node);
286  break;
287 
288  default:
289  elog(ERROR, "unrecognized node type: %d", (int) nodeTag(node));
290  break;
291  }
292 
293  if (node->chgParam != NULL)
294  {
295  bms_free(node->chgParam);
296  node->chgParam = NULL;
297  }
298 }
void ExecReScanBitmapHeapScan(BitmapHeapScanState *node)
void ExecReScanGroup(GroupState *node)
Definition: nodeGroup.c:245
void ExecReScanModifyTable(ModifyTableState *node)
Instrumentation * instrument
Definition: execnodes.h:857
List * initPlan
Definition: execnodes.h:868
void ExecReScanMaterial(MaterialState *node)
Definition: nodeMaterial.c:322
ExprContext * ps_ExprContext
Definition: execnodes.h:881
void ExecReScanLockRows(LockRowsState *node)
Definition: nodeLockRows.c:459
void ExecReScanFunctionScan(FunctionScanState *node)
List * subPlan
Definition: execnodes.h:870
void ExecReScanIndexOnlyScan(IndexOnlyScanState *node)
void ExecReScanLimit(LimitState *node)
Definition: nodeLimit.c:401
void ExecReScanWorkTableScan(WorkTableScanState *node)
struct PlanState * righttree
Definition: execnodes.h:867
void ExecReScanResult(ResultState *node)
Definition: nodeResult.c:265
void ExecReScanSetOp(SetOpState *node)
Definition: nodeSetOp.c:597
void ExecReScanSort(SortState *node)
Definition: nodeSort.c:306
void ExecReScanForeignScan(ForeignScanState *node)
struct PlanState * lefttree
Definition: execnodes.h:866
void InstrEndLoop(Instrumentation *instr)
Definition: instrument.c:114
void ExecReScanHash(HashState *node)
Definition: nodeHash.c:1270
void ExecReScanProjectSet(ProjectSetState *node)
#define ERROR
Definition: elog.h:43
struct PlanState * planstate
Definition: execnodes.h:758
void ExecReScanSetParamPlan(SubPlanState *node, PlanState *parent)
Definition: nodeSubplan.c:1092
void ExecReScanBitmapIndexScan(BitmapIndexScanState *node)
void ExecReScanUnique(UniqueState *node)
Definition: nodeUnique.c:190
void ExecReScanIndexScan(IndexScanState *node)
void ExecReScanGatherMerge(GatherMergeState *node)
void ExecReScanMergeAppend(MergeAppendState *node)
void ExecReScanNestLoop(NestLoopState *node)
Definition: nodeNestloop.c:396
static SPIPlanPtr splan
Definition: regress.c:449
Bitmapset * chgParam
Definition: execnodes.h:875
void ExecReScanGather(GatherState *node)
Definition: nodeGather.c:418
void ExecReScanNamedTuplestoreScan(NamedTuplestoreScanState *node)
void ExecReScanAppend(AppendState *node)
Definition: nodeAppend.c:279
void ExecReScanSubqueryScan(SubqueryScanState *node)
Plan * plan
Definition: execnodes.h:847
void ExecReScanBitmapOr(BitmapOrState *node)
Definition: nodeBitmapOr.c:219
void ExecReScanRecursiveUnion(RecursiveUnionState *node)
void UpdateChangedParamSet(PlanState *node, Bitmapset *newchg)
Definition: execUtils.c:676
void bms_free(Bitmapset *a)
Definition: bitmapset.c:201
#define lfirst(lc)
Definition: pg_list.h:106
void ExecReScanBitmapAnd(BitmapAndState *node)
void ExecReScanAgg(AggState *node)
Definition: nodeAgg.c:3896
Bitmapset * extParam
Definition: plannodes.h:162
void ReScanExprContext(ExprContext *econtext)
Definition: execUtils.c:381
#define nodeTag(nodeptr)
Definition: nodes.h:514
void ExecReScanValuesScan(ValuesScanState *node)
void ExecReScanSampleScan(SampleScanState *node)
void ExecReScanCteScan(CteScanState *node)
Definition: nodeCtescan.c:310
void ExecReScanWindowAgg(WindowAggState *node)
#define elog
Definition: elog.h:219
void ExecReScanTidScan(TidScanState *node)
Definition: nodeTidscan.c:463
void ExecReScanMergeJoin(MergeJoinState *node)
void ExecReScanCustomScan(CustomScanState *node)
Definition: nodeCustom.c:140
void ExecReScanTableFuncScan(TableFuncScanState *node)
void ExecReScanSeqScan(SeqScanState *node)
Definition: nodeSeqscan.c:271
void ExecReScanHashJoin(HashJoinState *node)
Definition: nodeHashjoin.c:898
void ExecRestrPos ( PlanState node)

Definition at line 363 of file execAmi.c.

References elog, ERROR, ExecCustomRestrPos(), ExecIndexOnlyRestrPos(), ExecIndexRestrPos(), ExecMaterialRestrPos(), ExecResultRestrPos(), ExecSortRestrPos(), nodeTag, T_CustomScanState, T_IndexOnlyScanState, T_IndexScanState, T_MaterialState, T_ResultState, and T_SortState.

Referenced by ExecMergeJoin(), and ExecResultRestrPos().

364 {
365  switch (nodeTag(node))
366  {
367  case T_IndexScanState:
369  break;
370 
373  break;
374 
375  case T_CustomScanState:
377  break;
378 
379  case T_MaterialState:
381  break;
382 
383  case T_SortState:
384  ExecSortRestrPos((SortState *) node);
385  break;
386 
387  case T_ResultState:
389  break;
390 
391  default:
392  elog(ERROR, "unrecognized node type: %d", (int) nodeTag(node));
393  break;
394  }
395 }
void ExecMaterialRestrPos(MaterialState *node)
Definition: nodeMaterial.c:299
void ExecIndexOnlyRestrPos(IndexOnlyScanState *node)
void ExecResultRestrPos(ResultState *node)
Definition: nodeResult.c:162
void ExecCustomRestrPos(CustomScanState *node)
Definition: nodeCustom.c:158
#define ERROR
Definition: elog.h:43
void ExecSortRestrPos(SortState *node)
Definition: nodeSort.c:291
void ExecIndexRestrPos(IndexScanState *node)
#define nodeTag(nodeptr)
Definition: nodes.h:514
#define elog
Definition: elog.h:219
bool ExecSupportsBackwardScan ( Plan node)

Definition at line 462 of file execAmi.c.

References CUSTOMPATH_SUPPORT_BACKWARD_SCAN, ExecSupportsBackwardScan(), IndexSupportsBackwardScan(), lfirst, nodeTag, outerPlan, Plan::parallel_aware, T_Append, T_CteScan, T_CustomScan, T_FunctionScan, T_Gather, T_IndexOnlyScan, T_IndexScan, T_Limit, T_LockRows, T_Material, T_Result, T_SampleScan, T_SeqScan, T_Sort, T_SubqueryScan, T_TidScan, and T_ValuesScan.

Referenced by ExecSupportsBackwardScan(), PerformCursorOpen(), SPI_cursor_open_internal(), and standard_planner().

463 {
464  if (node == NULL)
465  return false;
466 
467  /*
468  * Parallel-aware nodes return a subset of the tuples in each worker, and
469  * in general we can't expect to have enough bookkeeping state to know
470  * which ones we returned in this worker as opposed to some other worker.
471  */
472  if (node->parallel_aware)
473  return false;
474 
475  switch (nodeTag(node))
476  {
477  case T_Result:
478  if (outerPlan(node) != NULL)
479  return ExecSupportsBackwardScan(outerPlan(node));
480  else
481  return false;
482 
483  case T_Append:
484  {
485  ListCell *l;
486 
487  foreach(l, ((Append *) node)->appendplans)
488  {
489  if (!ExecSupportsBackwardScan((Plan *) lfirst(l)))
490  return false;
491  }
492  /* need not check tlist because Append doesn't evaluate it */
493  return true;
494  }
495 
496  case T_SampleScan:
497  /* Simplify life for tablesample methods by disallowing this */
498  return false;
499 
500  case T_Gather:
501  return false;
502 
503  case T_IndexScan:
504  return IndexSupportsBackwardScan(((IndexScan *) node)->indexid);
505 
506  case T_IndexOnlyScan:
507  return IndexSupportsBackwardScan(((IndexOnlyScan *) node)->indexid);
508 
509  case T_SubqueryScan:
510  return ExecSupportsBackwardScan(((SubqueryScan *) node)->subplan);
511 
512  case T_CustomScan:
513  {
514  uint32 flags = ((CustomScan *) node)->flags;
515 
517  return true;
518  }
519  return false;
520 
521  case T_SeqScan:
522  case T_TidScan:
523  case T_FunctionScan:
524  case T_ValuesScan:
525  case T_CteScan:
526  case T_Material:
527  case T_Sort:
528  return true;
529 
530  case T_LockRows:
531  case T_Limit:
532  return ExecSupportsBackwardScan(outerPlan(node));
533 
534  default:
535  return false;
536  }
537 }
#define CUSTOMPATH_SUPPORT_BACKWARD_SCAN
Definition: extensible.h:81
Definition: nodes.h:48
Definition: nodes.h:75
static bool IndexSupportsBackwardScan(Oid indexid)
Definition: execAmi.c:544
Definition: nodes.h:45
bool parallel_aware
Definition: plannodes.h:137
unsigned int uint32
Definition: c.h:258
#define outerPlan(node)
Definition: plannodes.h:174
bool ExecSupportsBackwardScan(Plan *node)
Definition: execAmi.c:462
#define lfirst(lc)
Definition: pg_list.h:106
#define nodeTag(nodeptr)
Definition: nodes.h:514
Definition: nodes.h:80
Definition: nodes.h:85
bool ExecSupportsMarkRestore ( Path pathnode)

Definition at line 405 of file execAmi.c.

References Assert, castNode, CUSTOMPATH_SUPPORT_MARK_RESTORE, ExecSupportsMarkRestore(), CustomPath::flags, IsA, Path::pathtype, subpath(), T_CustomScan, T_IndexOnlyScan, T_IndexScan, T_Material, T_Result, and T_Sort.

Referenced by ExecSupportsMarkRestore(), and final_cost_mergejoin().

406 {
407  /*
408  * For consistency with the routines above, we do not examine the nodeTag
409  * but rather the pathtype, which is the Plan node type the Path would
410  * produce.
411  */
412  switch (pathnode->pathtype)
413  {
414  case T_IndexScan:
415  case T_IndexOnlyScan:
416  case T_Material:
417  case T_Sort:
418  return true;
419 
420  case T_CustomScan:
421  {
422  CustomPath *customPath = castNode(CustomPath, pathnode);
423 
424  if (customPath->flags & CUSTOMPATH_SUPPORT_MARK_RESTORE)
425  return true;
426  return false;
427  }
428  case T_Result:
429 
430  /*
431  * Result supports mark/restore iff it has a child plan that does.
432  *
433  * We have to be careful here because there is more than one Path
434  * type that can produce a Result plan node.
435  */
436  if (IsA(pathnode, ProjectionPath))
437  return ExecSupportsMarkRestore(((ProjectionPath *) pathnode)->subpath);
438  else if (IsA(pathnode, MinMaxAggPath))
439  return false; /* childless Result */
440  else
441  {
442  Assert(IsA(pathnode, ResultPath));
443  return false; /* childless Result */
444  }
445 
446  default:
447  break;
448  }
449 
450  return false;
451 }
#define IsA(nodeptr, _type_)
Definition: nodes.h:560
bool ExecSupportsMarkRestore(Path *pathnode)
Definition: execAmi.c:405
#define castNode(_type_, nodeptr)
Definition: nodes.h:578
#define CUSTOMPATH_SUPPORT_MARK_RESTORE
Definition: extensible.h:82
uint32 flags
Definition: relation.h:1159
Definition: nodes.h:75
NodeTag pathtype
Definition: relation.h:952
Definition: nodes.h:45
#define Assert(condition)
Definition: c.h:664
Datum subpath(PG_FUNCTION_ARGS)
Definition: ltree_op.c:234
static bool IndexSupportsBackwardScan ( Oid  indexid)
static

Definition at line 544 of file execAmi.c.

References IndexAmRoutine::amcanbackward, elog, ERROR, GetIndexAmRoutineByAmId(), GETSTRUCT, HeapTupleIsValid, ObjectIdGetDatum, pfree(), ReleaseSysCache(), RELOID, result, and SearchSysCache1.

Referenced by ExecSupportsBackwardScan().

545 {
546  bool result;
547  HeapTuple ht_idxrel;
548  Form_pg_class idxrelrec;
549  IndexAmRoutine *amroutine;
550 
551  /* Fetch the pg_class tuple of the index relation */
552  ht_idxrel = SearchSysCache1(RELOID, ObjectIdGetDatum(indexid));
553  if (!HeapTupleIsValid(ht_idxrel))
554  elog(ERROR, "cache lookup failed for relation %u", indexid);
555  idxrelrec = (Form_pg_class) GETSTRUCT(ht_idxrel);
556 
557  /* Fetch the index AM's API struct */
558  amroutine = GetIndexAmRoutineByAmId(idxrelrec->relam, false);
559 
560  result = amroutine->amcanbackward;
561 
562  pfree(amroutine);
563  ReleaseSysCache(ht_idxrel);
564 
565  return result;
566 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
return result
Definition: formatting.c:1633
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:159
void pfree(void *pointer)
Definition: mcxt.c:949
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
IndexAmRoutine * GetIndexAmRoutineByAmId(Oid amoid, bool noerror)
Definition: amapi.c:56
bool amcanbackward
Definition: amapi.h:175
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1117
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
FormData_pg_class * Form_pg_class
Definition: pg_class.h:95
#define elog
Definition: elog.h:219