#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);
}
1.7.1