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/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/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 304 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().

305 {
306  switch (nodeTag(node))
307  {
308  case T_IndexScanState:
310  break;
311 
314  break;
315 
316  case T_CustomScanState:
318  break;
319 
320  case T_MaterialState:
322  break;
323 
324  case T_SortState:
325  ExecSortMarkPos((SortState *) node);
326  break;
327 
328  case T_ResultState:
329  ExecResultMarkPos((ResultState *) node);
330  break;
331 
332  default:
333  /* don't make hard error unless caller asks to restore... */
334  elog(DEBUG2, "unrecognized node type: %d", (int) nodeTag(node));
335  break;
336  }
337 }
void ExecIndexOnlyMarkPos(IndexOnlyScanState *node)
#define DEBUG2
Definition: elog.h:24
void ExecSortMarkPos(SortState *node)
Definition: nodeSort.c:258
void ExecIndexMarkPos(IndexScanState *node)
void ExecCustomMarkPos(CustomScanState *node)
Definition: nodeCustom.c:137
void ExecResultMarkPos(ResultState *node)
Definition: nodeResult.c:143
#define nodeTag(nodeptr)
Definition: nodes.h:509
void ExecMaterialMarkPos(MaterialState *node)
Definition: nodeMaterial.c:267
#define elog
Definition: elog.h:219
bool ExecMaterializesOutput ( NodeTag  plantype)

Definition at line 566 of file execAmi.c.

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

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

567 {
568  switch (plantype)
569  {
570  case T_Material:
571  case T_FunctionScan:
572  case T_TableFuncScan:
573  case T_CteScan:
574  case T_WorkTableScan:
575  case T_Sort:
576  return true;
577 
578  default:
579  break;
580  }
581 
582  return false;
583 }
Definition: nodes.h:74
void ExecReScan ( PlanState node)

Definition at line 74 of file execAmi.c.

References bms_free(), PlanState::chgParam, elog, ERROR, ExecReScanAgg(), ExecReScanAppend(), ExecReScanBitmapAnd(), ExecReScanBitmapHeapScan(), ExecReScanBitmapIndexScan(), ExecReScanBitmapOr(), ExecReScanCteScan(), ExecReScanCustomScan(), ExecReScanForeignScan(), ExecReScanFunctionScan(), ExecReScanGather(), ExecReScanGroup(), ExecReScanHash(), ExecReScanHashJoin(), ExecReScanIndexOnlyScan(), ExecReScanIndexScan(), ExecReScanLimit(), ExecReScanLockRows(), ExecReScanMaterial(), ExecReScanMergeAppend(), ExecReScanMergeJoin(), ExecReScanModifyTable(), 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, NULL, 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_GatherState, T_GroupState, T_HashJoinState, T_HashState, T_IndexOnlyScanState, T_IndexScanState, T_LimitState, T_LockRowsState, T_MaterialState, T_MergeAppendState, T_MergeJoinState, T_ModifyTableState, 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().

