PostgreSQL Source Code git master
Loading...
Searching...
No Matches
nodeBitmapIndexscan.h File Reference
#include "access/parallel.h"
#include "nodes/execnodes.h"
Include dependency graph for nodeBitmapIndexscan.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

BitmapIndexScanStateExecInitBitmapIndexScan (BitmapIndexScan *node, EState *estate, int eflags)
 
NodeMultiExecBitmapIndexScan (BitmapIndexScanState *node)
 
void ExecEndBitmapIndexScan (BitmapIndexScanState *node)
 
void ExecReScanBitmapIndexScan (BitmapIndexScanState *node)
 
void ExecBitmapIndexScanEstimate (BitmapIndexScanState *node, ParallelContext *pcxt)
 
void ExecBitmapIndexScanInitializeDSM (BitmapIndexScanState *node, ParallelContext *pcxt)
 
void ExecBitmapIndexScanInitializeWorker (BitmapIndexScanState *node, ParallelWorkerContext *pwcxt)
 
void ExecBitmapIndexScanRetrieveInstrumentation (BitmapIndexScanState *node)
 

Function Documentation

◆ ExecBitmapIndexScanEstimate()

void ExecBitmapIndexScanEstimate ( BitmapIndexScanState node,
ParallelContext pcxt 
)
extern

Definition at line 355 of file nodeBitmapIndexscan.c.

356{
357 Size size;
358
359 /*
360 * Parallel bitmap index scans are not supported, but we still need to
361 * store the scan's instrumentation in DSM during parallel query
362 */
363 if (!node->ss.ps.instrument || pcxt->nworkers == 0)
364 return;
365
366 size = offsetof(SharedIndexScanInstrumentation, winstrument) +
367 pcxt->nworkers * sizeof(IndexScanInstrumentation);
368 shm_toc_estimate_chunk(&pcxt->estimator, size);
370}
size_t Size
Definition c.h:691
static int fb(int x)
#define shm_toc_estimate_chunk(e, sz)
Definition shm_toc.h:51
#define shm_toc_estimate_keys(e, cnt)
Definition shm_toc.h:53
shm_toc_estimator estimator
Definition parallel.h:43
Instrumentation * instrument
Definition execnodes.h:1187
PlanState ps
Definition execnodes.h:1633

References ParallelContext::estimator, fb(), PlanState::instrument, ParallelContext::nworkers, ScanState::ps, shm_toc_estimate_chunk, shm_toc_estimate_keys, and BitmapIndexScanState::ss.

Referenced by ExecParallelEstimate().

◆ ExecBitmapIndexScanInitializeDSM()

void ExecBitmapIndexScanInitializeDSM ( BitmapIndexScanState node,
ParallelContext pcxt 
)
extern

Definition at line 379 of file nodeBitmapIndexscan.c.

381{
382 Size size;
383
384 /* don't need this if not instrumenting or no workers */
385 if (!node->ss.ps.instrument || pcxt->nworkers == 0)
386 return;
387
388 size = offsetof(SharedIndexScanInstrumentation, winstrument) +
389 pcxt->nworkers * sizeof(IndexScanInstrumentation);
390 node->biss_SharedInfo =
392 size);
393 shm_toc_insert(pcxt->toc, node->ss.ps.plan->plan_node_id,
394 node->biss_SharedInfo);
395
396 /* Each per-worker area must start out as zeroes */
397 memset(node->biss_SharedInfo, 0, size);
398 node->biss_SharedInfo->num_workers = pcxt->nworkers;
399}
void * shm_toc_allocate(shm_toc *toc, Size nbytes)
Definition shm_toc.c:88
void shm_toc_insert(shm_toc *toc, uint64 key, void *address)
Definition shm_toc.c:171
SharedIndexScanInstrumentation * biss_SharedInfo
Definition execnodes.h:1828
shm_toc * toc
Definition parallel.h:46
Plan * plan
Definition execnodes.h:1177
int plan_node_id
Definition plannodes.h:231

References BitmapIndexScanState::biss_SharedInfo, fb(), PlanState::instrument, SharedIndexScanInstrumentation::num_workers, ParallelContext::nworkers, PlanState::plan, Plan::plan_node_id, ScanState::ps, shm_toc_allocate(), shm_toc_insert(), BitmapIndexScanState::ss, and ParallelContext::toc.

Referenced by ExecParallelInitializeDSM().

◆ ExecBitmapIndexScanInitializeWorker()

