1/*-------------------------------------------------------------------------
4 * routines to handle BitmapAnd nodes.
6 * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
11 * src/backend/executor/nodeBitmapAnd.c
13 *-------------------------------------------------------------------------
16 * ExecInitBitmapAnd - initialize the BitmapAnd node
17 * MultiExecBitmapAnd - retrieve the result bitmap from the node
18 * ExecEndBitmapAnd - shut down the BitmapAnd node
19 * ExecReScanBitmapAnd - rescan the BitmapAnd node
22 * BitmapAnd nodes don't make use of their left and right
23 * subtrees, rather they maintain a list of subplans,
24 * much like Append nodes. The logic is much simpler than
25 * Append, however, since we needn't cope with forward/backward
35/* ----------------------------------------------------------------
38 * stub for pro forma compliance
39 * ----------------------------------------------------------------
44 elog(
ERROR,
"BitmapAnd node does not support ExecProcNode call convention");
48/* ----------------------------------------------------------------
51 * Begin all of the subscans of the BitmapAnd node.
52 * ----------------------------------------------------------------
64 /* check for unsupported flags */
68 * Set up empty vector of subplan states
75 * create new BitmapAndState for our BitmapAnd node
78 bitmapandstate->
ps.
state = estate;
81 bitmapandstate->
nplans = nplans;
84 * call ExecInitNode on each of the plans to be executed and save the
85 * results into the array "bitmapplanstates".
96 * Miscellaneous initialization
98 * BitmapAnd plans don't have expression contexts because they never call
99 * ExecQual or ExecProject. They don't need any tuple slots either.
102 return bitmapandstate;
105/* ----------------------------------------------------------------
107 * ----------------------------------------------------------------
117 /* must provide our own instrumentation support */
122 * get information from the node
128 * Scan all the subplans and AND their result bitmaps
130 for (
i = 0;
i < nplans;
i++)
138 elog(
ERROR,
"unrecognized result from subplan");
141 result = subresult;
/* first subplan */
149 * If at any stage we have a completely empty bitmap, we can fall out
150 * without evaluating the remaining subplans, since ANDing them can no
151 * longer change the result. (Note: the fact that indxpath.c orders
152 * the subplans by selectivity should make this case more likely to
160 elog(
ERROR,
"BitmapAnd doesn't support zero inputs");
162 /* must provide our own instrumentation support */
166 return (
Node *) result;
169/* ----------------------------------------------------------------
172 * Shuts down the subscans of the BitmapAnd node.
174 * Returns nothing of interest.
175 * ----------------------------------------------------------------
185 * get information from the node
191 * shut down each of the subscans (that we've initialized)
193 for (
i = 0;
i < nplans;
i++)
210 * ExecReScan doesn't know about my subplans, so I have to do
211 * changed-parameter signaling myself.
217 * If chgParam of subnode is not null then plan will be re-scanned by
218 * first ExecProcNode.
void ExecReScan(PlanState *node)
Node * MultiExecProcNode(PlanState *node)
void ExecEndNode(PlanState *node)
PlanState * ExecInitNode(Plan *node, EState *estate, int eflags)
void UpdateChangedParamSet(PlanState *node, Bitmapset *newchg)
#define EXEC_FLAG_BACKWARD
Assert(PointerIsAligned(start, uint64))
void InstrStartNode(Instrumentation *instr)
void InstrStopNode(Instrumentation *instr, double nTuples)
void * palloc0(Size size)
BitmapAndState * ExecInitBitmapAnd(BitmapAnd *node, EState *estate, int eflags)
Node * MultiExecBitmapAnd(BitmapAndState *node)
void ExecEndBitmapAnd(BitmapAndState *node)
static TupleTableSlot * ExecBitmapAnd(PlanState *pstate)
void ExecReScanBitmapAnd(BitmapAndState *node)
#define IsA(nodeptr, _type_)
static int list_length(const List *l)
Instrumentation * instrument
ExecProcNodeMtd ExecProcNode
void tbm_free(TIDBitmap *tbm)
bool tbm_is_empty(const TIDBitmap *tbm)
void tbm_intersect(TIDBitmap *a, const TIDBitmap *b)