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

314 {
315  switch (nodeTag(node))
316  {
317  case T_IndexScanState:
319  break;
320 
323  break;
324 
325  case T_CustomScanState:
327  break;
328 
329  case T_MaterialState:
331  break;
332 
333  case T_SortState:
334  ExecSortMarkPos((SortState *) node);
335  break;
336 
337  case T_ResultState:
338  ExecResultMarkPos((ResultState *) node);
339  break;
340 
341  default:
342  /* don't make hard error unless caller asks to restore... */
343  elog(DEBUG2, "unrecognized node type: %d", (int) nodeTag(node));
344  break;
345  }
346 }
void ExecIndexOnlyMarkPos(IndexOnlyScanState *node)
#define DEBUG2
Definition: elog.h:24
void ExecSortMarkPos(SortState *node)
Definition: nodeSort.c:269
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:530
#define elog(elevel,...)
Definition: elog.h:228
void ExecMaterialMarkPos(MaterialState *node)
Definition: nodeMaterial.c:267

◆ ExecMaterializesOutput()

bool ExecMaterializesOutput ( NodeTag  plantype)

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

610 {
611  switch (plantype)
612  {
613  case T_Material:
614  case T_FunctionScan:
615  case T_TableFuncScan:
616  case T_CteScan:
618  case T_WorkTableScan:
619  case T_Sort:
620  return true;
621 
622  default:
623  break;
624  }
625 
626  return false;
627 }
Definition: nodes.h:76

◆ ExecReScan()

void ExecReScan ( PlanState node)

Definition at line 75 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(), 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_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(), ExecReScanLimit(), ExecReScanLockRows(), ExecReScanMaterial(), ExecReScanMergeAppend(), ExecReScanMergeJoin(), ExecReScanNestLoop(), ExecReScanProjectSet(), ExecReScanRecursiveUnion(), ExecReScanResult(), ExecReScanSetOp(), ExecReScanSort(), ExecReScanSubqueryScan(), ExecReScanUnique(), ExecReScanWindowAgg(), ExecScanSubPlan(), ExecutorRewind(), MultiExecBitmapIndexScan(), and MultiExecProcNode().

