PostgreSQL Source Code  git master
execAmi.c File Reference
#include "postgres.h"
#include "access/amapi.h"
#include "access/htup_details.h"
#include "catalog/pg_class.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/nodeIncrementalSort.h"
#include "executor/nodeIndexonlyscan.h"
#include "executor/nodeIndexscan.h"
#include "executor/nodeLimit.h"
#include "executor/nodeLockRows.h"
#include "executor/nodeMaterial.h"
#include "executor/nodeMemoize.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/nodeTidrangescan.h"
#include "executor/nodeTidscan.h"
#include "executor/nodeUnique.h"
#include "executor/nodeValuesscan.h"
#include "executor/nodeWindowAgg.h"
#include "executor/nodeWorktablescan.h"
#include "nodes/extensible.h"
#include "nodes/pathnodes.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

◆ ExecMarkPos()

void ExecMarkPos ( PlanState node)

Definition at line 326 of file execAmi.c.

327 {
328  switch (nodeTag(node))
329  {
330  case T_IndexScanState:
332  break;
333 
334  case T_IndexOnlyScanState:
336  break;
337 
338  case T_CustomScanState:
340  break;
341 
342  case T_MaterialState:
344  break;
345 
346  case T_SortState:
347  ExecSortMarkPos((SortState *) node);
348  break;
349 
350  case T_ResultState:
351  ExecResultMarkPos((ResultState *) node);
352  break;
353 
354  default:
355  /* don't make hard error unless caller asks to restore... */
356  elog(DEBUG2, "unrecognized node type: %d", (int) nodeTag(node));
357  break;
358  }
359 }
#define DEBUG2
Definition: elog.h:29
#define elog(elevel,...)
Definition: elog.h:224
void ExecCustomMarkPos(CustomScanState *node)
Definition: nodeCustom.c:139
void ExecIndexOnlyMarkPos(IndexOnlyScanState *node)
void ExecIndexMarkPos(IndexScanState *node)
void ExecMaterialMarkPos(MaterialState *node)
Definition: nodeMaterial.c:262
void ExecResultMarkPos(ResultState *node)
Definition: nodeResult.c:146
void ExecSortMarkPos(SortState *node)
Definition: nodeSort.c:329
#define nodeTag(nodeptr)
Definition: nodes.h:133

References DEBUG2, elog, ExecCustomMarkPos(), ExecIndexMarkPos(), ExecIndexOnlyMarkPos(), ExecMaterialMarkPos(), ExecResultMarkPos(), ExecSortMarkPos(), and nodeTag.

Referenced by ExecMergeJoin(), and ExecResultMarkPos().

◆ ExecMaterializesOutput()

bool ExecMaterializesOutput ( NodeTag  plantype)

Definition at line 635 of file execAmi.c.

636 {
637  switch (plantype)
638  {
639  case T_Material:
640  case T_FunctionScan:
641  case T_TableFuncScan:
642  case T_CteScan:
643  case T_NamedTuplestoreScan:
644  case T_WorkTableScan:
645  case T_Sort:
646  return true;
647 
648  default:
649  break;
650  }
651 
652  return false;
653 }

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

◆ ExecReScan()

void ExecReScan ( PlanState node)

