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

319 {
320  switch (nodeTag(node))
321  {
322  case T_IndexScanState:
324  break;
325 
328  break;
329 
330  case T_CustomScanState:
332  break;
333 
334  case T_MaterialState:
336  break;
337 
338  case T_SortState:
339  ExecSortMarkPos((SortState *) node);
340  break;
341 
342  case T_ResultState:
343  ExecResultMarkPos((ResultState *) node);
344  break;
345 
346  default:
347  /* don't make hard error unless caller asks to restore... */
348  elog(DEBUG2, "unrecognized node type: %d", (int) nodeTag(node));
349  break;
350  }
351 }
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:533
#define elog(elevel,...)
Definition: elog.h:214
void ExecMaterialMarkPos(MaterialState *node)
Definition: nodeMaterial.c:267

◆ ExecMaterializesOutput()

bool ExecMaterializesOutput ( NodeTag  plantype)

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

624 {
625  switch (plantype)
626  {
627  case T_Material:
628  case T_FunctionScan:
629  case T_TableFuncScan:
630  case T_CteScan:
632  case T_WorkTableScan:
633  case T_Sort:
634  return true;
635 
636  default:
637  break;
638  }
639 
640  return false;
641 }
Definition: nodes.h:76

◆ ExecReScan()

void ExecReScan ( PlanState node)

