Header And Logo

PostgreSQL
| The world's most advanced open source database.

Functions

nodeUnique.c File Reference

#include "postgres.h"
#include "executor/executor.h"
#include "executor/nodeUnique.h"
#include "utils/memutils.h"
Include dependency graph for nodeUnique.c:

Go to the source code of this file.

Functions

TupleTableSlotExecUnique (UniqueState *node)
UniqueStateExecInitUnique (Unique *node, EState *estate, int eflags)
void ExecEndUnique (UniqueState *node)
void ExecReScanUnique (UniqueState *node)

Function Documentation

void ExecEndUnique ( UniqueState 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);
}