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

◆ ExecMaterializesOutput()

bool ExecMaterializesOutput ( NodeTag  plantype)

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

629 {
630  switch (plantype)
631  {
632  case T_Material:
633  case T_FunctionScan:
634  case T_TableFuncScan:
635  case T_CteScan:
637  case T_WorkTableScan:
638  case T_Sort:
639  return true;
640 
641  default:
642  break;
643  }
644 
645  return false;
646 }
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:938
List * initPlan
Definition: execnodes.h:953
void ExecReScanMaterial(MaterialState *node)
Definition: nodeMaterial.c:318
ExprContext * ps_ExprContext
Definition: execnodes.h:967
void ExecReScanLockRows(LockRowsState *node)
Definition: nodeLockRows.c:390
void ExecReScanFunctionScan(FunctionScanState *node)
List * subPlan
Definition: execnodes.h:955
void ExecReScanIndexOnlyScan(IndexOnlyScanState *node)
void ExecReScanLimit(LimitState *node)
Definition: nodeLimit.c:543
void ExecReScanWorkTableScan(WorkTableScanState *node)
struct PlanState * righttree
Definition: execnodes.h:951
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:950
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:846
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 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:960
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:928
void ExecReScanBitmapOr(BitmapOrState *node)
Definition: nodeBitmapOr.c:219
void ExecReScanRecursiveUnion(RecursiveUnionState *node)
void UpdateChangedParamSet(PlanState *node, Bitmapset *newchg)
Definition: execUtils.c:863
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:4425
Bitmapset * extParam
Definition: plannodes.h:154
void ReScanExprContext(ExprContext *econtext)
Definition: execUtils.c:437
#define nodeTag(nodeptr)
Definition: nodes.h:532
void ExecReScanValuesScan(ValuesScanState *node)
#define elog(elevel,...)
Definition: elog.h:228
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:532
#define elog(elevel,...)
Definition: elog.h:228

◆ ExecSupportsBackwardScan()

bool ExecSupportsBackwardScan ( Plan node)

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