void ExecBitmapIndexScanInitializeWorker ( BitmapIndexScanState node,
ParallelWorkerContext pwcxt 
)
extern

Definition at line 408 of file nodeBitmapIndexscan.c.

410{
411 /* don't need this if not instrumenting */
412 if (!node->ss.ps.instrument)
413 return;
414
416 shm_toc_lookup(pwcxt->toc, node->ss.ps.plan->plan_node_id, false);
417}
void * shm_toc_lookup(shm_toc *toc, uint64 key, bool noError)
Definition shm_toc.c:232

References BitmapIndexScanState::biss_SharedInfo, fb(), PlanState::instrument, PlanState::plan, Plan::plan_node_id, ScanState::ps, shm_toc_lookup(), and BitmapIndexScanState::ss.

Referenced by ExecParallelInitializeWorker().

◆ ExecBitmapIndexScanRetrieveInstrumentation()

void ExecBitmapIndexScanRetrieveInstrumentation ( BitmapIndexScanState node)
extern

Definition at line 426 of file nodeBitmapIndexscan.c.

427{
429 size_t size;
430
431 if (SharedInfo == NULL)
432 return;
433
434 /* Create a copy of SharedInfo in backend-local memory */
435 size = offsetof(SharedIndexScanInstrumentation, winstrument) +
437 node->biss_SharedInfo = palloc(size);
438 memcpy(node->biss_SharedInfo, SharedInfo, size);
439}
void * palloc(Size size)
Definition mcxt.c:1387

References BitmapIndexScanState::biss_SharedInfo, fb(), SharedIndexScanInstrumentation::num_workers, and palloc().

Referenced by ExecParallelRetrieveInstrumentation().

◆ ExecEndBitmapIndexScan()

void ExecEndBitmapIndexScan ( BitmapIndexScanState node)
extern

Definition at line 177 of file nodeBitmapIndexscan.c.

178{
181
182 /*
183 * extract information from the node
184 */
187
188 /*
189 * When ending a parallel worker, copy the statistics gathered by the
190 * worker back into shared memory so that it can be picked up by the main
191 * process to report in EXPLAIN ANALYZE
192 */
193 if (node->biss_SharedInfo != NULL && IsParallelWorker())
194 {
195 IndexScanInstrumentation *winstrument;
196
197 Assert(ParallelWorkerNumber < node->biss_SharedInfo->num_workers);
198 winstrument = &node->biss_SharedInfo->winstrument[ParallelWorkerNumber];
199
200 /*
201 * We have to accumulate the stats rather than performing a memcpy.
202 * When a Gather/GatherMerge node finishes it will perform planner
203 * shutdown on the workers. On rescan it will spin up new workers
204 * which will have a new BitmapIndexScanState and zeroed stats.
205 */
206 winstrument->nsearches += node->biss_Instrument.nsearches;
207 }
208
209 /*
210 * close the index relation (no-op if we didn't open it)
211 */
212 if (indexScanDesc)
216}
int ParallelWorkerNumber
Definition parallel.c:117
#define Assert(condition)
Definition c.h:945
#define IsParallelWorker()
Definition parallel.h:62
void index_close(Relation relation, LOCKMODE lockmode)
Definition indexam.c:177
void index_endscan(IndexScanDesc scan)
Definition indexam.c:392
#define NoLock
Definition lockdefs.h:34
struct IndexScanDescData * biss_ScanDesc
Definition execnodes.h:1826
Relation biss_RelationDesc
Definition execnodes.h:1825
IndexScanInstrumentation biss_Instrument
Definition execnodes.h:1827
IndexScanInstrumentation winstrument[FLEXIBLE_ARRAY_MEMBER]

References Assert, BitmapIndexScanState::biss_Instrument, BitmapIndexScanState::biss_RelationDesc, BitmapIndexScanState::biss_ScanDesc, BitmapIndexScanState::biss_SharedInfo, fb(), index_close(), index_endscan(), IsParallelWorker, NoLock, IndexScanInstrumentation::nsearches, ParallelWorkerNumber, and SharedIndexScanInstrumentation::winstrument.

Referenced by ExecEndNode().

◆ ExecInitBitmapIndexScan()

BitmapIndexScanState * ExecInitBitmapIndexScan ( BitmapIndexScan node,
EState estate,
int  eflags 
)
extern

Definition at line 225 of file nodeBitmapIndexscan.c.

