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

300 {
301  switch (nodeTag(node))
302  {
303  case T_IndexScanState:
305  break;
306 
309  break;
310 
311  case T_CustomScanState:
313  break;
314 
315  case T_MaterialState:
317  break;
318 
319  case T_SortState:
320  ExecSortMarkPos((SortState *) node);
321  break;
322 
323  case T_ResultState:
324  ExecResultMarkPos((ResultState *) node);
325  break;
326 
327  default:
328  /* don't make hard error unless caller asks to restore... */
329  elog(DEBUG2, "unrecognized node type: %d", (int) nodeTag(node));
330  break;
331  }
332 }
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:141
void ExecResultMarkPos(ResultState *node)
Definition: nodeResult.c:145
#define nodeTag(nodeptr)
Definition: nodes.h:513
void ExecMaterialMarkPos(MaterialState *node)
Definition: nodeMaterial.c:267
#define elog
Definition: elog.h:219
bool ExecMaterializesOutput ( NodeTag  plantype)

Definition at line 561 of file execAmi.c.

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

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

562 {
563  switch (plantype)
564  {
565  case T_Material:
566  case T_FunctionScan:
567  case T_CteScan:
568  case T_WorkTableScan:
569  case T_Sort:
570  return true;
571 
572  default:
573  break;
574  }
575 
576  return false;
577 }
Definition: nodes.h:73
void ExecReScan ( PlanState node)

Definition at line 73 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(), 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_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(), ExecReScanGroup(), ExecReScanHash(), ExecReScanHashJoin(), ExecReScanLimit(), ExecReScanLockRows(), ExecReScanMaterial(), ExecReScanMergeAppend(), ExecReScanMergeJoin(), ExecReScanNestLoop(), ExecReScanProjectSet(), ExecReScanRecursiveUnion(), ExecReScanResult(), ExecReScanSetOp(), ExecReScanSort(), ExecReScanSubqueryScan(), ExecReScanUnique(), ExecReScanWindowAgg(), ExecScanSubPlan(), ExecutorRewind(), MultiExecBitmapIndexScan(), and MultiExecProcNode().

