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

316 {
317  switch (nodeTag(node))
318  {
319  case T_IndexScanState:
321  break;
322 
325  break;
326 
327  case T_CustomScanState:
329  break;
330 
331  case T_MaterialState:
333  break;
334 
335  case T_SortState:
336  ExecSortMarkPos((SortState *) node);
337  break;
338 
339  case T_ResultState:
340  ExecResultMarkPos((ResultState *) node);
341  break;
342 
343  default:
344  /* don't make hard error unless caller asks to restore... */
345  elog(DEBUG2, "unrecognized node type: %d", (int) nodeTag(node));
346  break;
347  }
348 }
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:141
void ExecResultMarkPos(ResultState *node)
Definition: nodeResult.c:147
#define nodeTag(nodeptr)
Definition: nodes.h:530
#define elog(elevel,...)
Definition: elog.h:226
void ExecMaterialMarkPos(MaterialState *node)
Definition: nodeMaterial.c:267

◆ ExecMaterializesOutput()

bool ExecMaterializesOutput ( NodeTag  plantype)

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

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

◆ ExecReScan()

void ExecReScan ( PlanState node)

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

78 {
79  /* If collecting timing stats, update them */
80  if (node->instrument)
81  InstrEndLoop(node->instrument);
82 
83  /*
84  * If we have changed parameters, propagate that info.
85  *
86  * Note: ExecReScanSetParamPlan() can add bits to node->chgParam,
87  * corresponding to the output param(s) that the InitPlan will update.
88  * Since we make only one pass over the list, that means that an InitPlan
89  * can depend on the output param(s) of a sibling InitPlan only if that
90  * sibling appears earlier in the list. This is workable for now given
91  * the limited ways in which one InitPlan could depend on another, but
92  * eventually we might need to work harder (or else make the planner
93  * enlarge the extParam/allParam sets to include the params of depended-on
94  * InitPlans).
95  */
96  if (node->chgParam != NULL)
97  {
98  ListCell *l;
99 
100  foreach(l, node->initPlan)
101  {
102  SubPlanState *sstate = (SubPlanState *) lfirst(l);
103  PlanState *splan = sstate->planstate;
104 
105  if (splan->plan->extParam != NULL) /* don't care about child
106  * local Params */
107  UpdateChangedParamSet(splan, node->chgParam);
108  if (splan->chgParam != NULL)
109  ExecReScanSetParamPlan(sstate, node);
110  }
111  foreach(l, node->subPlan)
112  {
113  SubPlanState *sstate = (SubPlanState *) lfirst(l);
114  PlanState *splan = sstate->planstate;
115 
116  if (splan->plan->extParam != NULL)
117  UpdateChangedParamSet(splan, node->chgParam);
118  }
119  /* Well. Now set chgParam for left/right trees. */
120  if (node->lefttree != NULL)
122  if (node->righttree != NULL)
124  }
125 
126  /* Call expression callbacks */
127  if (node->ps_ExprContext)
129 
130  /* And do node-type-specific processing */
131  switch (nodeTag(node))
132  {
133  case T_ResultState:
134  ExecReScanResult((ResultState *) node);
135  break;
136 
137  case T_ProjectSetState:
139  break;
140 
141  case T_ModifyTableState:
143  break;
144 
145  case T_AppendState:
146  ExecReScanAppend((AppendState *) node);
147  break;
148 
149  case T_MergeAppendState:
151  break;
152 
155  break;
156 
157  case T_BitmapAndState:
159  break;
160 
161  case T_BitmapOrState:
163  break;
164 
165  case T_SeqScanState:
167  break;
168 
169  case T_SampleScanState:
171  break;
172 
173  case T_GatherState:
174  ExecReScanGather((GatherState *) node);
175  break;
176 
177  case T_GatherMergeState:
179  break;
180 
181  case T_IndexScanState:
183  break;
184 
187  break;
188 
191  break;
192 
195  break;
196 
197  case T_TidScanState:
199  break;
200 
201  case T_SubqueryScanState:
203  break;
204 
205  case T_FunctionScanState:
207  break;
208 
211  break;
212 
213  case T_ValuesScanState:
215  break;
216 
217  case T_CteScanState:
219  break;
220 
223  break;
224 
227  break;
228 
229  case T_ForeignScanState:
231  break;
232 
233  case T_CustomScanState:
235  break;
236 
237  case T_NestLoopState:
239  break;
240 
241  case T_MergeJoinState:
243  break;
244 
245  case T_HashJoinState:
247  break;
248 
249  case T_MaterialState:
251  break;
252 
253  case T_SortState:
254  ExecReScanSort((SortState *) node);
255  break;
256 
257  case T_GroupState:
258  ExecReScanGroup((GroupState *) node);
259  break;
260 
261  case T_AggState:
262  ExecReScanAgg((AggState *) node);
263  break;
264 
265  case T_WindowAggState:
267  break;
268 
269  case T_UniqueState:
270  ExecReScanUnique((UniqueState *) node);
271  break;
272 
273  case T_HashState:
274  ExecReScanHash((HashState *) node);
275  break;
276 
277  case T_SetOpState:
278  ExecReScanSetOp((SetOpState *) node);
279  break;
280 
281  case T_LockRowsState:
283  break;
284 
285  case T_LimitState:
286  ExecReScanLimit((LimitState *) node);
287  break;
288 
289  default:
290  elog(ERROR, "unrecognized node type: %d", (int) nodeTag(node));
291  break;
292  }
293 
294  if (node->chgParam != NULL)
295  {
296  bms_free(node->chgParam);
297  node->chgParam = NULL;
298  }
299 }
void ExecReScanBitmapHeapScan(BitmapHeapScanState *node)
void ExecReScanGroup(GroupState *node)
Definition: nodeGroup.c:241
void ExecReScanModifyTable(ModifyTableState *node)
Instrumentation * instrument
Definition: execnodes.h:950
List * initPlan
Definition: execnodes.h:965
void ExecReScanMaterial(MaterialState *node)
Definition: nodeMaterial.c:318
ExprContext * ps_ExprContext
Definition: execnodes.h:979
void ExecReScanLockRows(LockRowsState *node)
Definition: nodeLockRows.c:390
void ExecReScanFunctionScan(FunctionScanState *node)
List * subPlan
Definition: execnodes.h:967
void ExecReScanIndexOnlyScan(IndexOnlyScanState *node)
void ExecReScanLimit(LimitState *node)
Definition: nodeLimit.c:412
void ExecReScanWorkTableScan(WorkTableScanState *node)
struct PlanState * righttree
Definition: execnodes.h:963
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:962
void InstrEndLoop(Instrumentation *instr)
Definition: instrument.c:110
void ExecReScanHash(HashState *node)
Definition: nodeHash.c:2190
void ExecReScanProjectSet(ProjectSetState *node)
#define ERROR
Definition: elog.h:43
struct PlanState * planstate
Definition: execnodes.h:848
void ExecReScanSetParamPlan(SubPlanState *node, PlanState *parent)
Definition: nodeSubplan.c:1269
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:972
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:940
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:3434
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:226
void ExecReScanSampleScan(SampleScanState *node)
void ExecReScanCteScan(CteScanState *node)
Definition: nodeCtescan.c:319
void ExecReScanWindowAgg(WindowAggState *node)
void ExecReScanTidScan(TidScanState *node)
Definition: nodeTidscan.c:453
void ExecReScanMergeJoin(MergeJoinState *node)
void ExecReScanCustomScan(CustomScanState *node)
Definition: nodeCustom.c:134
void ExecReScanTableFuncScan(TableFuncScanState *node)
void ExecReScanSeqScan(SeqScanState *node)
Definition: nodeSeqscan.c:224
void ExecReScanHashJoin(HashJoinState *node)

◆ ExecRestrPos()

void ExecRestrPos ( PlanState node)

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

365 {
366  switch (nodeTag(node))
367  {
368  case T_IndexScanState:
370  break;
371 
374  break;
375 
376  case T_CustomScanState:
378  break;
379 
380  case T_MaterialState:
382  break;
383 
384  case T_SortState:
385  ExecSortRestrPos((SortState *) node);
386  break;
387 
388  case T_ResultState:
390  break;
391 
392  default:
393  elog(ERROR, "unrecognized node type: %d", (int) nodeTag(node));
394  break;
395  }
396 }
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:152
#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:226

◆ ExecSupportsBackwardScan()

bool ExecSupportsBackwardScan ( Plan node)

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

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

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

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

Referenced by ExecSupportsBackwardScan().

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