226{
228 LOCKMODE lockmode;
229
230 /* check for unsupported flags */
232
233 /*
234 * create state structure
235 */
237 indexstate->ss.ps.plan = (Plan *) node;
238 indexstate->ss.ps.state = estate;
239 indexstate->ss.ps.ExecProcNode = ExecBitmapIndexScan;
240
241 /* normally we don't make the result bitmap till runtime */
242 indexstate->biss_result = NULL;
243
244 /*
245 * We do not open or lock the base relation here. We assume that an
246 * ancestor BitmapHeapScan node is holding AccessShareLock (or better) on
247 * the heap relation throughout the execution of the plan tree.
248 */
249
250 indexstate->ss.ss_currentRelation = NULL;
251 indexstate->ss.ss_currentScanDesc = NULL;
252
253 /*
254 * Miscellaneous initialization
255 *
256 * We do not need a standard exprcontext for this node, though we may
257 * decide below to create a runtime-key exprcontext
258 */
259
260 /*
261 * initialize child expressions
262 *
263 * We don't need to initialize targetlist or qual since neither are used.
264 *
265 * Note: we don't initialize all of the indexqual expression, only the
266 * sub-parts corresponding to runtime keys (see below).
267 */
268
269 /*
270 * If we are just doing EXPLAIN (ie, aren't going to run the plan), stop
271 * here. This allows an index-advisor plugin to EXPLAIN a plan containing
272 * references to nonexistent indexes.
273 */
274 if (eflags & EXEC_FLAG_EXPLAIN_ONLY)
275 return indexstate;
276
277 /* Open the index relation. */
278 lockmode = exec_rt_fetch(node->scan.scanrelid, estate)->rellockmode;
279 indexstate->biss_RelationDesc = index_open(node->indexid, lockmode);
280
281 /*
282 * Initialize index-specific scan state
283 */
284 indexstate->biss_RuntimeKeysReady = false;
285 indexstate->biss_RuntimeKeys = NULL;
286 indexstate->biss_NumRuntimeKeys = 0;
287
288 /*
289 * build the index scan keys from the index qualification
290 */
292 indexstate->biss_RelationDesc,
293 node->indexqual,
294 false,
295 &indexstate->biss_ScanKeys,
296 &indexstate->biss_NumScanKeys,
297 &indexstate->biss_RuntimeKeys,
298 &indexstate->biss_NumRuntimeKeys,
299 &indexstate->biss_ArrayKeys,
300 &indexstate->biss_NumArrayKeys);
301
302 /*
303 * If we have runtime keys or array keys, we need an ExprContext to
304 * evaluate them. We could just create a "standard" plan node exprcontext,
305 * but to keep the code looking similar to nodeIndexscan.c, it seems
306 * better to stick with the approach of using a separate ExprContext.
307 */
308 if (indexstate->biss_NumRuntimeKeys != 0 ||
309 indexstate->biss_NumArrayKeys != 0)
310 {
311 ExprContext *stdecontext = indexstate->ss.ps.ps_ExprContext;
312
313 ExecAssignExprContext(estate, &indexstate->ss.ps);
314 indexstate->biss_RuntimeContext = indexstate->ss.ps.ps_ExprContext;
315 indexstate->ss.ps.ps_ExprContext = stdecontext;
316 }
317 else
318 {
319 indexstate->biss_RuntimeContext = NULL;
320 }
321
322 /*
323 * Initialize scan descriptor.
324 */
325 indexstate->biss_ScanDesc =
326 index_beginscan_bitmap(indexstate->biss_RelationDesc,
327 estate->es_snapshot,
328 &indexstate->biss_Instrument,
329 indexstate->biss_NumScanKeys);
330
331 /*
332 * If no run-time keys to calculate, go ahead and pass the scankeys to the
333 * index AM.
334 */
335 if (indexstate->biss_NumRuntimeKeys == 0 &&
336 indexstate->biss_NumArrayKeys == 0)
337 index_rescan(indexstate->biss_ScanDesc,
338 indexstate->biss_ScanKeys, indexstate->biss_NumScanKeys,
339 NULL, 0);
340
341 /*
342 * all done.
343 */
344 return indexstate;
345}
void ExecAssignExprContext(EState *estate, PlanState *planstate)
Definition execUtils.c:490
#define EXEC_FLAG_BACKWARD
Definition executor.h:70
static RangeTblEntry * exec_rt_fetch(Index rti, EState *estate)
Definition executor.h:701
#define EXEC_FLAG_EXPLAIN_ONLY
Definition executor.h:67
#define EXEC_FLAG_MARK
Definition executor.h:71
IndexScanDesc index_beginscan_bitmap(Relation indexRelation, Snapshot snapshot, IndexScanInstrumentation *instrument, int nkeys)
Definition indexam.c:299
Relation index_open(Oid relationId, LOCKMODE lockmode)
Definition indexam.c:133
void index_rescan(IndexScanDesc scan, ScanKey keys, int nkeys, ScanKey orderbys, int norderbys)
Definition indexam.c:366
int LOCKMODE
Definition lockdefs.h:26
static TupleTableSlot * ExecBitmapIndexScan(PlanState *pstate)
void ExecIndexBuildScanKeys(PlanState *planstate, Relation index, List *quals, bool isorderby, ScanKey *scanKeys, int *numScanKeys, IndexRuntimeKeyInfo **runtimeKeys, int *numRuntimeKeys, IndexArrayKeyInfo **arrayKeys, int *numArrayKeys)
#define makeNode(_type_)
Definition nodes.h:161
Snapshot es_snapshot
Definition execnodes.h:672
Index scanrelid
Definition plannodes.h:540

