1
/*-------------------------------------------------------------------------
4
* routines to handle BitmapAnd nodes.
6
* Portions Copyright (c) 1996-2011, 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
31
#include "executor/execdebug.h"
32
#include "executor/instrument.h"
33
#include "executor/nodeBitmapAnd.h"
36
/* ----------------------------------------------------------------
39
* Begin all of the subscans of the BitmapAnd node.
40
* ----------------------------------------------------------------
43
ExecInitBitmapAnd(BitmapAnd *node, EState *estate, int eflags)
45
BitmapAndState *bitmapandstate = makeNode(BitmapAndState);
46
PlanState **bitmapplanstates;
52
/* check for unsupported flags */
53
Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK)));
56
* Set up empty vector of subplan states
58
nplans = list_length(node->bitmapplans);
60
bitmapplanstates = (PlanState **) palloc0(nplans * sizeof(PlanState *));
63
* create new BitmapAndState for our BitmapAnd node
65
bitmapandstate->ps.plan = (Plan *) node;
66
bitmapandstate->ps.state = estate;
67
bitmapandstate->bitmapplans = bitmapplanstates;
68
bitmapandstate->nplans = nplans;
71
* Miscellaneous initialization
73
* BitmapAnd plans don't have expression contexts because they never call
74
* ExecQual or ExecProject. They don't need any tuple slots either.
78
* call ExecInitNode on each of the plans to be executed and save the
79
* results into the array "bitmapplanstates".
82
foreach(l, node->bitmapplans)
84
initNode = (Plan *) lfirst(l);
85
bitmapplanstates[i] = ExecInitNode(initNode, estate, eflags);
89
return bitmapandstate;
92
/* ----------------------------------------------------------------
94
* ----------------------------------------------------------------
97
MultiExecBitmapAnd(BitmapAndState *node)
99
PlanState **bitmapplans;
102
TIDBitmap *result = NULL;
104
/* must provide our own instrumentation support */
105
if (node->ps.instrument)
106
InstrStartNode(node->ps.instrument);
109
* get information from the node
111
bitmapplans = node->bitmapplans;
112
nplans = node->nplans;
115
* Scan all the subplans and AND their result bitmaps
117
for (i = 0; i < nplans; i++)
119
PlanState *subnode = bitmapplans[i];
120
TIDBitmap *subresult;
122
subresult = (TIDBitmap *) MultiExecProcNode(subnode);
124
if (!subresult || !IsA(subresult, TIDBitmap))
125
elog(ERROR, "unrecognized result from subplan");
128
result = subresult; /* first subplan */
131
tbm_intersect(result, subresult);
136
* If at any stage we have a completely empty bitmap, we can fall out
137
* without evaluating the remaining subplans, since ANDing them can no
138
* longer change the result. (Note: the fact that indxpath.c orders
139
* the subplans by selectivity should make this case more likely to
142
if (tbm_is_empty(result))
147
elog(ERROR, "BitmapAnd doesn't support zero inputs");
149
/* must provide our own instrumentation support */
150
if (node->ps.instrument)
151
InstrStopNode(node->ps.instrument, 0 /* XXX */ );
153
return (Node *) result;
156
/* ----------------------------------------------------------------
159
* Shuts down the subscans of the BitmapAnd node.
161
* Returns nothing of interest.
162
* ----------------------------------------------------------------
165
ExecEndBitmapAnd(BitmapAndState *node)
167
PlanState **bitmapplans;
172
* get information from the node
174
bitmapplans = node->bitmapplans;
175
nplans = node->nplans;
178
* shut down each of the subscans (that we've initialized)
180
for (i = 0; i < nplans; i++)
183
ExecEndNode(bitmapplans[i]);
188
ExecReScanBitmapAnd(BitmapAndState *node)
192
for (i = 0; i < node->nplans; i++)
194
PlanState *subnode = node->bitmapplans[i];
197
* ExecReScan doesn't know about my subplans, so I have to do
198
* changed-parameter signaling myself.
200
if (node->ps.chgParam != NULL)
201
UpdateChangedParamSet(subnode, node->ps.chgParam);
204
* If chgParam of subnode is not null then plan will be re-scanned by
205
* first ExecProcNode.
207
if (subnode->chgParam == NULL)