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/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/nodeResultCache.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.

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

329 {
330  switch (nodeTag(node))
331  {
332  case T_IndexScanState:
334  break;
335 
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 }
void ExecIndexOnlyMarkPos(IndexOnlyScanState *node)
#define DEBUG2
Definition: elog.h:24
void ExecSortMarkPos(SortState *node)
Definition: nodeSort.c:270
void ExecIndexMarkPos(IndexScanState *node)
void ExecCustomMarkPos(CustomScanState *node)
Definition: nodeCustom.c:140
void ExecResultMarkPos(ResultState *node)
Definition: nodeResult.c:147
#define nodeTag(nodeptr)
Definition: nodes.h:544
#define elog(elevel,...)
Definition: elog.h:232
void ExecMaterialMarkPos(MaterialState *node)
Definition: nodeMaterial.c:267

◆ ExecMaterializesOutput()

bool ExecMaterializesOutput ( NodeTag  plantype)

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

644 {
645  switch (plantype)
646  {
647  case T_Material:
648  case T_FunctionScan:
649  case T_TableFuncScan:
650  case T_CteScan:
652  case T_WorkTableScan:
653  case T_Sort:
654  return true;
655 
656  default:
657  break;
658  }
659 
660  return false;
661 }
Definition: nodes.h:78

◆ ExecReScan()

void ExecReScan ( PlanState node)

Definition at line 78 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(), ExecReScanIncrementalSort(), ExecReScanIndexOnlyScan(), ExecReScanIndexScan(), ExecReScanLimit(), ExecReScanLockRows(), ExecReScanMaterial(), ExecReScanMergeAppend(), ExecReScanMergeJoin(), ExecReScanModifyTable(), ExecReScanNamedTuplestoreScan(), ExecReScanNestLoop(), ExecReScanProjectSet(), ExecReScanRecursiveUnion(), ExecReScanResult(), ExecReScanResultCache(), ExecReScanSampleScan(), ExecReScanSeqScan(), ExecReScanSetOp(), ExecReScanSetParamPlan(), ExecReScanSort(), ExecReScanSubqueryScan(), ExecReScanTableFuncScan(), ExecReScanTidRangeScan(), 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_IncrementalSortState, 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_ResultCacheState, T_ResultState, T_SampleScanState, T_SeqScanState, T_SetOpState, T_SortState, T_SubqueryScanState, T_TableFuncScanState, T_TidRangeScanState, 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(), ExecReScanIncrementalSort(), ExecReScanLimit(), ExecReScanLockRows(), ExecReScanMaterial(), ExecReScanMergeAppend(), ExecReScanMergeJoin(), ExecReScanNestLoop(), ExecReScanProjectSet(), ExecReScanRecursiveUnion(), ExecReScanResult(), ExecReScanResultCache(), ExecReScanSetOp(), ExecReScanSort(), ExecReScanSubqueryScan(), ExecReScanUnique(), ExecReScanWindowAgg(), ExecScanSubPlan(), ExecutorRewind(), MultiExecBitmapIndexScan(), and MultiExecProcNode().

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 */
108  UpdateChangedParamSet(splan, node->chgParam);
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)
118  UpdateChangedParamSet(splan, node->chgParam);
119  }
120  /* Well. Now set chgParam for left/right trees. */
121  if (node->lefttree != NULL)
123  if (node->righttree != 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 
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 
188  break;
189 
192  break;
193 
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 
216  break;
217 
218  case T_ValuesScanState:
220  break;
221 
222  case T_CteScanState:
224  break;
225 
228  break;
229 
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_ResultCacheState:
260  break;
261 
262  case T_SortState:
263  ExecReScanSort((SortState *) node);
264  break;
265 
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 ExecReScanBitmapHeapScan(BitmapHeapScanState *node)
void ExecReScanGroup(GroupState *node)
Definition: nodeGroup.c:241
void ExecReScanModifyTable(ModifyTableState *node)
Instrumentation * instrument
Definition: execnodes.h:974
List * initPlan
Definition: execnodes.h:989
void ExecReScanMaterial(MaterialState *node)
Definition: nodeMaterial.c:318
ExprContext * ps_ExprContext
Definition: execnodes.h:1003
void ExecReScanLockRows(LockRowsState *node)
Definition: nodeLockRows.c:390
void ExecReScanFunctionScan(FunctionScanState *node)
List * subPlan
Definition: execnodes.h:991
void ExecReScanResultCache(ResultCacheState *node)
void ExecReScanIndexOnlyScan(IndexOnlyScanState *node)
void ExecReScanLimit(LimitState *node)
Definition: nodeLimit.c:543
void ExecReScanWorkTableScan(WorkTableScanState *node)
struct PlanState * righttree
Definition: execnodes.h:987
void ExecReScanResult(ResultState *node)
Definition: nodeResult.c:260
void ExecReScanSetOp(SetOpState *node)
Definition: nodeSetOp.c:598
void ExecReScanSort(SortState *node)
Definition: nodeSort.c:303
void ExecReScanForeignScan(ForeignScanState *node)
struct PlanState * lefttree
Definition: execnodes.h:986
void InstrEndLoop(Instrumentation *instr)
Definition: instrument.c:121
void ExecReScanHash(HashState *node)
Definition: nodeHash.c:2196
void ExecReScanProjectSet(ProjectSetState *node)
#define ERROR
Definition: elog.h:46
struct PlanState * planstate
Definition: execnodes.h:882
void ExecReScanSetParamPlan(SubPlanState *node, PlanState *parent)
Definition: nodeSubplan.c:1276
void ExecReScanBitmapIndexScan(BitmapIndexScanState *node)
void ExecReScanUnique(UniqueState *node)
Definition: nodeUnique.c:181
void ExecReScanIndexScan(IndexScanState *node)
void ExecReScanTidRangeScan(TidRangeScanState *node)
void ExecReScanGatherMerge(GatherMergeState *node)
void ExecReScanMergeAppend(MergeAppendState *node)
void ExecReScanNestLoop(NestLoopState *node)
Definition: nodeNestloop.c:392
static SPIPlanPtr splan
Definition: regress.c:262
Bitmapset * chgParam
Definition: execnodes.h:996
void ExecReScanGather(GatherState *node)
Definition: nodeGather.c:443
void ExecReScanNamedTuplestoreScan(NamedTuplestoreScanState *node)
void ExecReScanAppend(AppendState *node)
Definition: nodeAppend.c:407
void ExecReScanSubqueryScan(SubqueryScanState *node)
void ExecReScanIncrementalSort(IncrementalSortState *node)
Plan * plan
Definition: execnodes.h:964
void ExecReScanBitmapOr(BitmapOrState *node)
Definition: nodeBitmapOr.c:219
void ExecReScanRecursiveUnion(RecursiveUnionState *node)
void UpdateChangedParamSet(PlanState *node, Bitmapset *newchg)
Definition: execUtils.c:864
void bms_free(Bitmapset *a)
Definition: bitmapset.c:208
#define lfirst(lc)
Definition: pg_list.h:169
void ExecReScanBitmapAnd(BitmapAndState *node)
void ExecReScanAgg(AggState *node)
Definition: nodeAgg.c:4440
Bitmapset * extParam
Definition: plannodes.h:159
void ReScanExprContext(ExprContext *econtext)
Definition: execUtils.c:438
#define nodeTag(nodeptr)
Definition: nodes.h:544
void ExecReScanValuesScan(ValuesScanState *node)
#define elog(elevel,...)
Definition: elog.h:232
void ExecReScanSampleScan(SampleScanState *node)
void ExecReScanCteScan(CteScanState *node)
Definition: nodeCtescan.c:319
void ExecReScanWindowAgg(WindowAggState *node)
void ExecReScanTidScan(TidScanState *node)
Definition: nodeTidscan.c:445
void ExecReScanMergeJoin(MergeJoinState *node)
void ExecReScanCustomScan(CustomScanState *node)
Definition: nodeCustom.c:133
void ExecReScanTableFuncScan(TableFuncScanState *node)
void ExecReScanSeqScan(SeqScanState *node)
Definition: nodeSeqscan.c:224
void ExecReScanHashJoin(HashJoinState *node)

◆ ExecRestrPos()

void ExecRestrPos ( PlanState node)

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

378 {
379  switch (nodeTag(node))
380  {
381  case T_IndexScanState:
383  break;
384 
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 ExecMaterialRestrPos(MaterialState *node)
Definition: nodeMaterial.c:295
void ExecIndexOnlyRestrPos(IndexOnlyScanState *node)
void ExecResultRestrPos(ResultState *node)
Definition: nodeResult.c:162
void ExecCustomRestrPos(CustomScanState *node)
Definition: nodeCustom.c:151
#define ERROR
Definition: elog.h:46
void ExecSortRestrPos(SortState *node)
Definition: nodeSort.c:288
void ExecIndexRestrPos(IndexScanState *node)
#define nodeTag(nodeptr)
Definition: nodes.h:544
#define elog(elevel,...)
Definition: elog.h:232

◆ ExecSupportsBackwardScan()

bool ExecSupportsBackwardScan ( Plan node)

Definition at line 514 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_IncrementalSort, T_IndexOnlyScan, T_IndexScan, T_Limit, T_LockRows, T_Material, T_Result, T_SampleScan, T_SeqScan, T_Sort, T_SubqueryScan, T_TidRangeScan, T_TidScan, and T_ValuesScan.

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

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

◆ ExecSupportsMarkRestore()

bool ExecSupportsMarkRestore ( Path pathnode)

Definition at line 419 of file execAmi.c.

References Assert, castNode, CUSTOMPATH_SUPPORT_MARK_RESTORE, ExecSupportsMarkRestore(), CustomPath::flags, IsA, linitial, list_length(), Path::pathtype, subpath(), AppendPath::subpaths, MergeAppendPath::subpaths, T_Append, T_CustomScan, T_IndexOnlyScan, T_IndexScan, T_Material, T_MergeAppend, T_Result, and T_Sort.

Referenced by ExecSupportsMarkRestore(), and final_cost_mergejoin().

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  * Not all index types support mark/restore.
432  */
433  return castNode(IndexPath, pathnode)->indexinfo->amcanmarkpos;
434 
435  case T_Material:
436  case T_Sort:
437  return true;
438 
439  case T_CustomScan:
440  {
441  CustomPath *customPath = castNode(CustomPath, pathnode);
442 
443  if (customPath->flags & CUSTOMPATH_SUPPORT_MARK_RESTORE)
444  return true;
445  return false;
446  }
447  case T_Result:
448 
449  /*
450  * Result supports mark/restore iff it has a child plan that does.
451  *
452  * We have to be careful here because there is more than one Path
453  * type that can produce a Result plan node.
454  */
455  if (IsA(pathnode, ProjectionPath))
456  return ExecSupportsMarkRestore(((ProjectionPath *) pathnode)->subpath);
457  else if (IsA(pathnode, MinMaxAggPath))
458  return false; /* childless Result */
459  else if (IsA(pathnode, GroupResultPath))
460  return false; /* childless Result */
461  else
462  {
463  /* Simple RTE_RESULT base relation */
464  Assert(IsA(pathnode, Path));
465  return false; /* childless Result */
466  }
467 
468  case T_Append:
469  {
470  AppendPath *appendPath = castNode(AppendPath, pathnode);
471 
472  /*
473  * If there's exactly one child, then there will be no Append
474  * in the final plan, so we can handle mark/restore if the
475  * child plan node can.
476  */
477  if (list_length(appendPath->subpaths) == 1)
478  return ExecSupportsMarkRestore((Path *) linitial(appendPath->subpaths));
479  /* Otherwise, Append can't handle it */
480  return false;
481  }
482 
483  case T_MergeAppend:
484  {
485  MergeAppendPath *mapath = castNode(MergeAppendPath, pathnode);
486 
487  /*
488  * Like the Append case above, single-subpath MergeAppends
489  * won't be in the final plan, so just return the child's
490  * mark/restore ability.
491  */
492  if (list_length(mapath->subpaths) == 1)
493  return ExecSupportsMarkRestore((Path *) linitial(mapath->subpaths));
494  /* Otherwise, MergeAppend can't handle it */
495  return false;
496  }
497 
498  default:
499  break;
500  }
501 
502  return false;
503 }
#define IsA(nodeptr, _type_)
Definition: nodes.h:590
bool ExecSupportsMarkRestore(Path *pathnode)
Definition: execAmi.c:419
#define castNode(_type_, nodeptr)
Definition: nodes.h:608
#define CUSTOMPATH_SUPPORT_MARK_RESTORE
Definition: extensible.h:82
Definition: nodes.h:49
uint32 flags
Definition: pathnodes.h:1419
Definition: nodes.h:78
NodeTag pathtype
Definition: pathnodes.h:1172
List * subpaths
Definition: pathnodes.h:1444
#define linitial(l)
Definition: pg_list.h:174
Definition: nodes.h:46
#define Assert(condition)
Definition: c.h:804
static int list_length(const List *l)
Definition: pg_list.h:149
Datum subpath(PG_FUNCTION_ARGS)
Definition: ltree_op.c:241

◆ IndexSupportsBackwardScan()

static bool IndexSupportsBackwardScan ( Oid  indexid)
static

Definition at line 610 of file execAmi.c.

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

Referenced by ExecSupportsBackwardScan().

611 {
612  bool result;
613  HeapTuple ht_idxrel;
614  Form_pg_class idxrelrec;
615  IndexAmRoutine *amroutine;
616 
617  /* Fetch the pg_class tuple of the index relation */
618  ht_idxrel = SearchSysCache1(RELOID, ObjectIdGetDatum(indexid));
619  if (!HeapTupleIsValid(ht_idxrel))
620  elog(ERROR, "cache lookup failed for relation %u", indexid);
621  idxrelrec = (Form_pg_class) GETSTRUCT(ht_idxrel);
622 
623  /* Fetch the index AM's API struct */
624  amroutine = GetIndexAmRoutineByAmId(idxrelrec->relam, false);
625 
626  result = amroutine->amcanbackward;
627 
628  pfree(amroutine);
629  ReleaseSysCache(ht_idxrel);
630 
631  return result;
632 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:654
void pfree(void *pointer)
Definition: mcxt.c:1169
#define ObjectIdGetDatum(X)
Definition: postgres.h:551
#define ERROR
Definition: elog.h:46
IndexAmRoutine * GetIndexAmRoutineByAmId(Oid amoid, bool noerror)
Definition: amapi.c:56
bool amcanbackward
Definition: amapi.h:224
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1127
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1175
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
FormData_pg_class * Form_pg_class
Definition: pg_class.h:153
#define elog(elevel,...)
Definition: elog.h:232