References Assert, EState::es_snapshot, EXEC_FLAG_BACKWARD, EXEC_FLAG_EXPLAIN_ONLY, EXEC_FLAG_MARK, exec_rt_fetch(), ExecAssignExprContext(), ExecBitmapIndexScan(), ExecIndexBuildScanKeys(), fb(), index_beginscan_bitmap(), index_open(), index_rescan(), BitmapIndexScan::indexid, BitmapIndexScan::indexqual, makeNode, BitmapIndexScan::scan, and Scan::scanrelid.

Referenced by ExecInitNode().

◆ ExecReScanBitmapIndexScan()

void ExecReScanBitmapIndexScan ( BitmapIndexScanState node)
extern

Definition at line 133 of file nodeBitmapIndexscan.c.

134{
135 ExprContext *econtext = node->biss_RuntimeContext;
136
137 /*
138 * Reset the runtime-key context so we don't leak memory as each outer
139 * tuple is scanned. Note this assumes that we will recalculate *all*
140 * runtime keys on each call.
141 */
142 if (econtext)
143 ResetExprContext(econtext);
144
145 /*
146 * If we are doing runtime key calculations (ie, any of the index key
147 * values weren't simple Consts), compute the new key values.
148 *
149 * Array keys are also treated as runtime keys; note that if we return
150 * with biss_RuntimeKeysReady still false, then there is an empty array
151 * key so no index scan is needed.
152 */
153 if (node->biss_NumRuntimeKeys != 0)
155 node->biss_RuntimeKeys,
156 node->biss_NumRuntimeKeys);
157 if (node->biss_NumArrayKeys != 0)
159 ExecIndexEvalArrayKeys(econtext,
160 node->biss_ArrayKeys,
161 node->biss_NumArrayKeys);
162 else
163 node->biss_RuntimeKeysReady = true;
164
165 /* reset index scan */
166 if (node->biss_RuntimeKeysReady)
168 node->biss_ScanKeys, node->biss_NumScanKeys,
169 NULL, 0);
170}
#define ResetExprContext(econtext)
Definition executor.h:654
bool ExecIndexEvalArrayKeys(ExprContext *econtext, IndexArrayKeyInfo *arrayKeys, int numArrayKeys)
void ExecIndexEvalRuntimeKeys(ExprContext *econtext, IndexRuntimeKeyInfo *runtimeKeys, int numRuntimeKeys)
ExprContext * biss_RuntimeContext
Definition execnodes.h:1824
IndexArrayKeyInfo * biss_ArrayKeys
Definition execnodes.h:1821
ScanKeyData * biss_ScanKeys
Definition execnodes.h:1817
IndexRuntimeKeyInfo * biss_RuntimeKeys
Definition execnodes.h:1819

References BitmapIndexScanState::biss_ArrayKeys, BitmapIndexScanState::biss_NumArrayKeys, BitmapIndexScanState::biss_NumRuntimeKeys, BitmapIndexScanState::biss_NumScanKeys, BitmapIndexScanState::biss_RuntimeContext, BitmapIndexScanState::biss_RuntimeKeys, BitmapIndexScanState::biss_RuntimeKeysReady, BitmapIndexScanState::biss_ScanDesc, BitmapIndexScanState::biss_ScanKeys, ExecIndexEvalArrayKeys(), ExecIndexEvalRuntimeKeys(), fb(), index_rescan(), and ResetExprContext.

