#include "nodes/execnodes.h"
Go to the source code of this file.
Functions | |
GroupState * | ExecInitGroup (Group *node, EState *estate, int eflags) |
TupleTableSlot * | ExecGroup (GroupState *node) |
void | ExecEndGroup (GroupState *node) |
void | ExecReScanGroup (GroupState *node) |
void ExecEndGroup | ( | GroupState * | node | ) |
Definition at line 267 of file nodeGroup.c.
References ExecClearTuple(), ExecEndNode(), ExecFreeExprContext(), outerPlanState, ScanState::ps, GroupState::ss, and ScanState::ss_ScanTupleSlot.
Referenced by ExecEndNode().
{ PlanState *outerPlan; ExecFreeExprContext(&node->ss.ps); /* clean up tuple table */ ExecClearTuple(node->ss.ss_ScanTupleSlot); outerPlan = outerPlanState(node); ExecEndNode(outerPlan); }
TupleTableSlot* ExecGroup | ( | GroupState * | node | ) |
Definition at line 35 of file nodeGroup.c.
References ExprContext::ecxt_outertuple, ExprContext::ecxt_per_tuple_memory, GroupState::eqfunctions, ExecCopySlot(), ExecProcNode(), ExecProject(), ExecQual(), execTuplesMatch(), ExprEndResult, ExprMultipleResult, GroupState::grp_done, InstrCountFiltered1, outerPlanState, PlanState::plan, ScanState::ps, PlanState::ps_ExprContext, PlanState::ps_ProjInfo, PlanState::ps_TupFromTlist, PlanState::qual, GroupState::ss, ScanState::ss_ScanTupleSlot, and TupIsNull.
Referenced by ExecProcNode().
{ ExprContext *econtext; int numCols; AttrNumber *grpColIdx; TupleTableSlot *firsttupleslot; TupleTableSlot *outerslot; /* * get state info from node */ if (node->grp_done) return NULL; econtext = node->ss.ps.ps_ExprContext; numCols = ((Group *) node->ss.ps.plan)->numCols; grpColIdx = ((Group *) node->ss.ps.plan)->grpColIdx; /* * Check to see if we're still projecting out tuples from a previous group * tuple (because there is a function-returning-set in the projection * expressions). If so, try to project another one. */ if (node->ss.ps.ps_TupFromTlist) { TupleTableSlot *result; ExprDoneCond isDone; result = ExecProject(node->ss.ps.ps_ProjInfo, &isDone); if (isDone == ExprMultipleResult) return result; /* Done with that source tuple... */ node->ss.ps.ps_TupFromTlist = false; } /* * The ScanTupleSlot holds the (copied) first tuple of each group. */ firsttupleslot = node->ss.ss_ScanTupleSlot; /* * We need not call ResetExprContext here because execTuplesMatch will * reset the per-tuple memory context once per input tuple. */ /* * If first time through, acquire first input tuple and determine whether * to return it or not. */ if (TupIsNull(firsttupleslot)) { outerslot = ExecProcNode(outerPlanState(node)); if (TupIsNull(outerslot)) { /* empty input, so return nothing */ node->grp_done = TRUE; return NULL; } /* Copy tuple into firsttupleslot */ ExecCopySlot(firsttupleslot, outerslot); /* * Set it up as input for qual test and projection. The expressions * will access the input tuple as varno OUTER. */ econtext->ecxt_outertuple = firsttupleslot; /* * Check the qual (HAVING clause); if the group does not match, ignore * it and fall into scan loop. */ if (ExecQual(node->ss.ps.qual, econtext, false)) { /* * Form and return a projection tuple using the first input tuple. */ TupleTableSlot *result; ExprDoneCond isDone; result = ExecProject(node->ss.ps.ps_ProjInfo, &isDone); if (isDone != ExprEndResult) { node->ss.ps.ps_TupFromTlist = (isDone == ExprMultipleResult); return result; } } else InstrCountFiltered1(node, 1); } /* * This loop iterates once per input tuple group. At the head of the * loop, we have finished processing the first tuple of the group and now * need to scan over all the other group members. */ for (;;) { /* * Scan over all remaining tuples that belong to this group */ for (;;) { outerslot = ExecProcNode(outerPlanState(node)); if (TupIsNull(outerslot)) { /* no more groups, so we're done */ node->grp_done = TRUE; return NULL; } /* * Compare with first tuple and see if this tuple is of the same * group. If so, ignore it and keep scanning. */ if (!execTuplesMatch(firsttupleslot, outerslot, numCols, grpColIdx, node->eqfunctions, econtext->ecxt_per_tuple_memory)) break; } /* * We have the first tuple of the next input group. See if we want to * return it. */ /* Copy tuple, set up as input for qual test and projection */ ExecCopySlot(firsttupleslot, outerslot); econtext->ecxt_outertuple = firsttupleslot; /* * Check the qual (HAVING clause); if the group does not match, ignore * it and loop back to scan the rest of the group. */ if (ExecQual(node->ss.ps.qual, econtext, false)) { /* * Form and return a projection tuple using the first input tuple. */ TupleTableSlot *result; ExprDoneCond isDone; result = ExecProject(node->ss.ps.ps_ProjInfo, &isDone); if (isDone != ExprEndResult) { node->ss.ps.ps_TupFromTlist = (isDone == ExprMultipleResult); return result; } } else InstrCountFiltered1(node, 1); } }
GroupState* ExecInitGroup | ( | Group * | node, | |
EState * | estate, | |||
int | eflags | |||
) |
Definition at line 197 of file nodeGroup.c.
References Assert, GroupState::eqfunctions, EXEC_FLAG_BACKWARD, EXEC_FLAG_MARK, ExecAssignExprContext(), ExecAssignProjectionInfo(), ExecAssignResultTypeFromTL(), ExecAssignScanTypeFromOuterPlan(), ExecInitExpr(), ExecInitNode(), ExecInitResultTupleSlot(), ExecInitScanTupleSlot(), execTuplesMatchPrepare(), GroupState::grp_done, Group::grpOperators, makeNode, NULL, Group::numCols, outerPlan, outerPlanState, Group::plan, PlanState::plan, ScanState::ps, PlanState::ps_TupFromTlist, Plan::qual, PlanState::qual, GroupState::ss, PlanState::state, Plan::targetlist, and PlanState::targetlist.
Referenced by ExecInitNode().
{ GroupState *grpstate; /* check for unsupported flags */ Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK))); /* * create state structure */ grpstate = makeNode(GroupState); grpstate->ss.ps.plan = (Plan *) node; grpstate->ss.ps.state = estate; grpstate->grp_done = FALSE; /* * create expression context */ ExecAssignExprContext(estate, &grpstate->ss.ps); /* * tuple table initialization */ ExecInitScanTupleSlot(estate, &grpstate->ss); ExecInitResultTupleSlot(estate, &grpstate->ss.ps); /* * initialize child expressions */ grpstate->ss.ps.targetlist = (List *) ExecInitExpr((Expr *) node->plan.targetlist, (PlanState *) grpstate); grpstate->ss.ps.qual = (List *) ExecInitExpr((Expr *) node->plan.qual, (PlanState *) grpstate); /* * initialize child nodes */ outerPlanState(grpstate) = ExecInitNode(outerPlan(node), estate, eflags); /* * initialize tuple type. */ ExecAssignScanTypeFromOuterPlan(&grpstate->ss); /* * Initialize result tuple type and projection info. */ ExecAssignResultTypeFromTL(&grpstate->ss.ps); ExecAssignProjectionInfo(&grpstate->ss.ps, NULL); grpstate->ss.ps.ps_TupFromTlist = false; /* * Precompute fmgr lookup data for inner loop */ grpstate->eqfunctions = execTuplesMatchPrepare(node->numCols, node->grpOperators); return grpstate; }
void ExecReScanGroup | ( | GroupState * | node | ) |
Definition at line 281 of file nodeGroup.c.
References PlanState::chgParam, ExecClearTuple(), ExecReScan(), GroupState::grp_done, PlanState::lefttree, NULL, ScanState::ps, PlanState::ps_TupFromTlist, GroupState::ss, and ScanState::ss_ScanTupleSlot.
Referenced by ExecReScan().
{ node->grp_done = FALSE; node->ss.ps.ps_TupFromTlist = false; /* must clear first tuple */ ExecClearTuple(node->ss.ss_ScanTupleSlot); /* * if chgParam of subnode is not null then plan will be re-scanned by * first ExecProcNode. */ if (node->ss.ps.lefttree && node->ss.ps.lefttree->chgParam == NULL) ExecReScan(node->ss.ps.lefttree); }