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.

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:326
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:541
#define elog(elevel,...)
Definition: elog.h:232
void ExecMaterialMarkPos(MaterialState *node)
Definition: nodeMaterial.c:267

◆ ExecMaterializesOutput()

bool ExecMaterializesOutput ( NodeTag  plantype)

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

638 {
639  switch (plantype)
640  {
641  case T_Material:
642  case T_FunctionScan:
643  case T_TableFuncScan:
644  case T_CteScan:
646  case T_WorkTableScan:
647  case T_Sort:
648  return true;
649 
650  default:
651  break;
652  }
653 
654  return false;
655 }
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(), ExecReScanMemoize(), ExecReScanMergeAppend(), ExecReScanMergeJoin(), ExecReScanModifyTable(), ExecReScanNamedTuplestoreScan(), ExecReScanNestLoop(), ExecReScanProjectSet(), ExecReScanRecursiveUnion(), ExecReScanResult(), 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_MemoizeState, T_MergeAppendState, T_MergeJoinState, T_ModifyTableState, T_NamedTuplestoreScanState, T_NestLoopState, T_ProjectSetState, T_RecursiveUnionState, 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(), 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().

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_MemoizeState:
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:976
List * initPlan
Definition: execnodes.h:991
void ExecReScanMaterial(MaterialState *node)
Definition: nodeMaterial.c:318
ExprContext * ps_ExprContext
Definition: execnodes.h:1005
void ExecReScanLockRows(LockRowsState *node)
Definition: nodeLockRows.c:395
void ExecReScanFunctionScan(FunctionScanState *node)
List * subPlan
Definition: execnodes.h:993
void ExecReScanIndexOnlyScan(IndexOnlyScanState *node)
void ExecReScanLimit(LimitState *node)
Definition: nodeLimit.c:543
void ExecReScanWorkTableScan(WorkTableScanState *node)
struct PlanState * righttree
Definition: execnodes.h:989
void ExecReScanResult(ResultState *node)
Definition: nodeResult.c:260
void ExecReScanSetOp(SetOpState *node)
Definition: nodeSetOp.c:598
void ExecReScanSort(SortState *node)
Definition: nodeSort.c:359
void ExecReScanForeignScan(ForeignScanState *node)
struct PlanState * lefttree
Definition: execnodes.h:988
void InstrEndLoop(Instrumentation *instr)
Definition: instrument.c:140
void ExecReScanHash(HashState *node)
Definition: nodeHash.c:2213
void ExecReScanProjectSet(ProjectSetState *node)
#define ERROR
Definition: elog.h:46
struct PlanState * planstate
Definition: execnodes.h:884
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:263
Bitmapset * chgParam
Definition: execnodes.h:998
void ExecReScanGather(GatherState *node)
Definition: nodeGather.c:443
void ExecReScanNamedTuplestoreScan(NamedTuplestoreScanState *node)
void ExecReScanAppend(AppendState *node)
Definition: nodeAppend.c:415
void ExecReScanSubqueryScan(SubqueryScanState *node)
void ExecReScanIncrementalSort(IncrementalSortState *node)
Plan * plan
Definition: execnodes.h:966
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:4437
Bitmapset * extParam
Definition: plannodes.h:159
void ReScanExprContext(ExprContext *econtext)
Definition: execUtils.c:438
#define nodeTag(nodeptr)
Definition: nodes.h:541
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 ExecReScanMemoize(MemoizeState *node)
Definition: nodeMemoize.c:1007
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:344
void ExecIndexRestrPos(IndexScanState *node)
#define nodeTag(nodeptr)
Definition: nodes.h:541
#define elog(elevel,...)
Definition: elog.h:232

◆ ExecSupportsBackwardScan()

bool ExecSupportsBackwardScan ( Plan node)

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

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 }
#define CUSTOMPATH_SUPPORT_BACKWARD_SCAN
Definition: extensible.h:82
Definition: nodes.h:49
Definition: nodes.h:78
static bool IndexSupportsBackwardScan(Oid indexid)
Definition: execAmi.c:604
Definition: nodes.h:46
bool parallel_aware
Definition: plannodes.h:129
#define outerPlan(node)
Definition: plannodes.h:171
bool ExecSupportsBackwardScan(Plan *node)
Definition: execAmi.c:512
#define lfirst(lc)
Definition: pg_list.h:169
#define nodeTag(nodeptr)
Definition: nodes.h:541
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(), 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  /*
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 }
#define IsA(nodeptr, _type_)
Definition: nodes.h:587
bool ExecSupportsMarkRestore(Path *pathnode)
Definition: execAmi.c:419
#define castNode(_type_, nodeptr)
Definition: nodes.h:605
#define CUSTOMPATH_SUPPORT_MARK_RESTORE
Definition: extensible.h:83
Definition: nodes.h:49
Definition: nodes.h:78
NodeTag pathtype
Definition: pathnodes.h:1180
List * subpaths
Definition: pathnodes.h:1452
#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 604 of file execAmi.c.

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

Referenced by ExecSupportsBackwardScan().

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 }
#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