Definition at line 76 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(), ExecReScanSampleScan(), ExecReScanSeqScan(), ExecReScanSetOp(), ExecReScanSetParamPlan(), ExecReScanSort(), ExecReScanSubqueryScan(), ExecReScanTableFuncScan(), 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_ResultState, T_SampleScanState, T_SeqScanState, T_SetOpState, T_SortState, T_SubqueryScanState, T_TableFuncScanState, 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(), ExecReScanSetOp(), ExecReScanSort(), ExecReScanSubqueryScan(), ExecReScanUnique(), ExecReScanWindowAgg(), ExecScanSubPlan(), ExecutorRewind(), MultiExecBitmapIndexScan(), and MultiExecProcNode().

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 */
106  UpdateChangedParamSet(splan, node->chgParam);
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)
116  UpdateChangedParamSet(splan, node->chgParam);
117  }
118  /* Well. Now set chgParam for left/right trees. */
119  if (node->lefttree != NULL)
121  if (node->righttree != 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 
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 
186  break;
187 
190  break;
191 
194  break;
195 
196  case T_TidScanState:
198  break;
199 
200  case T_SubqueryScanState:
202  break;
203 
204  case T_FunctionScanState:
206  break;
207 
210  break;
211 
212  case T_ValuesScanState:
214  break;
215 
216  case T_CteScanState:
218  break;
219 
222  break;
223 
226  break;
227 
228  case T_ForeignScanState:
230  break;
231 
232  case T_CustomScanState:
234  break;
235 
236  case T_NestLoopState:
238  break;
239 
240  case T_MergeJoinState:
242  break;
243 
244  case T_HashJoinState:
246  break;
247 
248  case T_MaterialState:
250  break;
251 
252  case T_SortState:
253  ExecReScanSort((SortState *) node);
254  break;
255 
258  break;
259 
260  case T_GroupState:
261  ExecReScanGroup((GroupState *) node);
262  break;
263 
264  case T_AggState:
265  ExecReScanAgg((AggState *) node);
266  break;
267 
268  case T_WindowAggState:
270  break;
271 
272  case T_UniqueState:
273  ExecReScanUnique((UniqueState *) node);
274  break;
275 
276  case T_HashState:
277  ExecReScanHash((HashState *) node);
278  break;
279 
280  case T_SetOpState:
281  ExecReScanSetOp((SetOpState *) node);
282  break;
283 
284  case T_LockRowsState:
286  break;
287 
288  case T_LimitState:
289  ExecReScanLimit((LimitState *) node);
290  break;
291 
292  default:
293  elog(ERROR, "unrecognized node type: %d", (int) nodeTag(node));
294  break;
295  }
296 
297  if (node->chgParam != NULL)
298  {
299  bms_free(node->chgParam);
300  node->chgParam = NULL;
301  }
302 }
void ExecReScanBitmapHeapScan(BitmapHeapScanState *node)
void ExecReScanGroup(GroupState *node)
Definition: nodeGroup.c:241
void ExecReScanModifyTable(ModifyTableState *node)
Instrumentation * instrument
Definition: execnodes.h:942
List * initPlan
Definition: execnodes.h:957
void ExecReScanMaterial(MaterialState *node)
Definition: nodeMaterial.c:318
ExprContext * ps_ExprContext
Definition: execnodes.h:971
void ExecReScanLockRows(LockRowsState *node)
Definition: nodeLockRows.c:390
void ExecReScanFunctionScan(FunctionScanState *node)
List * subPlan
Definition: execnodes.h:959
void ExecReScanIndexOnlyScan(IndexOnlyScanState *node)
void ExecReScanLimit(LimitState *node)
Definition: nodeLimit.c:543
void ExecReScanWorkTableScan(WorkTableScanState *node)
struct PlanState * righttree
Definition: execnodes.h:955
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:954
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:43
struct PlanState * planstate
Definition: execnodes.h:850
void ExecReScanSetParamPlan(SubPlanState *node, PlanState *parent)
Definition: nodeSubplan.c:1268
void ExecReScanBitmapIndexScan(BitmapIndexScanState *node)
void ExecReScanUnique(UniqueState *node)
Definition: nodeUnique.c:181
void ExecReScanIndexScan(IndexScanState *node)
void ExecReScanGatherMerge(GatherMergeState *node)
void ExecReScanMergeAppend(MergeAppendState *node)
void ExecReScanNestLoop(NestLoopState *node)
Definition: nodeNestloop.c:392
static SPIPlanPtr splan
Definition: regress.c:259
Bitmapset * chgParam
Definition: execnodes.h:964
void ExecReScanGather(GatherState *node)
Definition: nodeGather.c:443
void ExecReScanNamedTuplestoreScan(NamedTuplestoreScanState *node)
void ExecReScanAppend(AppendState *node)
Definition: nodeAppend.c:314
void ExecReScanSubqueryScan(SubqueryScanState *node)
void ExecReScanIncrementalSort(IncrementalSortState *node)
Plan * plan
Definition: execnodes.h:932
void ExecReScanBitmapOr(BitmapOrState *node)
Definition: nodeBitmapOr.c:219
void ExecReScanRecursiveUnion(RecursiveUnionState *node)
void UpdateChangedParamSet(PlanState *node, Bitmapset *newchg)
Definition: execUtils.c:843
void bms_free(Bitmapset *a)
Definition: bitmapset.c:208
#define lfirst(lc)
Definition: pg_list.h:189
void ExecReScanBitmapAnd(BitmapAndState *node)
void ExecReScanAgg(AggState *node)
Definition: nodeAgg.c:4631
Bitmapset * extParam
Definition: plannodes.h:160
void ReScanExprContext(ExprContext *econtext)
Definition: execUtils.c:443
#define nodeTag(nodeptr)
Definition: nodes.h:533
void ExecReScanValuesScan(ValuesScanState *node)
#define elog(elevel,...)
Definition: elog.h:214
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 367 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().

368 {
369  switch (nodeTag(node))
370  {
371  case T_IndexScanState:
373  break;
374 
377  break;
378 
379  case T_CustomScanState:
381  break;
382 
383  case T_MaterialState:
385  break;
386 
387  case T_SortState:
388  ExecSortRestrPos((SortState *) node);
389  break;
390 
391  case T_ResultState:
393  break;
394 
395  default:
396  elog(ERROR, "unrecognized node type: %d", (int) nodeTag(node));
397  break;
398  }
399 }
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:43
void ExecSortRestrPos(SortState *node)
Definition: nodeSort.c:288
void ExecIndexRestrPos(IndexScanState *node)
#define nodeTag(nodeptr)
Definition: nodes.h:533
#define elog(elevel,...)
Definition: elog.h:214

◆ ExecSupportsBackwardScan()

bool ExecSupportsBackwardScan ( Plan node)

Definition at line 499 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_TidScan, and T_ValuesScan.

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

