1 /*-------------------------------------------------------------------------
4 * miscellaneous executor access method routines
6 * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
11 *-------------------------------------------------------------------------
15 #include "executor/execdebug.h"
16 #include "executor/instrument.h"
17 #include "executor/nodeAgg.h"
18 #include "executor/nodeAppend.h"
19 #include "executor/nodeBitmapAnd.h"
20 #include "executor/nodeBitmapHeapscan.h"
21 #include "executor/nodeBitmapIndexscan.h"
22 #include "executor/nodeBitmapOr.h"
23 #include "executor/nodeFunctionscan.h"
24 #include "executor/nodeGroup.h"
25 #include "executor/nodeGroup.h"
26 #include "executor/nodeHash.h"
27 #include "executor/nodeHashjoin.h"
28 #include "executor/nodeIndexscan.h"
29 #include "executor/nodeLimit.h"
30 #include "executor/nodeMaterial.h"
31 #include "executor/nodeMergejoin.h"
32 #include "executor/nodeNestloop.h"
33 #include "executor/nodeResult.h"
34 #include "executor/nodeSeqscan.h"
35 #include "executor/nodeSetOp.h"
36 #include "executor/nodeSort.h"
37 #include "executor/nodeSubplan.h"
38 #include "executor/nodeSubqueryscan.h"
39 #include "executor/nodeTidscan.h"
40 #include "executor/nodeUnique.h"
41 #include "executor/nodeValuesscan.h"
46 * Reset a plan node so that its output can be re-scanned.
48 * Note that if the plan node has parameters that have changed value,
49 * the output might be different from last time.
51 * The second parameter is currently only used to pass a NestLoop plan's
52 * econtext down to its inner child plan, in case that is an indexscan that
53 * needs access to variables of the current outer tuple. (The handling of
54 * this parameter is currently pretty inconsistent: some callers pass NULL
55 * and some pass down their parent's value; so don't rely on it in other
56 * situations. It'd probably be better to remove the whole thing and use
57 * the generalized parameter mechanism instead.)
60 ExecReScan(PlanState
*node
, ExprContext
*exprCtxt
)
62 /* If collecting timing stats, update them */
64 InstrEndLoop(node
->instrument
);
67 * If we have changed parameters, propagate that info.
69 * Note: ExecReScanSetParamPlan() can add bits to node->chgParam,
70 * corresponding to the output param(s) that the InitPlan will update.
71 * Since we make only one pass over the list, that means that an InitPlan
72 * can depend on the output param(s) of a sibling InitPlan only if that
73 * sibling appears earlier in the list. This is workable for now given
74 * the limited ways in which one InitPlan could depend on another, but
75 * eventually we might need to work harder (or else make the planner
76 * enlarge the extParam/allParam sets to include the params of depended-on
79 if (node
->chgParam
!= NULL
)
83 foreach(l
, node
->initPlan
)
85 SubPlanState
*sstate
= (SubPlanState
*) lfirst(l
);
86 PlanState
*splan
= sstate
->planstate
;
88 if (splan
->plan
->extParam
!= NULL
) /* don't care about child
90 UpdateChangedParamSet(splan
, node
->chgParam
);
91 if (splan
->chgParam
!= NULL
)
92 ExecReScanSetParamPlan(sstate
, node
);
94 foreach(l
, node
->subPlan
)
96 SubPlanState
*sstate
= (SubPlanState
*) lfirst(l
);
97 PlanState
*splan
= sstate
->planstate
;
99 if (splan
->plan
->extParam
!= NULL
)
100 UpdateChangedParamSet(splan
, node
->chgParam
);
102 /* Well. Now set chgParam for left/right trees. */
103 if (node
->lefttree
!= NULL
)
104 UpdateChangedParamSet(node
->lefttree
, node
->chgParam
);
105 if (node
->righttree
!= NULL
)
106 UpdateChangedParamSet(node
->righttree
, node
->chgParam
);
109 /* Shut down any SRFs in the plan node's targetlist */
110 if (node
->ps_ExprContext
)
111 ReScanExprContext(node
->ps_ExprContext
);
113 /* And do node-type-specific processing */
114 switch (nodeTag(node
))
117 ExecReScanResult((ResultState
*) node
, exprCtxt
);
121 ExecReScanAppend((AppendState
*) node
, exprCtxt
);
124 case T_BitmapAndState
:
125 ExecReScanBitmapAnd((BitmapAndState
*) node
, exprCtxt
);
128 case T_BitmapOrState
:
129 ExecReScanBitmapOr((BitmapOrState
*) node
, exprCtxt
);
133 ExecSeqReScan((SeqScanState
*) node
, exprCtxt
);
136 case T_IndexScanState
:
137 ExecIndexReScan((IndexScanState
*) node
, exprCtxt
);
140 case T_BitmapIndexScanState
:
141 ExecBitmapIndexReScan((BitmapIndexScanState
*) node
, exprCtxt
);
144 case T_BitmapHeapScanState
:
145 ExecBitmapHeapReScan((BitmapHeapScanState
*) node
, exprCtxt
);
149 ExecTidReScan((TidScanState
*) node
, exprCtxt
);
152 case T_SubqueryScanState
:
153 ExecSubqueryReScan((SubqueryScanState
*) node
, exprCtxt
);
156 case T_FunctionScanState
:
157 ExecFunctionReScan((FunctionScanState
*) node
, exprCtxt
);
160 case T_ValuesScanState
:
161 ExecValuesReScan((ValuesScanState
*) node
, exprCtxt
);
164 case T_NestLoopState
:
165 ExecReScanNestLoop((NestLoopState
*) node
, exprCtxt
);
168 case T_MergeJoinState
:
169 ExecReScanMergeJoin((MergeJoinState
*) node
, exprCtxt
);
172 case T_HashJoinState
:
173 ExecReScanHashJoin((HashJoinState
*) node
, exprCtxt
);
176 case T_MaterialState
:
177 ExecMaterialReScan((MaterialState
*) node
, exprCtxt
);
181 ExecReScanSort((SortState
*) node
, exprCtxt
);
185 ExecReScanGroup((GroupState
*) node
, exprCtxt
);
189 ExecReScanAgg((AggState
*) node
, exprCtxt
);
193 ExecReScanUnique((UniqueState
*) node
, exprCtxt
);
197 ExecReScanHash((HashState
*) node
, exprCtxt
);
201 ExecReScanSetOp((SetOpState
*) node
, exprCtxt
);
205 ExecReScanLimit((LimitState
*) node
, exprCtxt
);
209 elog(ERROR
, "unrecognized node type: %d", (int) nodeTag(node
));
213 if (node
->chgParam
!= NULL
)
215 bms_free(node
->chgParam
);
216 node
->chgParam
= NULL
;
223 * Marks the current scan position.
226 ExecMarkPos(PlanState
*node
)
228 switch (nodeTag(node
))
231 ExecSeqMarkPos((SeqScanState
*) node
);
234 case T_IndexScanState
:
235 ExecIndexMarkPos((IndexScanState
*) node
);
239 ExecTidMarkPos((TidScanState
*) node
);
242 case T_FunctionScanState
:
243 ExecFunctionMarkPos((FunctionScanState
*) node
);
246 case T_ValuesScanState
:
247 ExecValuesMarkPos((ValuesScanState
*) node
);
250 case T_MaterialState
:
251 ExecMaterialMarkPos((MaterialState
*) node
);
255 ExecSortMarkPos((SortState
*) node
);
259 ExecResultMarkPos((ResultState
*) node
);
263 /* don't make hard error unless caller asks to restore... */
264 elog(DEBUG2
, "unrecognized node type: %d", (int) nodeTag(node
));
272 * restores the scan position previously saved with ExecMarkPos()
274 * NOTE: the semantics of this are that the first ExecProcNode following
275 * the restore operation will yield the same tuple as the first one following
276 * the mark operation. It is unspecified what happens to the plan node's
277 * result TupleTableSlot. (In most cases the result slot is unchanged by
278 * a restore, but the node may choose to clear it or to load it with the
279 * restored-to tuple.) Hence the caller should discard any previously
280 * returned TupleTableSlot after doing a restore.
283 ExecRestrPos(PlanState
*node
)
285 switch (nodeTag(node
))
288 ExecSeqRestrPos((SeqScanState
*) node
);
291 case T_IndexScanState
:
292 ExecIndexRestrPos((IndexScanState
*) node
);
296 ExecTidRestrPos((TidScanState
*) node
);
299 case T_FunctionScanState
:
300 ExecFunctionRestrPos((FunctionScanState
*) node
);
303 case T_ValuesScanState
:
304 ExecValuesRestrPos((ValuesScanState
*) node
);
307 case T_MaterialState
:
308 ExecMaterialRestrPos((MaterialState
*) node
);
312 ExecSortRestrPos((SortState
*) node
);
316 ExecResultRestrPos((ResultState
*) node
);
320 elog(ERROR
, "unrecognized node type: %d", (int) nodeTag(node
));
326 * ExecSupportsMarkRestore - does a plan type support mark/restore?
328 * XXX Ideally, all plan node types would support mark/restore, and this
329 * wouldn't be needed. For now, this had better match the routines above.
330 * But note the test is on Plan nodetype, not PlanState nodetype.
332 * (However, since the only present use of mark/restore is in mergejoin,
333 * there is no need to support mark/restore in any plan type that is not
334 * capable of generating ordered output. So the seqscan, tidscan,
335 * functionscan, and valuesscan support is actually useless code at present.)
338 ExecSupportsMarkRestore(NodeTag plantype
)
354 * T_Result only supports mark/restore if it has a child plan that
355 * does, so we do not have enough information to give a really
356 * correct answer. However, for current uses it's enough to
357 * always say "false", because this routine is not asked about
358 * gating Result plans, only base-case Results.
370 * ExecSupportsBackwardScan - does a plan type support backwards scanning?
372 * Ideally, all plan types would support backwards scan, but that seems
373 * unlikely to happen soon. In some cases, a plan node passes the backwards
374 * scan down to its children, and so supports backwards scan only if its
375 * children do. Therefore, this routine must be passed a complete plan tree.
378 ExecSupportsBackwardScan(Plan
*node
)
383 switch (nodeTag(node
))
386 if (outerPlan(node
) != NULL
)
387 return ExecSupportsBackwardScan(outerPlan(node
));
395 foreach(l
, ((Append
*) node
)->appendplans
)
397 if (!ExecSupportsBackwardScan((Plan
*) lfirst(l
)))
411 return ExecSupportsBackwardScan(((SubqueryScan
*) node
)->subplan
);
418 return ExecSupportsBackwardScan(outerPlan(node
));