Definition at line 76 of file execAmi.c.

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 */
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)
117  }
118  /* Well. Now set chgParam for child trees. */
119  if (outerPlanState(node) != NULL)
121  if (innerPlanState(node) != 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 
152  case T_RecursiveUnionState:
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 
184  case T_IndexOnlyScanState:
186  break;
187 
188  case T_BitmapIndexScanState:
190  break;
191 
192  case T_BitmapHeapScanState:
194  break;
195 
196  case T_TidScanState:
198  break;
199 
200  case T_TidRangeScanState:
202  break;
203 
204  case T_SubqueryScanState:
206  break;
207 
208  case T_FunctionScanState:
210  break;
211 
212  case T_TableFuncScanState:
214  break;
215 
216  case T_ValuesScanState:
218  break;
219 
220  case T_CteScanState:
222  break;
223 
224  case T_NamedTuplestoreScanState:
226  break;
227 
228  case T_WorkTableScanState:
230  break;
231 
232  case T_ForeignScanState:
234  break;
235 
236  case T_CustomScanState:
238  break;
239 
240  case T_NestLoopState:
242  break;
243 
244  case T_MergeJoinState:
246  break;
247 
248  case T_HashJoinState:
250  break;
251 
252  case T_MaterialState:
254  break;
255 
256  case T_MemoizeState:
258  break;
259 
260  case T_SortState:
261  ExecReScanSort((SortState *) node);
262  break;
263 
264  case T_IncrementalSortState:
266  break;
267 
268  case T_GroupState:
269  ExecReScanGroup((GroupState *) node);
270  break;
271 
272  case T_AggState:
273  ExecReScanAgg((AggState *) node);
274  break;
275 
276  case T_WindowAggState:
278  break;
279 
280  case T_UniqueState:
281  ExecReScanUnique((UniqueState *) node);
282  break;
283 
284  case T_HashState:
285  ExecReScanHash((HashState *) node);
286  break;
287 
288  case T_SetOpState:
289  ExecReScanSetOp((SetOpState *) node);
290  break;
291 
292  case T_LockRowsState:
294  break;
295 
296  case T_LimitState:
297  ExecReScanLimit((LimitState *) node);
298  break;
299 
300  default:
301  elog(ERROR, "unrecognized node type: %d", (int) nodeTag(node));
302  break;
303  }
304 
305  if (node->chgParam != NULL)
306  {
307  bms_free(node->chgParam);
308  node->chgParam = NULL;
309  }
310 }
void bms_free(Bitmapset *a)
Definition: bitmapset.c:239
#define ERROR
Definition: elog.h:39
void ReScanExprContext(ExprContext *econtext)
Definition: execUtils.c:441
void UpdateChangedParamSet(PlanState *node, Bitmapset *newchg)
Definition: execUtils.c:844
#define outerPlanState(node)
Definition: execnodes.h:1213
#define innerPlanState(node)
Definition: execnodes.h:1212
void InstrEndLoop(Instrumentation *instr)
Definition: instrument.c:140
void ExecReScanAgg(AggState *node)
Definition: nodeAgg.c:4364
void ExecReScanAppend(AppendState *node)
Definition: nodeAppend.c:406
void ExecReScanBitmapAnd(BitmapAndState *node)
void ExecReScanBitmapHeapScan(BitmapHeapScanState *node)
void ExecReScanBitmapIndexScan(BitmapIndexScanState *node)
void ExecReScanBitmapOr(BitmapOrState *node)
Definition: nodeBitmapOr.c:219
void ExecReScanCteScan(CteScanState *node)
Definition: nodeCtescan.c:307
void ExecReScanCustomScan(CustomScanState *node)
Definition: nodeCustom.c:132
void ExecReScanForeignScan(ForeignScanState *node)
void ExecReScanFunctionScan(FunctionScanState *node)
void ExecReScanGatherMerge(GatherMergeState *node)
void ExecReScanGather(GatherState *node)
Definition: nodeGather.c:435
void ExecReScanGroup(GroupState *node)
Definition: nodeGroup.c:235
void ExecReScanHash(HashState *node)
Definition: nodeHash.c:2353
void ExecReScanHashJoin(HashJoinState *node)
void ExecReScanIncrementalSort(IncrementalSortState *node)
void ExecReScanIndexOnlyScan(IndexOnlyScanState *node)
void ExecReScanIndexScan(IndexScanState *node)
void ExecReScanLimit(LimitState *node)
Definition: nodeLimit.c:541
void ExecReScanLockRows(LockRowsState *node)
Definition: nodeLockRows.c:394
void ExecReScanMaterial(MaterialState *node)
Definition: nodeMaterial.c:313
void ExecReScanMemoize(MemoizeState *node)
Definition: nodeMemoize.c:1139
void ExecReScanMergeAppend(MergeAppendState *node)
void ExecReScanMergeJoin(MergeJoinState *node)
void ExecReScanModifyTable(ModifyTableState *node)
void ExecReScanNamedTuplestoreScan(NamedTuplestoreScanState *node)
void ExecReScanNestLoop(NestLoopState *node)
Definition: nodeNestloop.c:381
void ExecReScanProjectSet(ProjectSetState *node)
void ExecReScanRecursiveUnion(RecursiveUnionState *node)
void ExecReScanResult(ResultState *node)
Definition: nodeResult.c:249
void ExecReScanSampleScan(SampleScanState *node)
void ExecReScanSeqScan(SeqScanState *node)
Definition: nodeSeqscan.c:212
void ExecReScanSetOp(SetOpState *node)
Definition: nodeSetOp.c:594
void ExecReScanSort(SortState *node)
Definition: nodeSort.c:362
void ExecReScanSetParamPlan(SubPlanState *node, PlanState *parent)
Definition: nodeSubplan.c:1291
void ExecReScanSubqueryScan(SubqueryScanState *node)
void ExecReScanTableFuncScan(TableFuncScanState *node)
void ExecReScanTidRangeScan(TidRangeScanState *node)
void ExecReScanTidScan(TidScanState *node)
Definition: nodeTidscan.c:447
void ExecReScanUnique(UniqueState *node)
Definition: nodeUnique.c:175
void ExecReScanValuesScan(ValuesScanState *node)
void ExecReScanWindowAgg(WindowAggState *node)
void ExecReScanWorkTableScan(WorkTableScanState *node)
#define lfirst(lc)
Definition: pg_list.h:172
static SPIPlanPtr splan
Definition: regress.c:269
Instrumentation * instrument
Definition: execnodes.h:1127
List * subPlan
Definition: execnodes.h:1144
List * initPlan
Definition: execnodes.h:1142
Bitmapset * chgParam
Definition: execnodes.h:1149
ExprContext * ps_ExprContext
Definition: execnodes.h:1156
struct PlanState * planstate
Definition: execnodes.h:961

