PostgreSQL Source Code  git master
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/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/nodeFuncs.h"
#include "nodes/pathnodes.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

◆ ExecMarkPos()

void ExecMarkPos ( PlanState node)

Definition at line 328 of file execAmi.c.

329 {
330  switch (nodeTag(node))
331  {
332  case T_IndexScanState:
334  break;
335 
336  case T_IndexOnlyScanState:
338  break;
339 
340  case T_CustomScanState:
342  break;
343 
344  case T_MaterialState:
346  break;
347 
348  case T_SortState:
349  ExecSortMarkPos((SortState *) node);
350  break;
351 
352  case T_ResultState:
353  ExecResultMarkPos((ResultState *) node);
354  break;
355 
356  default:
357  /* don't make hard error unless caller asks to restore... */
358  elog(DEBUG2, "unrecognized node type: %d", (int) nodeTag(node));
359  break;
360  }
361 }
#define DEBUG2
Definition: elog.h:29
void ExecCustomMarkPos(CustomScanState *node)
Definition: nodeCustom.c:142
void ExecIndexOnlyMarkPos(IndexOnlyScanState *node)
void ExecIndexMarkPos(IndexScanState *node)
void ExecMaterialMarkPos(MaterialState *node)
Definition: nodeMaterial.c:262
void ExecResultMarkPos(ResultState *node)
Definition: nodeResult.c:147
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 637 of file execAmi.c.

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

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

◆ ExecReScan()

void ExecReScan ( PlanState node)

Definition at line 78 of file execAmi.c.

79 {
80  /* If collecting timing stats, update them */
81  if (node->instrument)
82  InstrEndLoop(node->instrument);
83 
84  /*
85  * If we have changed parameters, propagate that info.
86  *
87  * Note: ExecReScanSetParamPlan() can add bits to node->chgParam,
88  * corresponding to the output param(s) that the InitPlan will update.
89  * Since we make only one pass over the list, that means that an InitPlan
90  * can depend on the output param(s) of a sibling InitPlan only if that
91  * sibling appears earlier in the list. This is workable for now given
92  * the limited ways in which one InitPlan could depend on another, but
93  * eventually we might need to work harder (or else make the planner
94  * enlarge the extParam/allParam sets to include the params of depended-on
95  * InitPlans).
96  */
97  if (node->chgParam != NULL)
98  {
99  ListCell *l;
100 
101  foreach(l, node->initPlan)
102  {
103  SubPlanState *sstate = (SubPlanState *) lfirst(l);
104  PlanState *splan = sstate->planstate;
105 
106  if (splan->plan->extParam != NULL) /* don't care about child
107  * local Params */
109  if (splan->chgParam != NULL)
110  ExecReScanSetParamPlan(sstate, node);
111  }
112  foreach(l, node->subPlan)
113  {
114  SubPlanState *sstate = (SubPlanState *) lfirst(l);
115  PlanState *splan = sstate->planstate;
116 
117  if (splan->plan->extParam != NULL)
119  }
120  /* Well. Now set chgParam for child trees. */
121  if (outerPlanState(node) != NULL)
123  if (innerPlanState(node) != NULL)
125  }
126 
127  /* Call expression callbacks */
128  if (node->ps_ExprContext)
130 
131  /* And do node-type-specific processing */
132  switch (nodeTag(node))
133  {
134  case T_ResultState:
135  ExecReScanResult((ResultState *) node);
136  break;
137 
138  case T_ProjectSetState:
140  break;
141 
142  case T_ModifyTableState:
144  break;
145 
146  case T_AppendState:
147  ExecReScanAppend((AppendState *) node);
148  break;
149 
150  case T_MergeAppendState:
152  break;
153 
154  case T_RecursiveUnionState:
156  break;
157 
158  case T_BitmapAndState:
160  break;
161 
162  case T_BitmapOrState:
164  break;
165 
166  case T_SeqScanState:
168  break;
169 
170  case T_SampleScanState:
172  break;
173 
174  case T_GatherState:
175  ExecReScanGather((GatherState *) node);
176  break;
177 
178  case T_GatherMergeState:
180  break;
181 
182  case T_IndexScanState:
184  break;
185 
186  case T_IndexOnlyScanState:
188  break;
189 
190  case T_BitmapIndexScanState:
192  break;
193 
194  case T_BitmapHeapScanState:
196  break;
197 
198  case T_TidScanState:
200  break;
201 
202  case T_TidRangeScanState:
204  break;
205 
206  case T_SubqueryScanState:
208  break;
209 
210  case T_FunctionScanState:
212  break;
213 
214  case T_TableFuncScanState:
216  break;
217 
218  case T_ValuesScanState:
220  break;
221 
222  case T_CteScanState:
224  break;
225 
226  case T_NamedTuplestoreScanState:
228  break;
229 
230  case T_WorkTableScanState:
232  break;
233 
234  case T_ForeignScanState:
236  break;
237 
238  case T_CustomScanState:
240  break;
241 
242  case T_NestLoopState:
244  break;
245 
246  case T_MergeJoinState:
248  break;
249 
250  case T_HashJoinState:
252  break;
253 
254  case T_MaterialState:
256  break;
257 
258  case T_MemoizeState:
260  break;
261 
262  case T_SortState:
263  ExecReScanSort((SortState *) node);
264  break;
265 
266  case T_IncrementalSortState:
268  break;
269 
270  case T_GroupState:
271  ExecReScanGroup((GroupState *) node);
272  break;
273 
274  case T_AggState:
275  ExecReScanAgg((AggState *) node);
276  break;
277 
278  case T_WindowAggState:
280  break;
281 
282  case T_UniqueState:
283  ExecReScanUnique((UniqueState *) node);
284  break;
285 
286  case T_HashState:
287  ExecReScanHash((HashState *) node);
288  break;
289 
290  case T_SetOpState:
291  ExecReScanSetOp((SetOpState *) node);
292  break;
293 
294  case T_LockRowsState:
296  break;
297 
298  case T_LimitState:
299  ExecReScanLimit((LimitState *) node);
300  break;
301 
302  default:
303  elog(ERROR, "unrecognized node type: %d", (int) nodeTag(node));
304  break;
305  }
306 
307  if (node->chgParam != NULL)
308  {
309  bms_free(node->chgParam);
310  node->chgParam = NULL;
311  }
312 }
void bms_free(Bitmapset *a)
Definition: bitmapset.c:194
#define ERROR
Definition: elog.h:39
void ReScanExprContext(ExprContext *econtext)
Definition: execUtils.c:446
void UpdateChangedParamSet(PlanState *node, Bitmapset *newchg)
Definition: execUtils.c:849
#define outerPlanState(node)
Definition: execnodes.h:1133
#define innerPlanState(node)
Definition: execnodes.h:1132
void InstrEndLoop(Instrumentation *instr)
Definition: instrument.c:140
void ExecReScanAgg(AggState *node)
Definition: nodeAgg.c:4365
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:135
void ExecReScanForeignScan(ForeignScanState *node)
void ExecReScanFunctionScan(FunctionScanState *node)
void ExecReScanGatherMerge(GatherMergeState *node)
void ExecReScanGather(GatherState *node)
Definition: nodeGather.c:440
void ExecReScanGroup(GroupState *node)
Definition: nodeGroup.c:236
void ExecReScanHash(HashState *node)
Definition: nodeHash.c:2345
void ExecReScanHashJoin(HashJoinState *node)
void ExecReScanIncrementalSort(IncrementalSortState *node)
void ExecReScanIndexOnlyScan(IndexOnlyScanState *node)
void ExecReScanIndexScan(IndexScanState *node)
void ExecReScanLimit(LimitState *node)
Definition: nodeLimit.c:542
void ExecReScanLockRows(LockRowsState *node)
Definition: nodeLockRows.c:394
void ExecReScanMaterial(MaterialState *node)
Definition: nodeMaterial.c:313
void ExecReScanMemoize(MemoizeState *node)
Definition: nodeMemoize.c:1100
void ExecReScanMergeAppend(MergeAppendState *node)
void ExecReScanMergeJoin(MergeJoinState *node)
void ExecReScanModifyTable(ModifyTableState *node)
void ExecReScanNamedTuplestoreScan(NamedTuplestoreScanState *node)
void ExecReScanNestLoop(NestLoopState *node)
Definition: nodeNestloop.c:382
void ExecReScanProjectSet(ProjectSetState *node)
void ExecReScanRecursiveUnion(RecursiveUnionState *node)
void ExecReScanResult(ResultState *node)
Definition: nodeResult.c:250
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:448
void ExecReScanUnique(UniqueState *node)
Definition: nodeUnique.c:176
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:270
Instrumentation * instrument
Definition: execnodes.h:1047
List * subPlan
Definition: execnodes.h:1064
List * initPlan
Definition: execnodes.h:1062
Bitmapset * chgParam
Definition: execnodes.h:1069
ExprContext * ps_ExprContext
Definition: execnodes.h:1076
struct PlanState * planstate
Definition: execnodes.h:953

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 377 of file execAmi.c.

