Header And Logo

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

Functions

nodeAppend.c File Reference

#include "postgres.h"
#include "executor/execdebug.h"
#include "executor/nodeAppend.h"
Include dependency graph for nodeAppend.c:

Go to the source code of this file.

Functions

static bool exec_append_initialize_next (AppendState *appendstate)
AppendStateExecInitAppend (Append *node, EState *estate, int eflags)
TupleTableSlotExecAppend (AppendState *node)
void ExecEndAppend (AppendState *node)
void ExecReScanAppend (AppendState *node)

Function Documentation

static bool exec_append_initialize_next ( AppendState appendstate  )  [static]

Definition at line 75 of file nodeAppend.c.

References AppendState::as_nplans, and AppendState::as_whichplan.

Referenced by ExecAppend(), ExecInitAppend(), and ExecReScanAppend().

{
    int         whichplan;

    /*
     * get information from the append node
     */
    whichplan = appendstate->as_whichplan;

    if (whichplan < 0)
    {
        /*
         * if scanning in reverse, we start at the last scan in the list and
         * then proceed back to the first.. in any case we inform ExecAppend
         * that we are at the end of the line by returning FALSE
         */
        appendstate->as_whichplan = 0;
        return FALSE;
    }
    else if (whichplan >= appendstate->as_nplans)
    {
        /*
         * as above, end the scan if we go beyond the last scan in our list..
         */
        appendstate->as_whichplan = appendstate->as_nplans - 1;
        return FALSE;
    }
    else
    {
        return TRUE;
    }
}

TupleTableSlot* ExecAppend ( AppendState node  ) 

Definition at line 194 of file nodeAppend.c.

References AppendState::appendplans, AppendState::as_whichplan, EState::es_direction, exec_append_initialize_next(), ExecClearTuple(), ExecProcNode(), AppendState::ps, PlanState::ps_ResultTupleSlot, ScanDirectionIsForward, PlanState::state, and TupIsNull.

Referenced by ExecProcNode().

{
    for (;;)
    {
        PlanState  *subnode;
        TupleTableSlot *result;

        /*
         * figure out which subplan we are currently processing
         */
        subnode = node->appendplans[node->as_whichplan];

        /*
         * get a tuple from the subplan
         */
        result = ExecProcNode(subnode);

        if (!TupIsNull(result))
        {
            /*
             * If the subplan gave us something then return it as-is. We do
             * NOT make use of the result slot that was set up in
             * ExecInitAppend; there's no need for it.
             */
            return result;
        }

        /*
         * Go on to the "next" subplan in the appropriate direction. If no
         * more subplans, return the empty slot set up for us by
         * ExecInitAppend.
         */
        if (ScanDirectionIsForward(node->ps.state->es_direction))
            node->as_whichplan++;
        else
            node->as_whichplan--;
        if (!exec_append_initialize_next(node))
            return ExecClearTuple(node->ps.ps_ResultTupleSlot);

        /* Else loop back and try to get a tuple from the new subplan */
    }
}

void ExecEndAppend ( AppendState node  ) 

Definition at line 246 of file nodeAppend.c.

References AppendState::appendplans, AppendState::as_nplans, ExecEndNode(), and i.

Referenced by ExecEndNode().

{
    PlanState **appendplans;
    int         nplans;
    int         i;

    /*
     * get information from the node
     */
    appendplans = node->appendplans;
    nplans = node->as_nplans;

    /*
     * shut down each of the subscans
     */
    for (i = 0; i < nplans; i++)
        ExecEndNode(appendplans[i]);
}

AppendState* ExecInitAppend ( Append node,
EState estate,
int  eflags 
)

Definition at line 120 of file nodeAppend.c.

References AppendState::appendplans, Append::appendplans, AppendState::as_nplans, AppendState::as_whichplan, Assert, exec_append_initialize_next(), EXEC_FLAG_MARK, ExecAssignResultTypeFromTL(), ExecInitNode(), ExecInitResultTupleSlot(), i, lfirst, list_length(), makeNode, palloc0(), PlanState::plan, AppendState::ps, PlanState::ps_ProjInfo, and PlanState::state.

Referenced by ExecInitNode().

{
    AppendState *appendstate = makeNode(AppendState);
    PlanState **appendplanstates;
    int         nplans;
    int         i;
    ListCell   *lc;

    /* check for unsupported flags */
    Assert(!(eflags & EXEC_FLAG_MARK));

    /*
     * Set up empty vector of subplan states
     */
    nplans = list_length(node->appendplans);

    appendplanstates = (PlanState **) palloc0(nplans * sizeof(PlanState *));

    /*
     * create new AppendState for our append node
     */
    appendstate->ps.plan = (Plan *) node;
    appendstate->ps.state = estate;
    appendstate->appendplans = appendplanstates;
    appendstate->as_nplans = nplans;

    /*
     * Miscellaneous initialization
     *
     * Append plans don't have expression contexts because they never call
     * ExecQual or ExecProject.
     */

    /*
     * append nodes still have Result slots, which hold pointers to tuples, so
     * we have to initialize them.
     */
    ExecInitResultTupleSlot(estate, &appendstate->ps);

    /*
     * call ExecInitNode on each of the plans to be executed and save the
     * results into the array "appendplans".
     */
    i = 0;
    foreach(lc, node->appendplans)
    {
        Plan       *initNode = (Plan *) lfirst(lc);

        appendplanstates[i] = ExecInitNode(initNode, estate, eflags);
        i++;
    }

    /*
     * initialize output tuple type
     */
    ExecAssignResultTypeFromTL(&appendstate->ps);
    appendstate->ps.ps_ProjInfo = NULL;

    /*
     * initialize to scan first subplan
     */
    appendstate->as_whichplan = 0;
    exec_append_initialize_next(appendstate);

    return appendstate;
}

void ExecReScanAppend ( AppendState node  ) 

Definition at line 266 of file nodeAppend.c.

References AppendState::appendplans, AppendState::as_nplans, AppendState::as_whichplan, PlanState::chgParam, exec_append_initialize_next(), ExecReScan(), i, NULL, AppendState::ps, and UpdateChangedParamSet().

Referenced by ExecReScan().

{
    int         i;

    for (i = 0; i < node->as_nplans; i++)
    {
        PlanState  *subnode = node->appendplans[i];

        /*
         * ExecReScan doesn't know about my subplans, so I have to do
         * changed-parameter signaling myself.
         */
        if (node->ps.chgParam != NULL)
            UpdateChangedParamSet(subnode, node->ps.chgParam);

        /*
         * If chgParam of subnode is not null then plan will be re-scanned by
         * first ExecProcNode.
         */
        if (subnode->chgParam == NULL)
            ExecReScan(subnode);
    }
    node->as_whichplan = 0;
    exec_append_initialize_next(node);
}