PostgreSQL Source Code git master
nodeRecursiveunion.h File Reference
#include "nodes/execnodes.h"
Include dependency graph for nodeRecursiveunion.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

RecursiveUnionStateExecInitRecursiveUnion (RecursiveUnion *node, EState *estate, int eflags)
 
void ExecEndRecursiveUnion (RecursiveUnionState *node)
 
void ExecReScanRecursiveUnion (RecursiveUnionState *node)
 

Function Documentation

◆ ExecEndRecursiveUnion()

void ExecEndRecursiveUnion ( RecursiveUnionState node)

Definition at line 285 of file nodeRecursiveunion.c.

286{
287 /* Release tuplestores */
290
291 /* free subsidiary stuff including hashtable */
292 if (node->tempContext)
294 if (node->tableContext)
296
297 /*
298 * close down subplans
299 */
302}
void ExecEndNode(PlanState *node)
Definition: execProcnode.c:562
#define outerPlanState(node)
Definition: execnodes.h:1237
#define innerPlanState(node)
Definition: execnodes.h:1236
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:454
MemoryContext tempContext
Definition: execnodes.h:1540
MemoryContext tableContext
Definition: execnodes.h:1542
Tuplestorestate * working_table
Definition: execnodes.h:1535
Tuplestorestate * intermediate_table
Definition: execnodes.h:1536
void tuplestore_end(Tuplestorestate *state)
Definition: tuplestore.c:492

References ExecEndNode(), innerPlanState, RecursiveUnionState::intermediate_table, MemoryContextDelete(), outerPlanState, RecursiveUnionState::tableContext, RecursiveUnionState::tempContext, tuplestore_end(), and RecursiveUnionState::working_table.

Referenced by ExecEndNode().

◆ ExecInitRecursiveUnion()

RecursiveUnionState * ExecInitRecursiveUnion ( RecursiveUnion node,
EState estate,
int  eflags 
)

Definition at line 180 of file nodeRecursiveunion.c.

181{
182 RecursiveUnionState *rustate;
183 ParamExecData *prmdata;
184
185 /* check for unsupported flags */
187
188 /*
189 * create state structure
190 */
191 rustate = makeNode(RecursiveUnionState);
192 rustate->ps.plan = (Plan *) node;
193 rustate->ps.state = estate;
195
196 rustate->eqfuncoids = NULL;
197 rustate->hashfunctions = NULL;
198 rustate->hashtable = NULL;
199 rustate->tempContext = NULL;
200 rustate->tableContext = NULL;
201
202 /* initialize processing state */
203 rustate->recursing = false;
204 rustate->intermediate_empty = true;
205 rustate->working_table = tuplestore_begin_heap(false, false, work_mem);
206 rustate->intermediate_table = tuplestore_begin_heap(false, false, work_mem);
207
208 /*
209 * If hashing, we need a per-tuple memory context for comparisons, and a
210 * longer-lived context to store the hash table. The table can't just be
211 * kept in the per-query context because we want to be able to throw it
212 * away when rescanning.
213 */
214 if (node->numCols > 0)
215 {
216 rustate->tempContext =
218 "RecursiveUnion",
220 rustate->tableContext =
222 "RecursiveUnion hash table",
224 }
225
226 /*
227 * Make the state structure available to descendant WorkTableScan nodes
228 * via the Param slot reserved for it.
229 */
230 prmdata = &(estate->es_param_exec_vals[node->wtParam]);
231 Assert(prmdata->execPlan == NULL);
232 prmdata->value = PointerGetDatum(rustate);
233 prmdata->isnull = false;
234
235 /*
236 * Miscellaneous initialization
237 *
238 * RecursiveUnion plans don't have expression contexts because they never
239 * call ExecQual or ExecProject.
240 */
241 Assert(node->plan.qual == NIL);
242
243 /*
244 * RecursiveUnion nodes still have Result slots, which hold pointers to
245 * tuples, so we have to initialize them.
246 */
247 ExecInitResultTypeTL(&rustate->ps);
248
249 /*
250 * Initialize result tuple type. (Note: we have to set up the result type
251 * before initializing child nodes, because nodeWorktablescan.c expects it
252 * to be valid.)
253 */
254 rustate->ps.ps_ProjInfo = NULL;
255
256 /*
257 * initialize child nodes
258 */
259 outerPlanState(rustate) = ExecInitNode(outerPlan(node), estate, eflags);
260 innerPlanState(rustate) = ExecInitNode(innerPlan(node), estate, eflags);
261
262 /*
263 * If hashing, precompute fmgr lookup data for inner loop, and create the
264 * hash table.
265 */
266 if (node->numCols > 0)
267 {
269 node->dupOperators,
270 &rustate->eqfuncoids,
271 &rustate->hashfunctions);
272 build_hash_table(rustate);
273 }
274
275 return rustate;
276}
#define Assert(condition)
Definition: c.h:815
void execTuplesHashPrepare(int numCols, const Oid *eqOperators, Oid **eqFuncOids, FmgrInfo **hashFunctions)
Definition: execGrouping.c:97
PlanState * ExecInitNode(Plan *node, EState *estate, int eflags)
Definition: execProcnode.c:142
void ExecInitResultTypeTL(PlanState *planstate)
Definition: execTuples.c:1942
#define EXEC_FLAG_BACKWARD
Definition: executor.h:68
#define EXEC_FLAG_MARK
Definition: executor.h:69
int work_mem
Definition: globals.c:130
MemoryContext CurrentMemoryContext
Definition: mcxt.c:143
#define AllocSetContextCreate
Definition: memutils.h:129
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:160
static void build_hash_table(RecursiveUnionState *rustate)
static TupleTableSlot * ExecRecursiveUnion(PlanState *pstate)
#define makeNode(_type_)
Definition: nodes.h:155
#define NIL
Definition: pg_list.h:68
#define innerPlan(node)
Definition: plannodes.h:182
#define outerPlan(node)
Definition: plannodes.h:183
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:327
ParamExecData * es_param_exec_vals
Definition: execnodes.h:686
bool isnull
Definition: params.h:150
Datum value
Definition: params.h:149
void * execPlan
Definition: params.h:148
Plan * plan
Definition: execnodes.h:1141
EState * state
Definition: execnodes.h:1143
ProjectionInfo * ps_ProjInfo
Definition: execnodes.h:1181
ExecProcNodeMtd ExecProcNode
Definition: execnodes.h:1147
List * qual
Definition: plannodes.h:154
FmgrInfo * hashfunctions
Definition: execnodes.h:1539
TupleHashTable hashtable
Definition: execnodes.h:1541
Tuplestorestate * tuplestore_begin_heap(bool randomAccess, bool interXact, int maxKBytes)
Definition: tuplestore.c:330

References ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate, Assert, build_hash_table(), CurrentMemoryContext, RecursiveUnionState::eqfuncoids, EState::es_param_exec_vals, EXEC_FLAG_BACKWARD, EXEC_FLAG_MARK, ExecInitNode(), ExecInitResultTypeTL(), ParamExecData::execPlan, PlanState::ExecProcNode, ExecRecursiveUnion(), execTuplesHashPrepare(), RecursiveUnionState::hashfunctions, RecursiveUnionState::hashtable, innerPlan, innerPlanState, RecursiveUnionState::intermediate_empty, RecursiveUnionState::intermediate_table, ParamExecData::isnull, makeNode, NIL, RecursiveUnion::numCols, outerPlan, outerPlanState, PlanState::plan, RecursiveUnion::plan, PointerGetDatum(), RecursiveUnionState::ps, PlanState::ps_ProjInfo, Plan::qual, RecursiveUnionState::recursing, PlanState::state, RecursiveUnionState::tableContext, RecursiveUnionState::tempContext, tuplestore_begin_heap(), ParamExecData::value, work_mem, RecursiveUnionState::working_table, and RecursiveUnion::wtParam.

Referenced by ExecInitNode().

◆ ExecReScanRecursiveUnion()

void ExecReScanRecursiveUnion ( RecursiveUnionState node)

Definition at line 311 of file nodeRecursiveunion.c.

312{
316
317 /*
318 * Set recursive term's chgParam to tell it that we'll modify the working
319 * table and therefore it has to rescan.
320 */
321 innerPlan->chgParam = bms_add_member(innerPlan->chgParam, plan->wtParam);
322
323 /*
324 * if chgParam of subnode is not null then plan will be re-scanned by
325 * first ExecProcNode. Because of above, we only have to do this to the
326 * non-recursive term.
327 */
328 if (outerPlan->chgParam == NULL)
330
331 /* Release any hashtable storage */
332 if (node->tableContext)
334
335 /* Empty hashtable if needed */
336 if (plan->numCols > 0)
338
339 /* reset processing state */
340 node->recursing = false;
341 node->intermediate_empty = true;
344}
Bitmapset * bms_add_member(Bitmapset *a, int x)
Definition: bitmapset.c:815
void ExecReScan(PlanState *node)
Definition: execAmi.c:76
void ResetTupleHashTable(TupleHashTable hashtable)
Definition: execGrouping.c:271
void MemoryContextReset(MemoryContext context)
Definition: mcxt.c:383
#define plan(x)
Definition: pg_regress.c:161
void tuplestore_clear(Tuplestorestate *state)
Definition: tuplestore.c:430

References bms_add_member(), ExecReScan(), RecursiveUnionState::hashtable, innerPlan, innerPlanState, RecursiveUnionState::intermediate_empty, RecursiveUnionState::intermediate_table, MemoryContextReset(), outerPlan, outerPlanState, PlanState::plan, plan, RecursiveUnionState::ps, RecursiveUnionState::recursing, ResetTupleHashTable(), RecursiveUnionState::tableContext, tuplestore_clear(), and RecursiveUnionState::working_table.

Referenced by ExecReScan().