#include "nodes/execnodes.h"
Go to the source code of this file.
Functions | |
SetOpState * | ExecInitSetOp (SetOp *node, EState *estate, int eflags) |
TupleTableSlot * | ExecSetOp (SetOpState *node) |
void | ExecEndSetOp (SetOpState *node) |
void | ExecReScanSetOp (SetOpState *node) |
void ExecEndSetOp | ( | SetOpState * | node | ) |
Definition at line 586 of file nodeSetOp.c.
References ExecClearTuple(), ExecEndNode(), MemoryContextDelete(), outerPlanState, SetOpState::ps, PlanState::ps_ResultTupleSlot, SetOpState::tableContext, and SetOpState::tempContext.
Referenced by ExecEndNode().
{ /* clean up tuple table */ ExecClearTuple(node->ps.ps_ResultTupleSlot); /* free subsidiary stuff including hashtable */ MemoryContextDelete(node->tempContext); if (node->tableContext) MemoryContextDelete(node->tableContext); ExecEndNode(outerPlanState(node)); }
SetOpState* ExecInitSetOp | ( | SetOp * | node, | |
EState * | estate, | |||
int | eflags | |||
) |
Definition at line 477 of file nodeSetOp.c.
References ALLOCSET_DEFAULT_INITSIZE, ALLOCSET_DEFAULT_MAXSIZE, ALLOCSET_DEFAULT_MINSIZE, AllocSetContextCreate(), Assert, build_hash_table(), CurrentMemoryContext, SetOp::dupOperators, SetOpState::eqfunctions, EXEC_FLAG_BACKWARD, EXEC_FLAG_MARK, ExecAssignResultTypeFromTL(), ExecInitNode(), ExecInitResultTupleSlot(), execTuplesHashPrepare(), execTuplesMatchPrepare(), SetOpState::grp_firstTuple, SetOpState::hashfunctions, SetOpState::hashtable, makeNode, SetOp::numCols, SetOpState::numOutput, outerPlan, outerPlanState, palloc0(), SetOpState::pergroup, PlanState::plan, SetOpState::ps, PlanState::ps_ProjInfo, SetOpState::setop_done, SETOP_HASHED, PlanState::state, SetOp::strategy, SetOpState::table_filled, SetOpState::tableContext, and SetOpState::tempContext.
Referenced by ExecInitNode().
{ SetOpState *setopstate; /* check for unsupported flags */ Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK))); /* * create state structure */ setopstate = makeNode(SetOpState); setopstate->ps.plan = (Plan *) node; setopstate->ps.state = estate; setopstate->eqfunctions = NULL; setopstate->hashfunctions = NULL; setopstate->setop_done = false; setopstate->numOutput = 0; setopstate->pergroup = NULL; setopstate->grp_firstTuple = NULL; setopstate->hashtable = NULL; setopstate->tableContext = NULL; /* * Miscellaneous initialization * * SetOp nodes have no ExprContext initialization because they never call * ExecQual or ExecProject. But they do need a per-tuple memory context * anyway for calling execTuplesMatch. */ setopstate->tempContext = AllocSetContextCreate(CurrentMemoryContext, "SetOp", ALLOCSET_DEFAULT_MINSIZE, ALLOCSET_DEFAULT_INITSIZE, ALLOCSET_DEFAULT_MAXSIZE); /* * If hashing, we also need a longer-lived context to store the hash * table. The table can't just be kept in the per-query context because * we want to be able to throw it away in ExecReScanSetOp. */ if (node->strategy == SETOP_HASHED) setopstate->tableContext = AllocSetContextCreate(CurrentMemoryContext, "SetOp hash table", ALLOCSET_DEFAULT_MINSIZE, ALLOCSET_DEFAULT_INITSIZE, ALLOCSET_DEFAULT_MAXSIZE); /* * Tuple table initialization */ ExecInitResultTupleSlot(estate, &setopstate->ps); /* * initialize child nodes * * If we are hashing then the child plan does not need to handle REWIND * efficiently; see ExecReScanSetOp. */ if (node->strategy == SETOP_HASHED) eflags &= ~EXEC_FLAG_REWIND; outerPlanState(setopstate) = ExecInitNode(outerPlan(node), estate, eflags); /* * setop nodes do no projections, so initialize projection info for this * node appropriately */ ExecAssignResultTypeFromTL(&setopstate->ps); setopstate->ps.ps_ProjInfo = NULL; /* * Precompute fmgr lookup data for inner loop. We need both equality and * hashing functions to do it by hashing, but only equality if not * hashing. */ if (node->strategy == SETOP_HASHED) execTuplesHashPrepare(node->numCols, node->dupOperators, &setopstate->eqfunctions, &setopstate->hashfunctions); else setopstate->eqfunctions = execTuplesMatchPrepare(node->numCols, node->dupOperators); if (node->strategy == SETOP_HASHED) { build_hash_table(setopstate); setopstate->table_filled = false; } else { setopstate->pergroup = (SetOpStatePerGroup) palloc0(sizeof(SetOpStatePerGroupData)); } return setopstate; }
void ExecReScanSetOp | ( | SetOpState * | node | ) |
Definition at line 601 of file nodeSetOp.c.
References build_hash_table(), PlanState::chgParam, ExecClearTuple(), ExecReScan(), SetOpState::grp_firstTuple, SetOpState::hashiter, SetOpState::hashtable, heap_freetuple(), PlanState::lefttree, MemoryContextResetAndDeleteChildren(), NULL, SetOpState::numOutput, PlanState::plan, SetOpState::ps, PlanState::ps_ResultTupleSlot, ResetTupleHashIterator, SetOpState::setop_done, SETOP_HASHED, SetOpState::table_filled, and SetOpState::tableContext.
Referenced by ExecReScan().
{ ExecClearTuple(node->ps.ps_ResultTupleSlot); node->setop_done = false; node->numOutput = 0; if (((SetOp *) node->ps.plan)->strategy == SETOP_HASHED) { /* * In the hashed case, if we haven't yet built the hash table then we * can just return; nothing done yet, so nothing to undo. If subnode's * chgParam is not NULL then it will be re-scanned by ExecProcNode, * else no reason to re-scan it at all. */ if (!node->table_filled) return; /* * If we do have the hash table and the subplan does not have any * parameter changes, then we can just rescan the existing hash table; * no need to build it again. */ if (node->ps.lefttree->chgParam == NULL) { ResetTupleHashIterator(node->hashtable, &node->hashiter); return; } } /* Release first tuple of group, if we have made a copy */ if (node->grp_firstTuple != NULL) { heap_freetuple(node->grp_firstTuple); node->grp_firstTuple = NULL; } /* Release any hashtable storage */ if (node->tableContext) MemoryContextResetAndDeleteChildren(node->tableContext); /* And rebuild empty hashtable if needed */ if (((SetOp *) node->ps.plan)->strategy == SETOP_HASHED) { build_hash_table(node); node->table_filled = false; } /* * if chgParam of subnode is not null then plan will be re-scanned by * first ExecProcNode. */ if (node->ps.lefttree->chgParam == NULL) ExecReScan(node->ps.lefttree); }
TupleTableSlot* ExecSetOp | ( | SetOpState * | node | ) |
Definition at line 195 of file nodeSetOp.c.
References SetOpState::numOutput, PlanState::plan, SetOpState::ps, PlanState::ps_ResultTupleSlot, SetOpState::setop_done, setop_fill_hash_table(), SETOP_HASHED, setop_retrieve_direct(), setop_retrieve_hash_table(), SetOp::strategy, and SetOpState::table_filled.
Referenced by ExecProcNode().
{ SetOp *plannode = (SetOp *) node->ps.plan; TupleTableSlot *resultTupleSlot = node->ps.ps_ResultTupleSlot; /* * If the previously-returned tuple needs to be returned more than once, * keep returning it. */ if (node->numOutput > 0) { node->numOutput--; return resultTupleSlot; } /* Otherwise, we're done if we are out of groups */ if (node->setop_done) return NULL; /* Fetch the next tuple group according to the correct strategy */ if (plannode->strategy == SETOP_HASHED) { if (!node->table_filled) setop_fill_hash_table(node); return setop_retrieve_hash_table(node); } else return setop_retrieve_direct(node); }