76 {
77  /* If collecting timing stats, update them */
78  if (node->instrument)
79  InstrEndLoop(node->instrument);
80 
81  /*
82  * If we have changed parameters, propagate that info.
83  *
84  * Note: ExecReScanSetParamPlan() can add bits to node->chgParam,
85  * corresponding to the output param(s) that the InitPlan will update.
86  * Since we make only one pass over the list, that means that an InitPlan
87  * can depend on the output param(s) of a sibling InitPlan only if that
88  * sibling appears earlier in the list. This is workable for now given
89  * the limited ways in which one InitPlan could depend on another, but
90  * eventually we might need to work harder (or else make the planner
91  * enlarge the extParam/allParam sets to include the params of depended-on
92  * InitPlans).
93  */
94  if (node->chgParam != NULL)
95  {
96  ListCell *l;
97 
98  foreach(l, node->initPlan)
99  {
100  SubPlanState *sstate = (SubPlanState *) lfirst(l);
101  PlanState *splan = sstate->planstate;
102 
103  if (splan->plan->extParam != NULL) /* don't care about child
104  * local Params */
105  UpdateChangedParamSet(splan, node->chgParam);
106  if (splan->chgParam != NULL)
107  ExecReScanSetParamPlan(sstate, node);
108  }
109  foreach(l, node->subPlan)
110  {
111  SubPlanState *sstate = (SubPlanState *) lfirst(l);
112  PlanState *splan = sstate->planstate;
113 
114  if (splan->plan->extParam != NULL)
115  UpdateChangedParamSet(splan, node->chgParam);
116  }
117  /* Well. Now set chgParam for left/right trees. */
118  if (node->lefttree != NULL)
120  if (node->righttree != NULL)
122  }
123 
124  /* Call expression callbacks */
125  if (node->ps_ExprContext)
127 
128  /* And do node-type-specific processing */
129  switch (nodeTag(node))
130  {
131  case T_ResultState:
132  ExecReScanResult((ResultState *) node);
133  break;
134 
135  case T_ProjectSetState:
137  break;
138 
139  case T_ModifyTableState:
141  break;
142 
143  case T_AppendState:
144  ExecReScanAppend((AppendState *) node);
145  break;
146 
147  case T_MergeAppendState:
149  break;
150 
153  break;
154 
155  case T_BitmapAndState:
157  break;
158 
159  case T_BitmapOrState:
161  break;
162 
163  case T_SeqScanState:
165  break;
166 
167  case T_SampleScanState:
169  break;
170 
171  case T_GatherState:
172  ExecReScanGather((GatherState *) node);
173  break;
174 
175  case T_GatherMergeState:
177  break;
178 
179  case T_IndexScanState:
181  break;
182 
185  break;
186 
189  break;
190 
193  break;
194 
195  case T_TidScanState:
197  break;
198 
199  case T_SubqueryScanState:
201  break;
202 
203  case T_FunctionScanState:
205  break;
206 
209  break;
210 
211  case T_ValuesScanState:
213  break;
214 
215  case T_CteScanState:
217  break;
218 
221  break;
222 
225  break;
226 
227  case T_ForeignScanState:
229  break;
230 
231  case T_CustomScanState:
233  break;
234 
235  case T_NestLoopState:
237  break;
238 
239  case T_MergeJoinState:
241  break;
242 
243  case T_HashJoinState:
245  break;
246 
247  case T_MaterialState:
249  break;
250 
251  case T_SortState:
252  ExecReScanSort((SortState *) node);
253  break;
254 
255  case T_GroupState:
256  ExecReScanGroup((GroupState *) node);
257  break;
258 
259  case T_AggState:
260  ExecReScanAgg((AggState *) node);
261  break;
262 
263  case T_WindowAggState:
265  break;
266 
267  case T_UniqueState:
268  ExecReScanUnique((UniqueState *) node);
269  break;
270 
271  case T_HashState:
272  ExecReScanHash((HashState *) node);
273  break;
274 
275  case T_SetOpState:
276  ExecReScanSetOp((SetOpState *) node);
277  break;
278 
279  case T_LockRowsState:
281  break;
282 
283  case T_LimitState:
284  ExecReScanLimit((LimitState *) node);
285  break;
286 
287  default:
288  elog(ERROR, "unrecognized node type: %d", (int) nodeTag(node));
289  break;
290  }
291 
292  if (node->chgParam != NULL)
293  {
294  bms_free(node->chgParam);
295  node->chgParam = NULL;
296  }
297 }
void ExecReScanBitmapHeapScan(BitmapHeapScanState *node)
void ExecReScanGroup(GroupState *node)
Definition: nodeGroup.c:241
void ExecReScanModifyTable(ModifyTableState *node)
Instrumentation * instrument
Definition: execnodes.h:949
List * initPlan
Definition: execnodes.h:964
void ExecReScanMaterial(MaterialState *node)
Definition: nodeMaterial.c:318
ExprContext * ps_ExprContext
Definition: execnodes.h:978
void ExecReScanLockRows(LockRowsState *node)
Definition: nodeLockRows.c:390
void ExecReScanFunctionScan(FunctionScanState *node)
List * subPlan
Definition: execnodes.h:966
void ExecReScanIndexOnlyScan(IndexOnlyScanState *node)
void ExecReScanLimit(LimitState *node)
Definition: nodeLimit.c:410
void ExecReScanWorkTableScan(WorkTableScanState *node)
struct PlanState * righttree
Definition: execnodes.h:962
void ExecReScanResult(ResultState *node)
Definition: nodeResult.c:260
void ExecReScanSetOp(SetOpState *node)
Definition: nodeSetOp.c:598
void ExecReScanSort(SortState *node)
Definition: nodeSort.c:302
void ExecReScanForeignScan(ForeignScanState *node)
struct PlanState * lefttree
Definition: execnodes.h:961
void InstrEndLoop(Instrumentation *instr)
Definition: instrument.c:110
void ExecReScanHash(HashState *node)
Definition: nodeHash.c:2189
void ExecReScanProjectSet(ProjectSetState *node)
#define ERROR
Definition: elog.h:43
struct PlanState * planstate
Definition: execnodes.h:847
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:258
Bitmapset * chgParam
Definition: execnodes.h:971
void ExecReScanGather(GatherState *node)
Definition: nodeGather.c:443
void ExecReScanNamedTuplestoreScan(NamedTuplestoreScanState *node)
void ExecReScanAppend(AppendState *node)
Definition: nodeAppend.c:334
void ExecReScanSubqueryScan(SubqueryScanState *node)
Plan * plan
Definition: execnodes.h:939
void ExecReScanBitmapOr(BitmapOrState *node)
Definition: nodeBitmapOr.c:219
void ExecReScanRecursiveUnion(RecursiveUnionState *node)
void UpdateChangedParamSet(PlanState *node, Bitmapset *newchg)
Definition: execUtils.c:802
void bms_free(Bitmapset *a)
Definition: bitmapset.c:208
#define lfirst(lc)
Definition: pg_list.h:190
void ExecReScanBitmapAnd(BitmapAndState *node)
void ExecReScanAgg(AggState *node)
Definition: nodeAgg.c:3433
Bitmapset * extParam
Definition: plannodes.h:158
void ReScanExprContext(ExprContext *econtext)
Definition: execUtils.c:402
#define nodeTag(nodeptr)
Definition: nodes.h:530
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:446
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 362 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().