References bms_free(), PlanState::chgParam, elog, ERROR, ExecReScanAgg(), ExecReScanAppend(), ExecReScanBitmapAnd(), ExecReScanBitmapHeapScan(), ExecReScanBitmapIndexScan(), ExecReScanBitmapOr(), ExecReScanCteScan(), ExecReScanCustomScan(), ExecReScanForeignScan(), ExecReScanFunctionScan(), ExecReScanGather(), ExecReScanGatherMerge(), ExecReScanGroup(), ExecReScanHash(), ExecReScanHashJoin(), ExecReScanIncrementalSort(), ExecReScanIndexOnlyScan(), ExecReScanIndexScan(), ExecReScanLimit(), ExecReScanLockRows(), ExecReScanMaterial(), ExecReScanMemoize(), ExecReScanMergeAppend(), ExecReScanMergeJoin(), ExecReScanModifyTable(), ExecReScanNamedTuplestoreScan(), ExecReScanNestLoop(), ExecReScanProjectSet(), ExecReScanRecursiveUnion(), ExecReScanResult(), ExecReScanSampleScan(), ExecReScanSeqScan(), ExecReScanSetOp(), ExecReScanSetParamPlan(), ExecReScanSort(), ExecReScanSubqueryScan(), ExecReScanTableFuncScan(), ExecReScanTidRangeScan(), ExecReScanTidScan(), ExecReScanUnique(), ExecReScanValuesScan(), ExecReScanWindowAgg(), ExecReScanWorkTableScan(), PlanState::initPlan, innerPlanState, InstrEndLoop(), PlanState::instrument, lfirst, nodeTag, outerPlanState, SubPlanState::planstate, PlanState::ps_ExprContext, ReScanExprContext(), splan, PlanState::subPlan, and UpdateChangedParamSet().

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

◆ ExecRestrPos()

void ExecRestrPos ( PlanState node)

Definition at line 375 of file execAmi.c.

376 {
377  switch (nodeTag(node))
378  {
379  case T_IndexScanState:
381  break;
382 
383  case T_IndexOnlyScanState:
385  break;
386 
387  case T_CustomScanState:
389  break;
390 
391  case T_MaterialState:
393  break;
394 
395  case T_SortState:
396  ExecSortRestrPos((SortState *) node);
397  break;
398 
399  case T_ResultState:
401  break;
402 
403  default:
404  elog(ERROR, "unrecognized node type: %d", (int) nodeTag(node));
405  break;
406  }
407 }
void ExecCustomRestrPos(CustomScanState *node)
Definition: nodeCustom.c:150
void ExecIndexOnlyRestrPos(IndexOnlyScanState *node)
void ExecIndexRestrPos(IndexScanState *node)
void ExecMaterialRestrPos(MaterialState *node)
Definition: nodeMaterial.c:290
void ExecResultRestrPos(ResultState *node)
Definition: nodeResult.c:161
void ExecSortRestrPos(SortState *node)
Definition: nodeSort.c:347