75 {
76  /* If collecting timing stats, update them */
77  if (node->instrument)
78  InstrEndLoop(node->instrument);
79 
80  /*
81  * If we have changed parameters, propagate that info.
82  *
83  * Note: ExecReScanSetParamPlan() can add bits to node->chgParam,
84  * corresponding to the output param(s) that the InitPlan will update.
85  * Since we make only one pass over the list, that means that an InitPlan
86  * can depend on the output param(s) of a sibling InitPlan only if that
87  * sibling appears earlier in the list. This is workable for now given
88  * the limited ways in which one InitPlan could depend on another, but
89  * eventually we might need to work harder (or else make the planner
90  * enlarge the extParam/allParam sets to include the params of depended-on
91  * InitPlans).
92  */
93  if (node->chgParam != NULL)
94  {
95  ListCell *l;
96 
97  foreach(l, node->initPlan)
98  {
99  SubPlanState *sstate = (SubPlanState *) lfirst(l);
100  PlanState *splan = sstate->planstate;
101 
102  if (splan->plan->extParam != NULL) /* don't care about child
103  * local Params */
104  UpdateChangedParamSet(splan, node->chgParam);
105  if (splan->chgParam != NULL)
106  ExecReScanSetParamPlan(sstate, node);
107  }
108  foreach(l, node->subPlan)
109  {
110  SubPlanState *sstate = (SubPlanState *) lfirst(l);
111  PlanState *splan = sstate->planstate;
112 
113  if (splan->plan->extParam != NULL)
114  UpdateChangedParamSet(splan, node->chgParam);
115  }
116  /* Well. Now set chgParam for left/right trees. */
117  if (node->lefttree != NULL)
119  if (node->righttree != NULL)
121  }
122 
123  /* Call expression callbacks */
124  if (node->ps_ExprContext)
126 
127  /* And do node-type-specific processing */
128  switch (nodeTag(node))
129  {
130  case T_ResultState:
131  ExecReScanResult((ResultState *) node);
132  break;
133 
134  case T_ProjectSetState:
136  break;
137 
138  case T_ModifyTableState:
140  break;
141 
142  case T_AppendState:
143  ExecReScanAppend((AppendState *) node);
144  break;
145 
146  case T_MergeAppendState:
148  break;
149 
152  break;
153 
154  case T_BitmapAndState:
156  break;
157 
158  case T_BitmapOrState:
160  break;
161 
162  case T_SeqScanState:
164  break;
165 
166  case T_SampleScanState:
168  break;
169 
170  case T_GatherState:
171  ExecReScanGather((GatherState *) node);
172  break;
173 
174  case T_IndexScanState:
176  break;
177 
180  break;
181 
184  break;
185 
188  break;
189 
190  case T_TidScanState:
192  break;
193 
194  case T_SubqueryScanState:
196  break;
197 
198  case T_FunctionScanState:
200  break;
201 
204  break;
205 
206  case T_ValuesScanState:
208  break;
209 
210  case T_CteScanState:
212  break;
213 
216  break;
217 
218  case T_ForeignScanState:
220  break;
221 
222  case T_CustomScanState:
224  break;
225 
226  case T_NestLoopState:
228  break;
229 
230  case T_MergeJoinState:
232  break;
233 
234  case T_HashJoinState:
236  break;
237 
238  case T_MaterialState:
240  break;
241 
242  case T_SortState:
243  ExecReScanSort((SortState *) node);
244  break;
245 
246  case T_GroupState:
247  ExecReScanGroup((GroupState *) node);
248  break;
249 
250  case T_AggState:
251  ExecReScanAgg((AggState *) node);
252  break;
253 
254  case T_WindowAggState:
256  break;
257 
258  case T_UniqueState:
259  ExecReScanUnique((UniqueState *) node);
260  break;
261 
262  case T_HashState:
263  ExecReScanHash((HashState *) node);
264  break;
265 
266  case T_SetOpState:
267  ExecReScanSetOp((SetOpState *) node);
268  break;
269 
270  case T_LockRowsState:
272  break;
273 
274  case T_LimitState:
275  ExecReScanLimit((LimitState *) node);
276  break;
277 
278  default:
279  elog(ERROR, "unrecognized node type: %d", (int) nodeTag(node));
280  break;
281  }
282 
283  if (node->chgParam != NULL)
284  {
285  bms_free(node->chgParam);
286  node->chgParam = NULL;
287  }
288 }
void ExecReScanBitmapHeapScan(BitmapHeapScanState *node)
void ExecReScanGroup(GroupState *node)
Definition: nodeGroup.c:240
void ExecReScanModifyTable(ModifyTableState *node)
Instrumentation * instrument
Definition: execnodes.h:806
List * initPlan
Definition: execnodes.h:817
void ExecReScanMaterial(MaterialState *node)
Definition: nodeMaterial.c:318
ExprContext * ps_ExprContext
Definition: execnodes.h:830
void ExecReScanLockRows(LockRowsState *node)
Definition: nodeLockRows.c:454
void ExecReScanFunctionScan(FunctionScanState *node)
List * subPlan
Definition: execnodes.h:819
void ExecReScanIndexOnlyScan(IndexOnlyScanState *node)
void ExecReScanLimit(LimitState *node)
Definition: nodeLimit.c:434
void ExecReScanWorkTableScan(WorkTableScanState *node)
struct PlanState * righttree
Definition: execnodes.h:816
void ExecReScanResult(ResultState *node)
Definition: nodeResult.c:260
void ExecReScanSetOp(SetOpState *node)
Definition: nodeSetOp.c:590
void ExecReScanSort(SortState *node)
Definition: nodeSort.c:291
void ExecReScanForeignScan(ForeignScanState *node)
struct PlanState * lefttree
Definition: execnodes.h:815
void InstrEndLoop(Instrumentation *instr)
Definition: instrument.c:114
void ExecReScanHash(HashState *node)
Definition: nodeHash.c:1263
void ExecReScanProjectSet(ProjectSetState *node)
#define ERROR
Definition: elog.h:43
struct PlanState * planstate
Definition: execnodes.h:723
void ExecReScanSetParamPlan(SubPlanState *node, PlanState *parent)
Definition: nodeSubplan.c:1087
void ExecReScanBitmapIndexScan(BitmapIndexScanState *node)
void ExecReScanUnique(UniqueState *node)
Definition: nodeUnique.c:185
void ExecReScanIndexScan(IndexScanState *node)
void ExecReScanMergeAppend(MergeAppendState *node)
void ExecReScanNestLoop(NestLoopState *node)
Definition: nodeNestloop.c:383
static SPIPlanPtr splan
Definition: regress.c:461
Bitmapset * chgParam
Definition: execnodes.h:824
void ExecReScanGather(GatherState *node)
Definition: nodeGather.c:424
void ExecReScanAppend(AppendState *node)
Definition: nodeAppend.c:272
void ExecReScanSubqueryScan(SubqueryScanState *node)
Plan * plan
Definition: execnodes.h:800
void ExecReScanBitmapOr(BitmapOrState *node)
Definition: nodeBitmapOr.c:205
void ExecReScanRecursiveUnion(RecursiveUnionState *node)
void UpdateChangedParamSet(PlanState *node, Bitmapset *newchg)
Definition: execUtils.c:666
void bms_free(Bitmapset *a)
Definition: bitmapset.c:200
#define NULL
Definition: c.h:229
#define lfirst(lc)
Definition: pg_list.h:106
void ExecReScanBitmapAnd(BitmapAndState *node)
void ExecReScanAgg(AggState *node)
Definition: nodeAgg.c:3529
Bitmapset * extParam
Definition: plannodes.h:150
void ReScanExprContext(ExprContext *econtext)
Definition: execUtils.c:371
#define nodeTag(nodeptr)
Definition: nodes.h:509
void ExecReScanValuesScan(ValuesScanState *node)
void ExecReScanSampleScan(SampleScanState *node)
void ExecReScanCteScan(CteScanState *node)
Definition: nodeCtescan.c:307
void ExecReScanWindowAgg(WindowAggState *node)
#define elog
Definition: elog.h:219
void ExecReScanTidScan(TidScanState *node)
Definition: nodeTidscan.c:458
void ExecReScanMergeJoin(MergeJoinState *node)
void ExecReScanCustomScan(CustomScanState *node)
Definition: nodeCustom.c:130
void ExecReScanTableFuncScan(TableFuncScanState *node)
void ExecReScanSeqScan(SeqScanState *node)
Definition: nodeSeqscan.c:267
void ExecReScanHashJoin(HashJoinState *node)
Definition: nodeHashjoin.c:888
void ExecRestrPos ( PlanState node)