500 {
501  if (node == NULL)
502  return false;
503 
504  /*
505  * Parallel-aware nodes return a subset of the tuples in each worker, and
506  * in general we can't expect to have enough bookkeeping state to know
507  * which ones we returned in this worker as opposed to some other worker.
508  */
509  if (node->parallel_aware)
510  return false;
511 
512  switch (nodeTag(node))
513  {
514  case T_Result:
515  if (outerPlan(node) != NULL)
516  return ExecSupportsBackwardScan(outerPlan(node));
517  else
518  return false;
519 
520  case T_Append:
521  {
522  ListCell *l;
523 
524  foreach(l, ((Append *) node)->appendplans)
525  {
526  if (!ExecSupportsBackwardScan((Plan *) lfirst(l)))
527  return false;
528  }
529  /* need not check tlist because Append doesn't evaluate it */
530  return true;
531  }
532 
533  case T_SampleScan:
534  /* Simplify life for tablesample methods by disallowing this */
535  return false;
536 
537  case T_Gather:
538  return false;
539 
540  case T_IndexScan:
541  return IndexSupportsBackwardScan(((IndexScan *) node)->indexid);
542 
543  case T_IndexOnlyScan:
544  return IndexSupportsBackwardScan(((IndexOnlyScan *) node)->indexid);
545 
546  case T_SubqueryScan:
547  return ExecSupportsBackwardScan(((SubqueryScan *) node)->subplan);
548 
549  case T_CustomScan:
550  {
551  uint32 flags = ((CustomScan *) node)->flags;
552 
554  return true;
555  }
556  return false;
557 
558  case T_SeqScan:
559  case T_TidScan:
560  case T_FunctionScan:
561  case T_ValuesScan:
562  case T_CteScan:
563  case T_Material:
564  case T_Sort:
565  /* these don't evaluate tlist */
566  return true;
567 
568  case T_IncrementalSort:
569 
570  /*
571  * Unlike full sort, incremental sort keeps only a single group of
572  * tuples in memory, so it can't scan backwards.
573  */
574  return false;
575 
576  case T_LockRows:
577  case T_Limit:
578  return ExecSupportsBackwardScan(outerPlan(node));
579 
580  default:
581  return false;
582  }
583 }
#define CUSTOMPATH_SUPPORT_BACKWARD_SCAN
Definition: extensible.h:81
Definition: nodes.h:49
Definition: nodes.h:76
static bool IndexSupportsBackwardScan(Oid indexid)
Definition: execAmi.c:590
Definition: nodes.h:46
bool parallel_aware
Definition: plannodes.h:135
unsigned int uint32
Definition: c.h:374
#define outerPlan(node)
Definition: plannodes.h:172
bool ExecSupportsBackwardScan(Plan *node)
Definition: execAmi.c:499
#define lfirst(lc)
Definition: pg_list.h:189
#define nodeTag(nodeptr)
Definition: nodes.h:533
Definition: nodes.h:82
Definition: nodes.h:87

◆ ExecSupportsMarkRestore()

bool ExecSupportsMarkRestore ( Path pathnode)

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

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

◆ IndexSupportsBackwardScan()

static bool IndexSupportsBackwardScan ( Oid  indexid)
static

Definition at line 590 of file execAmi.c.

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

Referenced by ExecSupportsBackwardScan().

591 {
592  bool result;
593  HeapTuple ht_idxrel;
594  Form_pg_class idxrelrec;
595  IndexAmRoutine *amroutine;
596 
597  /* Fetch the pg_class tuple of the index relation */
598  ht_idxrel = SearchSysCache1(RELOID, ObjectIdGetDatum(indexid));
599  if (!HeapTupleIsValid(ht_idxrel))
600  elog(ERROR, "cache lookup failed for relation %u", indexid);
601  idxrelrec = (Form_pg_class) GETSTRUCT(ht_idxrel);
602 
603  /* Fetch the index AM's API struct */
604  amroutine = GetIndexAmRoutineByAmId(idxrelrec->relam, false);
605 
606  result = amroutine->amcanbackward;
607 
608  pfree(amroutine);
609  ReleaseSysCache(ht_idxrel);
610 
611  return result;
612 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
void pfree(void *pointer)
Definition: mcxt.c:1057
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
IndexAmRoutine * GetIndexAmRoutineByAmId(Oid amoid, bool noerror)
Definition: amapi.c:56
bool amcanbackward
Definition: amapi.h:223
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1116
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1164
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
FormData_pg_class * Form_pg_class
Definition: pg_class.h:153
#define elog(elevel,...)
Definition: elog.h:214