References elog, ERROR, ExecCustomRestrPos(), ExecIndexOnlyRestrPos(), ExecIndexRestrPos(), ExecMaterialRestrPos(), ExecResultRestrPos(), ExecSortRestrPos(), and nodeTag.

Referenced by ExecMergeJoin(), and ExecResultRestrPos().

◆ ExecSupportsBackwardScan()

bool ExecSupportsBackwardScan ( Plan node)

Definition at line 510 of file execAmi.c.

511 {
512  if (node == NULL)
513  return false;
514 
515  /*
516  * Parallel-aware nodes return a subset of the tuples in each worker, and
517  * in general we can't expect to have enough bookkeeping state to know
518  * which ones we returned in this worker as opposed to some other worker.
519  */
520  if (node->parallel_aware)
521  return false;
522 
523  switch (nodeTag(node))
524  {
525  case T_Result:
526  if (outerPlan(node) != NULL)
527  return ExecSupportsBackwardScan(outerPlan(node));
528  else
529  return false;
530 
531  case T_Append:
532  {
533  ListCell *l;
534 
535  /* With async, tuples may be interleaved, so can't back up. */
536  if (((Append *) node)->nasyncplans > 0)
537  return false;
538 
539  foreach(l, ((Append *) node)->appendplans)
540  {
541  if (!ExecSupportsBackwardScan((Plan *) lfirst(l)))
542  return false;
543  }
544  /* need not check tlist because Append doesn't evaluate it */
545  return true;
546  }
547 
548  case T_SampleScan:
549  /* Simplify life for tablesample methods by disallowing this */
550  return false;
551 
552  case T_Gather:
553  return false;
554 
555  case T_IndexScan:
556  return IndexSupportsBackwardScan(((IndexScan *) node)->indexid);
557 
558  case T_IndexOnlyScan:
559  return IndexSupportsBackwardScan(((IndexOnlyScan *) node)->indexid);
560 
561  case T_SubqueryScan:
562  return ExecSupportsBackwardScan(((SubqueryScan *) node)->subplan);
563 
564  case T_CustomScan:
565  if (((CustomScan *) node)->flags & CUSTOMPATH_SUPPORT_BACKWARD_SCAN)
566  return true;
567  return false;
568 
569  case T_SeqScan:
570  case T_TidScan:
571  case T_TidRangeScan:
572  case T_FunctionScan:
573  case T_ValuesScan:
574  case T_CteScan:
575  case T_Material:
576  case T_Sort:
577  /* these don't evaluate tlist */
578  return true;
579 
580  case T_IncrementalSort:
581 
582  /*
583  * Unlike full sort, incremental sort keeps only a single group of
584  * tuples in memory, so it can't scan backwards.
585  */
586  return false;
587 
588  case T_LockRows:
589  case T_Limit:
590  return ExecSupportsBackwardScan(outerPlan(node));
591 
592  default:
593  return false;
594  }
595 }
static bool IndexSupportsBackwardScan(Oid indexid)
Definition: execAmi.c:602
bool ExecSupportsBackwardScan(Plan *node)
Definition: execAmi.c:510
#define CUSTOMPATH_SUPPORT_BACKWARD_SCAN
Definition: extensible.h:84
#define outerPlan(node)
Definition: plannodes.h:182
bool parallel_aware
Definition: plannodes.h:140

References CUSTOMPATH_SUPPORT_BACKWARD_SCAN, IndexSupportsBackwardScan(), lfirst, nodeTag, outerPlan, and Plan::parallel_aware.

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

◆ ExecSupportsMarkRestore()

bool ExecSupportsMarkRestore ( Path pathnode)

Definition at line 417 of file execAmi.c.

