PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
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 
)

Definition at line 353 of file nodeBitmapIndexscan.c.

354{
355 Size size;
356
357 /*
358 * Parallel bitmap index scans are not supported, but we still need to
359 * store the scan's instrumentation in DSM during parallel query
360 */
361 if (!node->ss.ps.instrument || pcxt->nworkers == 0)
362 return;
363
364 size = offsetof(SharedIndexScanInstrumentation, winstrument) +
365 pcxt->nworkers * sizeof(IndexScanInstrumentation);
366 shm_toc_estimate_chunk(&pcxt->estimator, size);
368}
size_t Size
Definition: c.h:576
struct IndexScanInstrumentation IndexScanInstrumentation
#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:41
Instrumentation * instrument
Definition: execnodes.h:1169
PlanState ps
Definition: execnodes.h:1615

References ParallelContext::estimator, 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 
)

Definition at line 377 of file nodeBitmapIndexscan.c.

379{
380 Size size;
381
382 /* don't need this if not instrumenting or no workers */
383 if (!node->ss.ps.instrument || pcxt->nworkers == 0)
384 return;
385
386 size = offsetof(SharedIndexScanInstrumentation, winstrument) +
387 pcxt->nworkers * sizeof(IndexScanInstrumentation);
388 node->biss_SharedInfo =
390 size);
391 shm_toc_insert(pcxt->toc, node->ss.ps.plan->plan_node_id,
392 node->biss_SharedInfo);
393
394 /* Each per-worker area must start out as zeroes */
395 memset(node->biss_SharedInfo, 0, size);
396 node->biss_SharedInfo->num_workers = pcxt->nworkers;
397}
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:1810
shm_toc * toc
Definition: parallel.h:44
Plan * plan
Definition: execnodes.h:1159
int plan_node_id
Definition: plannodes.h:207

References BitmapIndexScanState::biss_SharedInfo, 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 
)

Definition at line 406 of file nodeBitmapIndexscan.c.

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

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

Referenced by ExecParallelInitializeWorker().

◆ ExecBitmapIndexScanRetrieveInstrumentation()

void ExecBitmapIndexScanRetrieveInstrumentation ( BitmapIndexScanState node)

Definition at line 424 of file nodeBitmapIndexscan.c.

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

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

Referenced by ExecParallelRetrieveInstrumentation().

◆ ExecEndBitmapIndexScan()

void ExecEndBitmapIndexScan ( BitmapIndexScanState node)

Definition at line 175 of file nodeBitmapIndexscan.c.

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

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

Referenced by ExecEndNode().

◆ ExecInitBitmapIndexScan()

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

Definition at line 223 of file nodeBitmapIndexscan.c.

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

References Assert(), BitmapIndexScanState::biss_ArrayKeys, BitmapIndexScanState::biss_Instrument, BitmapIndexScanState::biss_NumArrayKeys, BitmapIndexScanState::biss_NumRuntimeKeys, BitmapIndexScanState::biss_NumScanKeys, BitmapIndexScanState::biss_RelationDesc, BitmapIndexScanState::biss_result, BitmapIndexScanState::biss_RuntimeContext, BitmapIndexScanState::biss_RuntimeKeys, BitmapIndexScanState::biss_RuntimeKeysReady, BitmapIndexScanState::biss_ScanDesc, BitmapIndexScanState::biss_ScanKeys, EState::es_snapshot, EXEC_FLAG_BACKWARD, EXEC_FLAG_EXPLAIN_ONLY, EXEC_FLAG_MARK, exec_rt_fetch(), ExecAssignExprContext(), ExecBitmapIndexScan(), ExecIndexBuildScanKeys(), PlanState::ExecProcNode, index_beginscan_bitmap(), index_open(), index_rescan(), BitmapIndexScan::indexid, BitmapIndexScan::indexqual, makeNode, PlanState::plan, ScanState::ps, PlanState::ps_ExprContext, BitmapIndexScan::scan, Scan::scanrelid, BitmapIndexScanState::ss, ScanState::ss_currentRelation, ScanState::ss_currentScanDesc, and PlanState::state.

Referenced by ExecInitNode().

◆ ExecReScanBitmapIndexScan()

void ExecReScanBitmapIndexScan ( BitmapIndexScanState node)

Definition at line 131 of file nodeBitmapIndexscan.c.

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

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(), index_rescan(), and ResetExprContext.

Referenced by ExecReScan().

◆ MultiExecBitmapIndexScan()

Node * MultiExecBitmapIndexScan ( BitmapIndexScanState node)

Definition at line 49 of file nodeBitmapIndexscan.c.

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

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(), index_getbitmap(), index_rescan(), InstrStartNode(), InstrStopNode(), PlanState::instrument, PlanState::plan, ScanState::ps, BitmapIndexScanState::ss, PlanState::state, tbm_create(), and work_mem.

Referenced by MultiExecProcNode().