PostgreSQL Source Code git master
Loading...
Searching...
No Matches
nodeBitmapOr.c
Go to the documentation of this file.
1/*-------------------------------------------------------------------------
2 *
3 * nodeBitmapOr.c
4 * routines to handle BitmapOr nodes.
5 *
6 * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
8 *
9 *
10 * IDENTIFICATION
11 * src/backend/executor/nodeBitmapOr.c
12 *
13 *-------------------------------------------------------------------------
14 */
15/*
16 * INTERFACE ROUTINES
17 * ExecInitBitmapOr - initialize the BitmapOr node
18 * MultiExecBitmapOr - retrieve the result bitmap from the node
19 * ExecEndBitmapOr - shut down the BitmapOr node
20 * ExecReScanBitmapOr - rescan the BitmapOr node
21 *
22 * NOTES
23 * BitmapOr nodes don't make use of their left and right
24 * subtrees, rather they maintain a list of subplans,
25 * much like Append nodes. The logic is much simpler than
26 * Append, however, since we needn't cope with forward/backward
27 * execution.
28 */
29
30#include "postgres.h"
31
32#include "executor/executor.h"
33#include "executor/instrument.h"
35#include "nodes/tidbitmap.h"
36#include "miscadmin.h"
37
38
39/* ----------------------------------------------------------------
40 * ExecBitmapOr
41 *
42 * stub for pro forma compliance
43 * ----------------------------------------------------------------
44 */
45static TupleTableSlot *
47{
48 elog(ERROR, "BitmapOr node does not support ExecProcNode call convention");
49 return NULL;
50}
51
52/* ----------------------------------------------------------------
53 * ExecInitBitmapOr
54 *
55 * Begin all of the subscans of the BitmapOr node.
56 * ----------------------------------------------------------------
57 */
59ExecInitBitmapOr(BitmapOr *node, EState *estate, int eflags)
60{
63 int nplans;
64 int i;
65 ListCell *l;
67
68 /* check for unsupported flags */
70
71 /*
72 * Set up empty vector of subplan states
73 */
74 nplans = list_length(node->bitmapplans);
75
76 bitmapplanstates = (PlanState **) palloc0(nplans * sizeof(PlanState *));
77
78 /*
79 * create new BitmapOrState for our BitmapOr node
80 */
81 bitmaporstate->ps.plan = (Plan *) node;
82 bitmaporstate->ps.state = estate;
83 bitmaporstate->ps.ExecProcNode = ExecBitmapOr;
84 bitmaporstate->bitmapplans = bitmapplanstates;
85 bitmaporstate->nplans = nplans;
86
87 /*
88 * call ExecInitNode on each of the plans to be executed and save the
89 * results into the array "bitmapplanstates".
90 */
91 i = 0;
92 foreach(l, node->bitmapplans)
93 {
94 initNode = (Plan *) lfirst(l);
95 bitmapplanstates[i] = ExecInitNode(initNode, estate, eflags);
96 i++;
97 }
98
99 /*
100 * Miscellaneous initialization
101 *
102 * BitmapOr plans don't have expression contexts because they never call
103 * ExecQual or ExecProject. They don't need any tuple slots either.
104 */
105
106 return bitmaporstate;
107}
108
109/* ----------------------------------------------------------------
110 * MultiExecBitmapOr
111 * ----------------------------------------------------------------
112 */
113Node *
115{
116 PlanState **bitmapplans;
117 int nplans;
118 int i;
120
121 /* must provide our own instrumentation support */
122 if (node->ps.instrument)
124
125 /*
126 * get information from the node
127 */
128 bitmapplans = node->bitmapplans;
129 nplans = node->nplans;
130
131 /*
132 * Scan all the subplans and OR their result bitmaps
133 */
134 for (i = 0; i < nplans; i++)
135 {
136 PlanState *subnode = bitmapplans[i];
138
139 /*
140 * We can special-case BitmapIndexScan children to avoid an explicit
141 * tbm_union step for each child: just pass down the current result
142 * bitmap and let the child OR directly into it.
143 */
145 {
146 if (result == NULL) /* first subplan */
147 {
148 /* XXX should we use less than work_mem for this? */
149 result = tbm_create(work_mem * (Size) 1024,
150 ((BitmapOr *) node->ps.plan)->isshared ?
151 node->ps.state->es_query_dsa : NULL);
152 }
153
154 ((BitmapIndexScanState *) subnode)->biss_result = result;
155
157
158 if (subresult != result)
159 elog(ERROR, "unrecognized result from subplan");
160 }
161 else
162 {
163 /* standard implementation */
165
166 if (!subresult || !IsA(subresult, TIDBitmap))
167 elog(ERROR, "unrecognized result from subplan");
168
169 if (result == NULL)
170 result = subresult; /* first subplan */
171 else
172 {
175 }
176 }
177 }
178
179 /* We could return an empty result set here? */
180 if (result == NULL)
181 elog(ERROR, "BitmapOr doesn't support zero inputs");
182
183 /* must provide our own instrumentation support */
184 if (node->ps.instrument)
185 InstrStopNode(node->ps.instrument, 0 /* XXX */ );
186
187 return (Node *) result;
188}
189
190/* ----------------------------------------------------------------
191 * ExecEndBitmapOr
192 *
193 * Shuts down the subscans of the BitmapOr node.
194 *
195 * Returns nothing of interest.
196 * ----------------------------------------------------------------
197 */
198void
200{
201 PlanState **bitmapplans;
202 int nplans;
203 int i;
204
205 /*
206 * get information from the node
207 */
208 bitmapplans = node->bitmapplans;
209 nplans = node->nplans;
210
211 /*
212 * shut down each of the subscans (that we've initialized)
213 */
214 for (i = 0; i < nplans; i++)
215 {
216 if (bitmapplans[i])
217 ExecEndNode(bitmapplans[i]);
218 }
219}
220
221void
223{
224 int i;
225
226 for (i = 0; i < node->nplans; i++)
227 {
228 PlanState *subnode = node->bitmapplans[i];
229
230 /*
231 * ExecReScan doesn't know about my subplans, so I have to do
232 * changed-parameter signaling myself.
233 */
234 if (node->ps.chgParam != NULL)
236
237 /*
238 * If chgParam of subnode is not null then plan will be re-scanned by
239 * first ExecProcNode.
240 */
241 if (subnode->chgParam == NULL)
243 }
244}
#define Assert(condition)
Definition c.h:943
size_t Size
Definition c.h:689
uint32 result
#define ERROR
Definition elog.h:40
#define elog(elevel,...)
Definition elog.h:228
void ExecReScan(PlanState *node)
Definition execAmi.c:78
Node * MultiExecProcNode(PlanState *node)
void ExecEndNode(PlanState *node)
PlanState * ExecInitNode(Plan *node, EState *estate, int eflags)
void UpdateChangedParamSet(PlanState *node, Bitmapset *newchg)
Definition execUtils.c:936
#define EXEC_FLAG_BACKWARD
Definition executor.h:70
#define EXEC_FLAG_MARK
Definition executor.h:71
int work_mem
Definition globals.c:133
void InstrStartNode(NodeInstrumentation *instr)
Definition instrument.c:132
void InstrStopNode(NodeInstrumentation *instr, double nTuples)
Definition instrument.c:139
int i
Definition isn.c:77
void * palloc0(Size size)
Definition mcxt.c:1420
void ExecEndBitmapOr(BitmapOrState *node)
Node * MultiExecBitmapOr(BitmapOrState *node)
void ExecReScanBitmapOr(BitmapOrState *node)
BitmapOrState * ExecInitBitmapOr(BitmapOr *node, EState *estate, int eflags)
static TupleTableSlot * ExecBitmapOr(PlanState *pstate)
#define IsA(nodeptr, _type_)
Definition nodes.h:164
#define makeNode(_type_)
Definition nodes.h:161
#define lfirst(lc)
Definition pg_list.h:172
static int list_length(const List *l)
Definition pg_list.h:152
static int fb(int x)
PlanState ps
Definition execnodes.h:1633
PlanState ** bitmapplans
Definition execnodes.h:1634
List * bitmapplans
Definition plannodes.h:528
struct dsa_area * es_query_dsa
Definition execnodes.h:788
Definition nodes.h:135
Plan * plan
Definition execnodes.h:1201
EState * state
Definition execnodes.h:1203
NodeInstrumentation * instrument
Definition execnodes.h:1211
Bitmapset * chgParam
Definition execnodes.h:1235
void tbm_free(TIDBitmap *tbm)
Definition tidbitmap.c:312
void tbm_union(TIDBitmap *a, const TIDBitmap *b)
Definition tidbitmap.c:447
TIDBitmap * tbm_create(Size maxbytes, dsa_area *dsa)
Definition tidbitmap.c:256