378 {
379  switch (nodeTag(node))
380  {
381  case T_IndexScanState:
383  break;
384 
385  case T_IndexOnlyScanState:
387  break;
388 
389  case T_CustomScanState:
391  break;
392 
393  case T_MaterialState:
395  break;
396 
397  case T_SortState:
398  ExecSortRestrPos((SortState *) node);
399  break;
400 
401  case T_ResultState:
403  break;
404 
405  default:
406  elog(ERROR, "unrecognized node type: %d", (int) nodeTag(node));
407  break;
408  }
409 }
void ExecCustomRestrPos(CustomScanState *node)
Definition: nodeCustom.c:153
void ExecIndexOnlyRestrPos(IndexOnlyScanState *node)
void ExecIndexRestrPos(IndexScanState *node)
void ExecMaterialRestrPos(MaterialState *node)
Definition: nodeMaterial.c:290
void ExecResultRestrPos(ResultState *node)
Definition: nodeResult.c:162
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 512 of file execAmi.c.

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

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 419 of file execAmi.c.

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

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 604 of file execAmi.c.

605 {
606  bool result;
607  HeapTuple ht_idxrel;
608  Form_pg_class idxrelrec;
609  IndexAmRoutine *amroutine;
610 
611  /* Fetch the pg_class tuple of the index relation */
612  ht_idxrel = SearchSysCache1(RELOID, ObjectIdGetDatum(indexid));
613  if (!HeapTupleIsValid(ht_idxrel))
614  elog(ERROR, "cache lookup failed for relation %u", indexid);
615  idxrelrec = (Form_pg_class) GETSTRUCT(ht_idxrel);
616 
617  /* Fetch the index AM's API struct */
618  amroutine = GetIndexAmRoutineByAmId(idxrelrec->relam, false);
619 
620  result = amroutine->amcanbackward;
621 
622  pfree(amroutine);
623  ReleaseSysCache(ht_idxrel);
624 
625  return result;
626 }
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:1456
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:224
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:868
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:820
@ RELOID
Definition: syscache.h:89

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

Referenced by ExecSupportsBackwardScan().