74 {
75  /* If collecting timing stats, update them */
76  if (node->instrument)
77  InstrEndLoop(node->instrument);
78 
79  /*
80  * If we have changed parameters, propagate that info.
81  *
82  * Note: ExecReScanSetParamPlan() can add bits to node->chgParam,
83  * corresponding to the output param(s) that the InitPlan will update.
84  * Since we make only one pass over the list, that means that an InitPlan
85  * can depend on the output param(s) of a sibling InitPlan only if that
86  * sibling appears earlier in the list. This is workable for now given
87  * the limited ways in which one InitPlan could depend on another, but
88  * eventually we might need to work harder (or else make the planner
89  * enlarge the extParam/allParam sets to include the params of depended-on
90  * InitPlans).
91  */
92  if (node->chgParam != NULL)
93  {
94  ListCell *l;
95 
96  foreach(l, node->initPlan)
97  {
98  SubPlanState *sstate = (SubPlanState *) lfirst(l);
99  PlanState *splan = sstate->planstate;
100 
101  if (splan->plan->extParam != NULL) /* don't care about child
102  * local Params */
103  UpdateChangedParamSet(splan, node->chgParam);
104  if (splan->chgParam != NULL)
105  ExecReScanSetParamPlan(sstate, node);
106  }
107  foreach(l, node->subPlan)
108  {
109  SubPlanState *sstate = (SubPlanState *) lfirst(l);
110  PlanState *splan = sstate->planstate;
111 
112  if (splan->plan->extParam != NULL)
113  UpdateChangedParamSet(splan, node->chgParam);
114  }
115  /* Well. Now set chgParam for left/right trees. */
116  if (node->lefttree != NULL)
118  if (node->righttree != NULL)
120  }
121 
122  /* Call expression callbacks */
123  if (node->ps_ExprContext)
125 
126  /* And do node-type-specific processing */
127  switch (nodeTag(node))
128  {
129  case T_ResultState:
130  ExecReScanResult((ResultState *) node);
131  break;
132 
133  case T_ProjectSetState:
135  break;
136 
137  case T_ModifyTableState:
139  break;
140 
141  case T_AppendState:
142  ExecReScanAppend((AppendState *) node);
143  break;
144 
145  case T_MergeAppendState:
147  break;
148 
151  break;
152 
153  case T_BitmapAndState:
155  break;
156 
157  case T_BitmapOrState:
159  break;
160 
161  case T_SeqScanState:
163  break;
164 
165  case T_SampleScanState:
167  break;
168 
169  case T_GatherState:
170  ExecReScanGather((GatherState *) node);
171  break;
172 
173  case T_IndexScanState:
175  break;
176 
179  break;
180 
183  break;
184 
187  break;
188 
189  case T_TidScanState:
191  break;
192 
193  case T_SubqueryScanState:
195  break;
196 
197  case T_FunctionScanState:
199  break;
200 
201  case T_ValuesScanState:
203  break;
204 
205  case T_CteScanState:
207  break;
208 
211  break;
212 
213  case T_ForeignScanState:
215  break;
216 
217  case T_CustomScanState:
219  break;
220 
221  case T_NestLoopState:
223  break;
224 
225  case T_MergeJoinState:
227  break;
228 
229  case T_HashJoinState:
231  break;
232 
233  case T_MaterialState:
235  break;
236 
237  case T_SortState:
238  ExecReScanSort((SortState *) node);
239  break;
240 
241  case T_GroupState:
242  ExecReScanGroup((GroupState *) node);
243  break;
244 
245  case T_AggState:
246  ExecReScanAgg((AggState *) node);
247  break;
248 
249  case T_WindowAggState:
251  break;
252 
253  case T_UniqueState:
254  ExecReScanUnique((UniqueState *) node);
255  break;
256 
257  case T_HashState:
258  ExecReScanHash((HashState *) node);
259  break;
260 
261  case T_SetOpState:
262  ExecReScanSetOp((SetOpState *) node);
263  break;
264 
265  case T_LockRowsState:
267  break;
268 
269  case T_LimitState:
270  ExecReScanLimit((LimitState *) node);
271  break;
272 
273  default:
274  elog(ERROR, "unrecognized node type: %d", (int) nodeTag(node));
275  break;
276  }
277 
278  if (node->chgParam != NULL)
279  {
280  bms_free(node->chgParam);
281  node->chgParam = NULL;
282  }
283 }
void ExecReScanBitmapHeapScan(BitmapHeapScanState *node)
void ExecReScanGroup(GroupState *node)
Definition: nodeGroup.c:244
void ExecReScanModifyTable(ModifyTableState *node)
Instrumentation * instrument
Definition: execnodes.h:1053
List * initPlan
Definition: execnodes.h:1065
void ExecReScanMaterial(MaterialState *node)
Definition: nodeMaterial.c:318
ExprContext * ps_ExprContext
Definition: execnodes.h:1078
void ExecReScanLockRows(LockRowsState *node)
Definition: nodeLockRows.c:454
void ExecReScanFunctionScan(FunctionScanState *node)
List * subPlan
Definition: execnodes.h:1067
void ExecReScanIndexOnlyScan(IndexOnlyScanState *node)
void ExecReScanLimit(LimitState *node)
Definition: nodeLimit.c:434
void ExecReScanWorkTableScan(WorkTableScanState *node)
struct PlanState * righttree
Definition: execnodes.h:1064
void ExecReScanResult(ResultState *node)
Definition: nodeResult.c:266
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:1063
void InstrEndLoop(Instrumentation *instr)
Definition: instrument.c:114
void ExecReScanHash(HashState *node)
Definition: nodeHash.c:1267
void ExecReScanProjectSet(ProjectSetState *node)
#define ERROR
Definition: elog.h:43
struct PlanState * planstate
Definition: execnodes.h:786
void ExecReScanSetParamPlan(SubPlanState *node, PlanState *parent)
Definition: nodeSubplan.c:1111
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:388
static SPIPlanPtr splan
Definition: regress.c:461
Bitmapset * chgParam
Definition: execnodes.h:1072
void ExecReScanGather(GatherState *node)
Definition: nodeGather.c:428
void ExecReScanAppend(AppendState *node)
Definition: nodeAppend.c:266
void ExecReScanSubqueryScan(SubqueryScanState *node)
Plan * plan
Definition: execnodes.h:1047
void ExecReScanBitmapOr(BitmapOrState *node)
Definition: nodeBitmapOr.c:203
void ExecReScanRecursiveUnion(RecursiveUnionState *node)
void UpdateChangedParamSet(PlanState *node, Bitmapset *newchg)
Definition: execUtils.c:840
void bms_free(Bitmapset *a)
Definition: bitmapset.c:200
#define NULL
Definition: c.h:226
#define lfirst(lc)
Definition: pg_list.h:106
void ExecReScanBitmapAnd(BitmapAndState *node)
void ExecReScanAgg(AggState *node)
Definition: nodeAgg.c:3531
Bitmapset * extParam
Definition: plannodes.h:147
void ReScanExprContext(ExprContext *econtext)
Definition: execUtils.c:366
#define nodeTag(nodeptr)
Definition: nodes.h:513
void ExecReScanValuesScan(ValuesScanState *node)
void ExecReScanSampleScan(SampleScanState *node)
void ExecReScanCteScan(CteScanState *node)
Definition: nodeCtescan.c:311
void ExecReScanWindowAgg(WindowAggState *node)
#define elog
Definition: elog.h:219
void ExecReScanTidScan(TidScanState *node)
Definition: nodeTidscan.c:401
void ExecReScanMergeJoin(MergeJoinState *node)
void ExecReScanCustomScan(CustomScanState *node)
Definition: nodeCustom.c:134
void ExecReScanSeqScan(SeqScanState *node)
Definition: nodeSeqscan.c:271
void ExecReScanHashJoin(HashJoinState *node)
Definition: nodeHashjoin.c:896
void ExecRestrPos ( PlanState node)

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

349 {
350  switch (nodeTag(node))
351  {
352  case T_IndexScanState:
354  break;
355 
358  break;
359 
360  case T_CustomScanState:
362  break;
363 
364  case T_MaterialState:
366  break;
367 
368  case T_SortState:
369  ExecSortRestrPos((SortState *) node);
370  break;
371 
372  case T_ResultState:
374  break;
375 
376  default:
377  elog(ERROR, "unrecognized node type: %d", (int) nodeTag(node));
378  break;
379  }
380 }
void ExecMaterialRestrPos(MaterialState *node)
Definition: nodeMaterial.c:295
void ExecIndexOnlyRestrPos(IndexOnlyScanState *node)
void ExecResultRestrPos(ResultState *node)
Definition: nodeResult.c:160
void ExecCustomRestrPos(CustomScanState *node)
Definition: nodeCustom.c:152
#define ERROR
Definition: elog.h:43
void ExecSortRestrPos(SortState *node)
Definition: nodeSort.c:276
void ExecIndexRestrPos(IndexScanState *node)
#define nodeTag(nodeptr)
Definition: nodes.h:513
#define elog
Definition: elog.h:219
bool ExecSupportsBackwardScan ( Plan node)

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

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

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

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

Definition at line 528 of file execAmi.c.

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

Referenced by ExecSupportsBackwardScan().

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