418 {
419  /*
420  * For consistency with the routines above, we do not examine the nodeTag
421  * but rather the pathtype, which is the Plan node type the Path would
422  * produce.
423  */
424  switch (pathnode->pathtype)
425  {
426  case T_IndexScan:
427  case T_IndexOnlyScan:
428 
429  /*
430  * Not all index types support mark/restore.
431  */
432  return castNode(IndexPath, pathnode)->indexinfo->amcanmarkpos;
433 
434  case T_Material:
435  case T_Sort:
436  return true;
437 
438  case T_CustomScan:
439  if (castNode(CustomPath, pathnode)->flags & CUSTOMPATH_SUPPORT_MARK_RESTORE)
440  return true;
441  return false;
442 
443  case T_Result:
444 
445  /*
446  * Result supports mark/restore iff it has a child plan that does.
447  *
448  * We have to be careful here because there is more than one Path
449  * type that can produce a Result plan node.
450  */
451  if (IsA(pathnode, ProjectionPath))
452  return ExecSupportsMarkRestore(((ProjectionPath *) pathnode)->subpath);
453  else if (IsA(pathnode, MinMaxAggPath))
454  return false; /* childless Result */
455  else if (IsA(pathnode, GroupResultPath))
456  return false; /* childless Result */
457  else
458  {
459  /* Simple RTE_RESULT base relation */
460  Assert(IsA(pathnode, Path));
461  return false; /* childless Result */
462  }
463 
464  case T_Append:
465  {
466  AppendPath *appendPath = castNode(AppendPath, pathnode);
467 
468  /*
469  * If there's exactly one child, then there will be no Append
470  * in the final plan, so we can handle mark/restore if the
471  * child plan node can.
472  */
473  if (list_length(appendPath->subpaths) == 1)
474  return ExecSupportsMarkRestore((Path *) linitial(appendPath->subpaths));
475  /* Otherwise, Append can't handle it */
476  return false;
477  }
478 
479  case T_MergeAppend:
480  {
481  MergeAppendPath *mapath = castNode(MergeAppendPath, pathnode);
482 
483  /*
484  * Like the Append case above, single-subpath MergeAppends
485  * won't be in the final plan, so just return the child's
486  * mark/restore ability.
487  */
488  if (list_length(mapath->subpaths) == 1)
489  return ExecSupportsMarkRestore((Path *) linitial(mapath->subpaths));
490  /* Otherwise, MergeAppend can't handle it */
491  return false;
492  }
493 
494  default:
495  break;
496  }
497 
498  return false;
499 }
#define Assert(condition)
Definition: c.h:858
bool ExecSupportsMarkRestore(Path *pathnode)
Definition: execAmi.c:417
#define CUSTOMPATH_SUPPORT_MARK_RESTORE
Definition: extensible.h:85
Datum subpath(PG_FUNCTION_ARGS)
Definition: ltree_op.c:310
#define IsA(nodeptr, _type_)
Definition: nodes.h:158
#define castNode(_type_, nodeptr)
Definition: nodes.h:176
static int list_length(const List *l)
Definition: pg_list.h:152
#define linitial(l)
Definition: pg_list.h:178
List * subpaths
Definition: pathnodes.h:1921
NodeTag pathtype
Definition: pathnodes.h:1615

References Assert, castNode, CUSTOMPATH_SUPPORT_MARK_RESTORE, IsA, linitial, list_length(), Path::pathtype, subpath(), AppendPath::subpaths, and MergeAppendPath::subpaths.

Referenced by final_cost_mergejoin().

◆ IndexSupportsBackwardScan()

static bool IndexSupportsBackwardScan ( Oid  indexid)
static

Definition at line 602 of file execAmi.c.

603 {
604  bool result;
605  HeapTuple ht_idxrel;
606  Form_pg_class idxrelrec;
607  IndexAmRoutine *amroutine;
608 
609  /* Fetch the pg_class tuple of the index relation */
610  ht_idxrel = SearchSysCache1(RELOID, ObjectIdGetDatum(indexid));
611  if (!HeapTupleIsValid(ht_idxrel))
612  elog(ERROR, "cache lookup failed for relation %u", indexid);
613  idxrelrec = (Form_pg_class) GETSTRUCT(ht_idxrel);
614 
615  /* Fetch the index AM's API struct */
616  amroutine = GetIndexAmRoutineByAmId(idxrelrec->relam, false);
617 
618  result = amroutine->amcanbackward;
619 
620  pfree(amroutine);
621  ReleaseSysCache(ht_idxrel);
622 
623  return result;
624 }
IndexAmRoutine * GetIndexAmRoutineByAmId(Oid amoid, bool noerror)
Definition: amapi.c:56
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define GETSTRUCT(TUP)
Definition: htup_details.h:653
void pfree(void *pointer)
Definition: mcxt.c:1520
FormData_pg_class * Form_pg_class
Definition: pg_class.h:153
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:252
bool amcanbackward
Definition: amapi.h:228
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:266
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:218

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

Referenced by ExecSupportsBackwardScan().