505 {
506  if (node == NULL)
507  return false;
508 
509  /*
510  * Parallel-aware nodes return a subset of the tuples in each worker, and
511  * in general we can't expect to have enough bookkeeping state to know
512  * which ones we returned in this worker as opposed to some other worker.
513  */
514  if (node->parallel_aware)
515  return false;
516 
517  switch (nodeTag(node))
518  {
519  case T_Result:
520  if (outerPlan(node) != NULL)
521  return ExecSupportsBackwardScan(outerPlan(node));
522  else
523  return false;
524 
525  case T_Append:
526  {
527  ListCell *l;
528 
529  foreach(l, ((Append *) node)->appendplans)
530  {
531  if (!ExecSupportsBackwardScan((Plan *) lfirst(l)))
532  return false;
533  }
534  /* need not check tlist because Append doesn't evaluate it */
535  return true;
536  }
537 
538  case T_SampleScan:
539  /* Simplify life for tablesample methods by disallowing this */
540  return false;
541 
542  case T_Gather:
543  return false;
544 
545  case T_IndexScan:
546  return IndexSupportsBackwardScan(((IndexScan *) node)->indexid);
547 
548  case T_IndexOnlyScan:
549  return IndexSupportsBackwardScan(((IndexOnlyScan *) node)->indexid);
550 
551  case T_SubqueryScan:
552  return ExecSupportsBackwardScan(((SubqueryScan *) node)->subplan);
553 
554  case T_CustomScan:
555  {
556  uint32 flags = ((CustomScan *) node)->flags;
557 
559  return true;
560  }
561  return false;
562 
563  case T_SeqScan:
564  case T_TidScan:
565  case T_FunctionScan:
566  case T_ValuesScan:
567  case T_CteScan:
568  case T_Material:
569  case T_Sort:
570  /* these don't evaluate tlist */
571  return true;
572 
573  case T_IncrementalSort:
574 
575  /*
576  * Unlike full sort, incremental sort keeps only a single group of
577  * tuples in memory, so it can't scan backwards.
578  */
579  return false;
580 
581  case T_LockRows:
582  case T_Limit:
583  return ExecSupportsBackwardScan(outerPlan(node));
584 
585  default:
586  return false;
587  }
588 }
#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:595
Definition: nodes.h:46
bool parallel_aware
Definition: plannodes.h:129
unsigned int uint32
Definition: c.h:429
#define outerPlan(node)
Definition: plannodes.h:166
bool ExecSupportsBackwardScan(Plan *node)
Definition: execAmi.c:504
#define lfirst(lc)
Definition: pg_list.h:169
#define nodeTag(nodeptr)
Definition: nodes.h:532
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  /*
421  * Not all index types support mark/restore.
422  */
423  return castNode(IndexPath, pathnode)->indexinfo->amcanmarkpos;
424 
425  case T_Material:
426  case T_Sort:
427  return true;
428 
429  case T_CustomScan:
430  {
431  CustomPath *customPath = castNode(CustomPath, pathnode);
432 
433  if (customPath->flags & CUSTOMPATH_SUPPORT_MARK_RESTORE)
434  return true;
435  return false;
436  }
437  case T_Result:
438 
439  /*
440  * Result supports mark/restore iff it has a child plan that does.
441  *
442  * We have to be careful here because there is more than one Path
443  * type that can produce a Result plan node.
444  */
445  if (IsA(pathnode, ProjectionPath))
446  return ExecSupportsMarkRestore(((ProjectionPath *) pathnode)->subpath);
447  else if (IsA(pathnode, MinMaxAggPath))
448  return false; /* childless Result */
449  else if (IsA(pathnode, GroupResultPath))
450  return false; /* childless Result */
451  else
452  {
453  /* Simple RTE_RESULT base relation */
454  Assert(IsA(pathnode, Path));
455  return false; /* childless Result */
456  }
457 
458  case T_Append:
459  {
460  AppendPath *appendPath = castNode(AppendPath, pathnode);
461 
462  /*
463  * If there's exactly one child, then there will be no Append
464  * in the final plan, so we can handle mark/restore if the
465  * child plan node can.
466  */
467  if (list_length(appendPath->subpaths) == 1)
468  return ExecSupportsMarkRestore((Path *) linitial(appendPath->subpaths));
469  /* Otherwise, Append can't handle it */
470  return false;
471  }
472 
473  case T_MergeAppend:
474  {
475  MergeAppendPath *mapath = castNode(MergeAppendPath, pathnode);
476 
477  /*
478  * Like the Append case above, single-subpath MergeAppends
479  * won't be in the final plan, so just return the child's
480  * mark/restore ability.
481  */
482  if (list_length(mapath->subpaths) == 1)
483  return ExecSupportsMarkRestore((Path *) linitial(mapath->subpaths));
484  /* Otherwise, MergeAppend can't handle it */
485  return false;
486  }
487 
488  default:
489  break;
490  }
491 
492  return false;
493 }
#define IsA(nodeptr, _type_)
Definition: nodes.h:578
bool ExecSupportsMarkRestore(Path *pathnode)
Definition: execAmi.c:409
#define castNode(_type_, nodeptr)
Definition: nodes.h:596
#define CUSTOMPATH_SUPPORT_MARK_RESTORE
Definition: extensible.h:82
Definition: nodes.h:49
uint32 flags
Definition: pathnodes.h:1381
Definition: nodes.h:76
NodeTag pathtype
Definition: pathnodes.h:1146
List * subpaths
Definition: pathnodes.h:1409
#define linitial(l)
Definition: pg_list.h:174
Definition: nodes.h:46
#define Assert(condition)
Definition: c.h:800
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 595 of file execAmi.c.

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

Referenced by ExecSupportsBackwardScan().

596 {
597  bool result;
598  HeapTuple ht_idxrel;
599  Form_pg_class idxrelrec;
600  IndexAmRoutine *amroutine;
601 
602  /* Fetch the pg_class tuple of the index relation */
603  ht_idxrel = SearchSysCache1(RELOID, ObjectIdGetDatum(indexid));
604  if (!HeapTupleIsValid(ht_idxrel))
605  elog(ERROR, "cache lookup failed for relation %u", indexid);
606  idxrelrec = (Form_pg_class) GETSTRUCT(ht_idxrel);
607 
608  /* Fetch the index AM's API struct */
609  amroutine = GetIndexAmRoutineByAmId(idxrelrec->relam, false);
610 
611  result = amroutine->amcanbackward;
612 
613  pfree(amroutine);
614  ReleaseSysCache(ht_idxrel);
615 
616  return result;
617 }
#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:1115
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1163
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
FormData_pg_class * Form_pg_class
Definition: pg_class.h:153
#define elog(elevel,...)
Definition: elog.h:228