Header And Logo

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

Functions

nodeBitmapOr.c File Reference

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

Go to the source code of this file.

Functions

BitmapOrStateExecInitBitmapOr (BitmapOr *node, EState *estate, int eflags)
NodeMultiExecBitmapOr (BitmapOrState *node)
void ExecEndBitmapOr (BitmapOrState *node)
void ExecReScanBitmapOr (BitmapOrState *node)

Function Documentation

void ExecEndBitmapOr ( BitmapOrState node  ) 

Definition at line 180 of file nodeBitmapOr.c.

References BitmapOrState::bitmapplans, ExecEndNode(), i, and BitmapOrState::nplans.

Referenced by ExecEndNode().

{
    PlanState **bitmapplans;
    int         nplans;
    int         i;

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

    /*
     * shut down each of the subscans (that we've initialized)
     */
    for (i = 0; i < nplans; i++)
    {
        if (bitmapplans[i])
            ExecEndNode(bitmapplans[i]);
    }
}

BitmapOrState* ExecInitBitmapOr ( BitmapOr node,
EState estate,
int  eflags 
)

Definition at line 43 of file nodeBitmapOr.c.

References Assert, BitmapOrState::bitmapplans, BitmapOr::bitmapplans, EXEC_FLAG_BACKWARD, EXEC_FLAG_MARK, ExecInitNode(), i, lfirst, list_length(), makeNode, BitmapOrState::nplans, palloc0(), PlanState::plan, BitmapOrState::ps, and PlanState::state.

Referenced by ExecInitNode().

{
    BitmapOrState *bitmaporstate = makeNode(BitmapOrState);
    PlanState **bitmapplanstates;
    int         nplans;
    int         i;
    ListCell   *l;
    Plan       *initNode;

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

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

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

    /*
     * create new BitmapOrState for our BitmapOr node
     */
    bitmaporstate->ps.plan = (Plan *) node;
    bitmaporstate->ps.state = estate;
    bitmaporstate->bitmapplans = bitmapplanstates;
    bitmaporstate->nplans = nplans;

    /*
     * Miscellaneous initialization
     *
     * BitmapOr plans don't have expression contexts because they never call
     * ExecQual or ExecProject.  They don't need any tuple slots either.
     */

    /*
     * call ExecInitNode on each of the plans to be executed and save the
     * results into the array "bitmapplanstates".
     */
    i = 0;
    foreach(l, node->bitmapplans)
    {
        initNode = (Plan *) lfirst(l);
        bitmapplanstates[i] = ExecInitNode(initNode, estate, eflags);
        i++;
    }

    return bitmaporstate;
}

void ExecReScanBitmapOr ( BitmapOrState node  ) 

Definition at line 203 of file nodeBitmapOr.c.

References BitmapOrState::bitmapplans, PlanState::chgParam, ExecReScan(), i, BitmapOrState::nplans, NULL, BitmapOrState::ps, and UpdateChangedParamSet().

Referenced by ExecReScan().

{
    int         i;

    for (i = 0; i < node->nplans; i++)
    {
        PlanState  *subnode = node->bitmapplans[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* MultiExecBitmapOr ( BitmapOrState node  ) 

Definition at line 97 of file nodeBitmapOr.c.

References BitmapOrState::bitmapplans, elog, ERROR, i, InstrStartNode(), InstrStopNode(), PlanState::instrument, IsA, MultiExecProcNode(), BitmapOrState::nplans, NULL, BitmapOrState::ps, tbm_create(), tbm_free(), tbm_union(), and work_mem.

Referenced by MultiExecProcNode().

{
    PlanState **bitmapplans;
    int         nplans;
    int         i;
    TIDBitmap  *result = NULL;

    /* must provide our own instrumentation support */
    if (node->ps.instrument)
        InstrStartNode(node->ps.instrument);

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

    /*
     * Scan all the subplans and OR their result bitmaps
     */
    for (i = 0; i < nplans; i++)
    {
        PlanState  *subnode = bitmapplans[i];
        TIDBitmap  *subresult;

        /*
         * We can special-case BitmapIndexScan children to avoid an explicit
         * tbm_union step for each child: just pass down the current result
         * bitmap and let the child OR directly into it.
         */
        if (IsA(subnode, BitmapIndexScanState))
        {
            if (result == NULL) /* first subplan */
            {
                /* XXX should we use less than work_mem for this? */
                result = tbm_create(work_mem * 1024L);
            }

            ((BitmapIndexScanState *) subnode)->biss_result = result;

            subresult = (TIDBitmap *) MultiExecProcNode(subnode);

            if (subresult != result)
                elog(ERROR, "unrecognized result from subplan");
        }
        else
        {
            /* standard implementation */
            subresult = (TIDBitmap *) MultiExecProcNode(subnode);

            if (!subresult || !IsA(subresult, TIDBitmap))
                elog(ERROR, "unrecognized result from subplan");

            if (result == NULL)
                result = subresult;     /* first subplan */
            else
            {
                tbm_union(result, subresult);
                tbm_free(subresult);
            }
        }
    }

    /* We could return an empty result set here? */
    if (result == NULL)
        elog(ERROR, "BitmapOr doesn't support zero inputs");

    /* must provide our own instrumentation support */
    if (node->ps.instrument)
        InstrStopNode(node->ps.instrument, 0 /* XXX */ );

    return (Node *) result;
}