#include "postgres.h"
#include "executor/executor.h"
#include "executor/nodeUnique.h"
#include "utils/memutils.h"
Go to the source code of this file.
Functions | |
TupleTableSlot * | ExecUnique (UniqueState *node) |
UniqueState * | ExecInitUnique (Unique *node, EState *estate, int eflags) |
void | ExecEndUnique (UniqueState *node) |
void | ExecReScanUnique (UniqueState *node) |
void ExecEndUnique | ( | UniqueState * | node | ) |
Definition at line 175 of file nodeUnique.c.
References ExecClearTuple(), ExecEndNode(), MemoryContextDelete(), outerPlanState, UniqueState::ps, PlanState::ps_ResultTupleSlot, and UniqueState::tempContext.
Referenced by ExecEndNode().
{ /* clean up tuple table */ ExecClearTuple(node->ps.ps_ResultTupleSlot); MemoryContextDelete(node->tempContext); ExecEndNode(outerPlanState(node)); }
UniqueState* ExecInitUnique | ( | Unique * | node, | |
EState * | estate, | |||
int | eflags | |||
) |
Definition at line 112 of file nodeUnique.c.
References ALLOCSET_DEFAULT_INITSIZE, ALLOCSET_DEFAULT_MAXSIZE, ALLOCSET_DEFAULT_MINSIZE, AllocSetContextCreate(), Assert, CurrentMemoryContext, UniqueState::eqfunctions, EXEC_FLAG_BACKWARD, EXEC_FLAG_MARK, ExecAssignResultTypeFromTL(), ExecInitNode(), ExecInitResultTupleSlot(), execTuplesMatchPrepare(), makeNode, Unique::numCols, outerPlan, outerPlanState, PlanState::plan, UniqueState::ps, PlanState::ps_ProjInfo, PlanState::state, UniqueState::tempContext, and Unique::uniqOperators.
Referenced by ExecInitNode().
{ UniqueState *uniquestate; /* check for unsupported flags */ Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK))); /* * create state structure */ uniquestate = makeNode(UniqueState); uniquestate->ps.plan = (Plan *) node; uniquestate->ps.state = estate; /* * Miscellaneous initialization * * Unique 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. */ uniquestate->tempContext = AllocSetContextCreate(CurrentMemoryContext, "Unique", ALLOCSET_DEFAULT_MINSIZE, ALLOCSET_DEFAULT_INITSIZE, ALLOCSET_DEFAULT_MAXSIZE); /* * Tuple table initialization */ ExecInitResultTupleSlot(estate, &uniquestate->ps); /* * then initialize outer plan */ outerPlanState(uniquestate) = ExecInitNode(outerPlan(node), estate, eflags); /* * unique nodes do no projections, so initialize projection info for this * node appropriately */ ExecAssignResultTypeFromTL(&uniquestate->ps); uniquestate->ps.ps_ProjInfo = NULL; /* * Precompute fmgr lookup data for inner loop */ uniquestate->eqfunctions = execTuplesMatchPrepare(node->numCols, node->uniqOperators); return uniquestate; }
void ExecReScanUnique | ( | UniqueState * | node | ) |
Definition at line 187 of file nodeUnique.c.
References PlanState::chgParam, ExecClearTuple(), ExecReScan(), PlanState::lefttree, NULL, UniqueState::ps, and PlanState::ps_ResultTupleSlot.
Referenced by ExecReScan().
{ /* must clear result tuple so first input tuple is returned */ ExecClearTuple(node->ps.ps_ResultTupleSlot); /* * 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* ExecUnique | ( | UniqueState * | node | ) |
Definition at line 46 of file nodeUnique.c.
References UniqueState::eqfunctions, ExecClearTuple(), ExecCopySlot(), ExecProcNode(), execTuplesMatch(), Unique::numCols, outerPlan, outerPlanState, PlanState::plan, UniqueState::ps, PlanState::ps_ResultTupleSlot, UniqueState::tempContext, TupIsNull, and Unique::uniqColIdx.
Referenced by ExecProcNode().
{ Unique *plannode = (Unique *) node->ps.plan; TupleTableSlot *resultTupleSlot; TupleTableSlot *slot; PlanState *outerPlan; /* * get information from the node */ outerPlan = outerPlanState(node); resultTupleSlot = node->ps.ps_ResultTupleSlot; /* * now loop, returning only non-duplicate tuples. We assume that the * tuples arrive in sorted order so we can detect duplicates easily. The * first tuple of each group is returned. */ for (;;) { /* * fetch a tuple from the outer subplan */ slot = ExecProcNode(outerPlan); if (TupIsNull(slot)) { /* end of subplan, so we're done */ ExecClearTuple(resultTupleSlot); return NULL; } /* * Always return the first tuple from the subplan. */ if (TupIsNull(resultTupleSlot)) break; /* * Else test if the new tuple and the previously returned tuple match. * If so then we loop back and fetch another new tuple from the * subplan. */ if (!execTuplesMatch(slot, resultTupleSlot, plannode->numCols, plannode->uniqColIdx, node->eqfunctions, node->tempContext)) break; } /* * We have a new tuple different from the previous saved tuple (if any). * Save it and return it. We must copy it because the source subplan * won't guarantee that this source tuple is still accessible after * fetching the next source tuple. */ return ExecCopySlot(resultTupleSlot, slot); }