363 {
364  switch (nodeTag(node))
365  {
366  case T_IndexScanState:
368  break;
369 
372  break;
373 
374  case T_CustomScanState:
376  break;
377 
378  case T_MaterialState:
380  break;
381 
382  case T_SortState:
383  ExecSortRestrPos((SortState *) node);
384  break;
385 
386  case T_ResultState:
388  break;
389 
390  default:
391  elog(ERROR, "unrecognized node type: %d", (int) nodeTag(node));
392  break;
393  }
394 }
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:287
void ExecIndexRestrPos(IndexScanState *node)
#define nodeTag(nodeptr)
Definition: nodes.h:530
#define elog(elevel,...)
Definition: elog.h:228

◆ ExecSupportsBackwardScan()

bool ExecSupportsBackwardScan ( Plan node)

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

495 {
496  if (node == NULL)
497  return false;
498 
499  /*
500  * Parallel-aware nodes return a subset of the tuples in each worker, and
501  * in general we can't expect to have enough bookkeeping state to know
502  * which ones we returned in this worker as opposed to some other worker.
503  */
504  if (node->parallel_aware)
505  return false;
506 
507  switch (nodeTag(node))
508  {
509  case T_Result:
510  if (outerPlan(node) != NULL)
511  return ExecSupportsBackwardScan(outerPlan(node));
512  else
513  return false;
514 
515  case T_Append:
516  {
517  ListCell *l;
518 
519  foreach(l, ((Append *) node)->appendplans)
520  {
521  if (!ExecSupportsBackwardScan((Plan *) lfirst(l)))
522  return false;
523  }
524  /* need not check tlist because Append doesn't evaluate it */
525  return true;
526  }
527 
528  case T_SampleScan:
529  /* Simplify life for tablesample methods by disallowing this */
530  return false;
531 
532  case T_Gather:
533  return false;
534 
535  case T_IndexScan:
536  return IndexSupportsBackwardScan(((IndexScan *) node)->indexid);
537 
538  case T_IndexOnlyScan:
539  return IndexSupportsBackwardScan(((IndexOnlyScan *) node)->indexid);
540 
541  case T_SubqueryScan:
542  return ExecSupportsBackwardScan(((SubqueryScan *) node)->subplan);
543 
544  case T_CustomScan:
545  {
546  uint32 flags = ((CustomScan *) node)->flags;
547 
549  return true;
550  }
551  return false;
552 
553  case T_SeqScan:
554  case T_TidScan:
555  case T_FunctionScan:
556  case T_ValuesScan:
557  case T_CteScan:
558  case T_Material:
559  case T_Sort:
560  return true;
561 
562  case T_LockRows:
563  case T_Limit:
564  return ExecSupportsBackwardScan(outerPlan(node));
565 
566  default:
567  return false;
568  }
569 }
#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:576
Definition: nodes.h:46
bool parallel_aware
Definition: plannodes.h:133
unsigned int uint32
Definition: c.h:359
#define outerPlan(node)
Definition: plannodes.h:170
bool ExecSupportsBackwardScan(Plan *node)
Definition: execAmi.c:494
#define lfirst(lc)
Definition: pg_list.h:190
#define nodeTag(nodeptr)
Definition: nodes.h:530
Definition: nodes.h:81
Definition: nodes.h:86

◆ ExecSupportsMarkRestore()

bool ExecSupportsMarkRestore ( Path pathnode)

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

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

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

Referenced by ExecSupportsBackwardScan().

577 {
578  bool result;
579  HeapTuple ht_idxrel;
580  Form_pg_class idxrelrec;
581  IndexAmRoutine *amroutine;
582 
583  /* Fetch the pg_class tuple of the index relation */
584  ht_idxrel = SearchSysCache1(RELOID, ObjectIdGetDatum(indexid));
585  if (!HeapTupleIsValid(ht_idxrel))
586  elog(ERROR, "cache lookup failed for relation %u", indexid);
587  idxrelrec = (Form_pg_class) GETSTRUCT(ht_idxrel);
588 
589  /* Fetch the index AM's API struct */
590  amroutine = GetIndexAmRoutineByAmId(idxrelrec->relam, false);
591 
592  result = amroutine->amcanbackward;
593 
594  pfree(amroutine);
595  ReleaseSysCache(ht_idxrel);
596 
597  return result;
598 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
void pfree(void *pointer)
Definition: mcxt.c:1056
#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:179
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:150
#define elog(elevel,...)
Definition: elog.h:228