Referenced by ExecReScan().

◆ MultiExecBitmapIndexScan()

Node * MultiExecBitmapIndexScan ( BitmapIndexScanState node)
extern

Definition at line 51 of file nodeBitmapIndexscan.c.

52{
53 TIDBitmap *tbm;
54 IndexScanDesc scandesc;
55 double nTuples = 0;
56 bool doscan;
57
58 /* must provide our own instrumentation support */
59 if (node->ss.ps.instrument)
61
62 /*
63 * extract necessary information from index scan node
64 */
65 scandesc = node->biss_ScanDesc;
66
67 /*
68 * If we have runtime keys and they've not already been set up, do it now.
69 * Array keys are also treated as runtime keys; note that if ExecReScan
70 * returns with biss_RuntimeKeysReady still false, then there is an empty
71 * array key so we should do nothing.
72 */
73 if (!node->biss_RuntimeKeysReady &&
74 (node->biss_NumRuntimeKeys != 0 || node->biss_NumArrayKeys != 0))
75 {
76 ExecReScan((PlanState *) node);
78 }
79 else
80 doscan = true;
81
82 /*
83 * Prepare the result bitmap. Normally we just create a new one to pass
84 * back; however, our parent node is allowed to store a pre-made one into
85 * node->biss_result, in which case we just OR our tuple IDs into the
86 * existing bitmap. (This saves needing explicit UNION steps.)
87 */
88 if (node->biss_result)
89 {
90 tbm = node->biss_result;
91 node->biss_result = NULL; /* reset for next time */
92 }
93 else
94 {
95 /* XXX should we use less than work_mem for this? */
96 tbm = tbm_create(work_mem * (Size) 1024,
97 ((BitmapIndexScan *) node->ss.ps.plan)->isshared ?
98 node->ss.ps.state->es_query_dsa : NULL);
99 }
100
101 /*
102 * Get TIDs from index and insert into bitmap
103 */
104 while (doscan)
105 {
106 nTuples += (double) index_getbitmap(scandesc, tbm);
107
109
111 node->biss_NumArrayKeys);
112 if (doscan) /* reset index scan */
114 node->biss_ScanKeys, node->biss_NumScanKeys,
115 NULL, 0);
116 }
117
118 /* must provide our own instrumentation support */
119 if (node->ss.ps.instrument)
120 InstrStopNode(node->ss.ps.instrument, nTuples);
121
122 return (Node *) tbm;
123}
void ExecReScan(PlanState *node)
Definition execAmi.c:78
int work_mem
Definition globals.c:131
int64 index_getbitmap(IndexScanDesc scan, TIDBitmap *bitmap)
Definition indexam.c:775
void InstrStartNode(Instrumentation *instr)
Definition instrument.c:68
void InstrStopNode(Instrumentation *instr, double nTuples)
Definition instrument.c:88
#define CHECK_FOR_INTERRUPTS()
Definition miscadmin.h:123
bool ExecIndexAdvanceArrayKeys(IndexArrayKeyInfo *arrayKeys, int numArrayKeys)
TIDBitmap * biss_result
Definition execnodes.h:1816
struct dsa_area * es_query_dsa
Definition execnodes.h:764
Definition nodes.h:135
EState * state
Definition execnodes.h:1179
TIDBitmap * tbm_create(Size maxbytes, dsa_area *dsa)
Definition tidbitmap.c:256

References BitmapIndexScanState::biss_ArrayKeys, BitmapIndexScanState::biss_NumArrayKeys, BitmapIndexScanState::biss_NumRuntimeKeys, BitmapIndexScanState::biss_NumScanKeys, BitmapIndexScanState::biss_result, BitmapIndexScanState::biss_RuntimeKeysReady, BitmapIndexScanState::biss_ScanDesc, BitmapIndexScanState::biss_ScanKeys, CHECK_FOR_INTERRUPTS, EState::es_query_dsa, ExecIndexAdvanceArrayKeys(), ExecReScan(), fb(), index_getbitmap(), index_rescan(), InstrStartNode(), InstrStopNode(), PlanState::instrument, PlanState::plan, ScanState::ps, BitmapIndexScanState::ss, PlanState::state, tbm_create(), and work_mem.

Referenced by MultiExecProcNode().