Definition at line 353 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().

354 {
355  switch (nodeTag(node))
356  {
357  case T_IndexScanState:
359  break;
360 
363  break;
364 
365  case T_CustomScanState:
367  break;
368 
369  case T_MaterialState:
371  break;
372 
373  case T_SortState:
374  ExecSortRestrPos((SortState *) node);
375  break;
376 
377  case T_ResultState:
379  break;
380 
381  default:
382  elog(ERROR, "unrecognized node type: %d", (int) nodeTag(node));
383  break;
384  }
385 }
void ExecMaterialRestrPos(MaterialState *node)
Definition: nodeMaterial.c:295
void ExecIndexOnlyRestrPos(IndexOnlyScanState *node)
void ExecResultRestrPos(ResultState *node)
Definition: nodeResult.c:158
void ExecCustomRestrPos(CustomScanState *node)
Definition: nodeCustom.c:148
#define ERROR
Definition: elog.h:43
void ExecSortRestrPos(SortState *node)
Definition: nodeSort.c:276
void ExecIndexRestrPos(IndexScanState *node)
#define nodeTag(nodeptr)
Definition: nodes.h:509
#define elog
Definition: elog.h:219
bool ExecSupportsBackwardScan ( Plan node)

Definition at line 451 of file execAmi.c.

References CUSTOMPATH_SUPPORT_BACKWARD_SCAN, ExecSupportsBackwardScan(), IndexSupportsBackwardScan(), lfirst, nodeTag, NULL, 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().

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

Definition at line 395 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().

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

Definition at line 533 of file execAmi.c.

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

Referenced by ExecSupportsBackwardScan().

534 {
535  bool result;
536  HeapTuple ht_idxrel;
537  Form_pg_class idxrelrec;
538  IndexAmRoutine *amroutine;
539 
540  /* Fetch the pg_class tuple of the index relation */
541  ht_idxrel = SearchSysCache1(RELOID, ObjectIdGetDatum(indexid));
542  if (!HeapTupleIsValid(ht_idxrel))
543  elog(ERROR, "cache lookup failed for relation %u", indexid);
544  idxrelrec = (Form_pg_class) GETSTRUCT(ht_idxrel);
545 
546  /* Fetch the index AM's API struct */
547  amroutine = GetIndexAmRoutineByAmId(idxrelrec->relam, false);
548 
549  result = amroutine->amcanbackward;
550 
551  pfree(amroutine);
552  ReleaseSysCache(ht_idxrel);
553 
554  return result;
555 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
return result
Definition: formatting.c:1618
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:152
void pfree(void *pointer)
Definition: mcxt.c:950
#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:1116
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
FormData_pg_class * Form_pg_class
Definition: pg_class.h:95
#define elog
Definition: elog.h:219