PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
nodeBitmapIndexscan.c File Reference
#include "postgres.h"
#include "access/genam.h"
#include "executor/executor.h"
#include "executor/nodeBitmapIndexscan.h"
#include "executor/nodeIndexscan.h"
#include "miscadmin.h"
Include dependency graph for nodeBitmapIndexscan.c:

Go to the source code of this file.

Functions

static TupleTableSlotExecBitmapIndexScan (PlanState *pstate)
 
NodeMultiExecBitmapIndexScan (BitmapIndexScanState *node)
 
void ExecReScanBitmapIndexScan (BitmapIndexScanState *node)
 
void ExecEndBitmapIndexScan (BitmapIndexScanState *node)
 
BitmapIndexScanStateExecInitBitmapIndexScan (BitmapIndexScan *node, EState *estate, int eflags)
 

Function Documentation

◆ ExecBitmapIndexScan()

static TupleTableSlot * ExecBitmapIndexScan ( PlanState pstate)
static

Definition at line 38 of file nodeBitmapIndexscan.c.

39{
40 elog(ERROR, "BitmapIndexScan node does not support ExecProcNode call convention");
41 return NULL;
42}
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:225

References elog, and ERROR.

Referenced by ExecInitBitmapIndexScan().

◆ 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 * close the index relation (no-op if we didn't open it)
188 */
189 if (indexScanDesc)
190 index_endscan(indexScanDesc);
191 if (indexRelationDesc)
192 index_close(indexRelationDesc, NoLock);
193}
void index_close(Relation relation, LOCKMODE lockmode)
Definition: indexam.c:177
void index_endscan(IndexScanDesc scan)
Definition: indexam.c:378
#define NoLock
Definition: lockdefs.h:34
struct IndexScanDescData * biss_ScanDesc
Definition: execnodes.h:1756
Relation biss_RelationDesc
Definition: execnodes.h:1755

References BitmapIndexScanState::biss_RelationDesc, BitmapIndexScanState::biss_ScanDesc, index_close(), index_endscan(), and NoLock.

Referenced by ExecEndNode().

◆ ExecInitBitmapIndexScan()

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

Definition at line 202 of file nodeBitmapIndexscan.c.

203{
204 BitmapIndexScanState *indexstate;
205 LOCKMODE lockmode;
206
207 /* check for unsupported flags */
209
210 /*
211 * create state structure
212 */
213 indexstate = makeNode(BitmapIndexScanState);
214 indexstate->ss.ps.plan = (Plan *) node;
215 indexstate->ss.ps.state = estate;
217
218 /* normally we don't make the result bitmap till runtime */
219 indexstate->biss_result = NULL;
220
221 /*
222 * We do not open or lock the base relation here. We assume that an
223 * ancestor BitmapHeapScan node is holding AccessShareLock (or better) on
224 * the heap relation throughout the execution of the plan tree.
225 */
226
227 indexstate->ss.ss_currentRelation = NULL;
228 indexstate->ss.ss_currentScanDesc = NULL;
229
230 /*
231 * Miscellaneous initialization
232 *
233 * We do not need a standard exprcontext for this node, though we may
234 * decide below to create a runtime-key exprcontext
235 */
236
237 /*
238 * initialize child expressions
239 *
240 * We don't need to initialize targetlist or qual since neither are used.
241 *
242 * Note: we don't initialize all of the indexqual expression, only the
243 * sub-parts corresponding to runtime keys (see below).
244 */
245
246 /*
247 * If we are just doing EXPLAIN (ie, aren't going to run the plan), stop
248 * here. This allows an index-advisor plugin to EXPLAIN a plan containing
249 * references to nonexistent indexes.
250 */
251 if (eflags & EXEC_FLAG_EXPLAIN_ONLY)
252 return indexstate;
253
254 /* Open the index relation. */
255 lockmode = exec_rt_fetch(node->scan.scanrelid, estate)->rellockmode;
256 indexstate->biss_RelationDesc = index_open(node->indexid, lockmode);
257
258 /*
259 * Initialize index-specific scan state
260 */
261 indexstate->biss_RuntimeKeysReady = false;
262 indexstate->biss_RuntimeKeys = NULL;
263 indexstate->biss_NumRuntimeKeys = 0;
264
265 /*
266 * build the index scan keys from the index qualification
267 */
268 ExecIndexBuildScanKeys((PlanState *) indexstate,
269 indexstate->biss_RelationDesc,
270 node->indexqual,
271 false,
272 &indexstate->biss_ScanKeys,
273 &indexstate->biss_NumScanKeys,
274 &indexstate->biss_RuntimeKeys,
275 &indexstate->biss_NumRuntimeKeys,
276 &indexstate->biss_ArrayKeys,
277 &indexstate->biss_NumArrayKeys);
278
279 /*
280 * If we have runtime keys or array keys, we need an ExprContext to
281 * evaluate them. We could just create a "standard" plan node exprcontext,
282 * but to keep the code looking similar to nodeIndexscan.c, it seems
283 * better to stick with the approach of using a separate ExprContext.
284 */
285 if (indexstate->biss_NumRuntimeKeys != 0 ||
286 indexstate->biss_NumArrayKeys != 0)
287 {
288 ExprContext *stdecontext = indexstate->ss.ps.ps_ExprContext;
289
290 ExecAssignExprContext(estate, &indexstate->ss.ps);
291 indexstate->biss_RuntimeContext = indexstate->ss.ps.ps_ExprContext;
292 indexstate->ss.ps.ps_ExprContext = stdecontext;
293 }
294 else
295 {
296 indexstate->biss_RuntimeContext = NULL;
297 }
298
299 /*
300 * Initialize scan descriptor.
301 */
302 indexstate->biss_ScanDesc =
304 estate->es_snapshot,
305 indexstate->biss_NumScanKeys);
306
307 /*
308 * If no run-time keys to calculate, go ahead and pass the scankeys to the
309 * index AM.
310 */
311 if (indexstate->biss_NumRuntimeKeys == 0 &&
312 indexstate->biss_NumArrayKeys == 0)
313 index_rescan(indexstate->biss_ScanDesc,
314 indexstate->biss_ScanKeys, indexstate->biss_NumScanKeys,
315 NULL, 0);
316
317 /*
318 * all done.
319 */
320 return indexstate;
321}
#define Assert(condition)
Definition: c.h:812
void ExecAssignExprContext(EState *estate, PlanState *planstate)
Definition: execUtils.c:485
#define EXEC_FLAG_BACKWARD
Definition: executor.h:68
static RangeTblEntry * exec_rt_fetch(Index rti, EState *estate)
Definition: executor.h:603
#define EXEC_FLAG_EXPLAIN_ONLY
Definition: executor.h:65
#define EXEC_FLAG_MARK
Definition: executor.h:69
IndexScanDesc index_beginscan_bitmap(Relation indexRelation, Snapshot snapshot, int nkeys)
Definition: indexam.c:287
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:352
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:155
ExprContext * biss_RuntimeContext
Definition: execnodes.h:1754
IndexRuntimeKeyInfo * biss_RuntimeKeys
Definition: execnodes.h:1749
TIDBitmap * biss_result
Definition: execnodes.h:1746
struct ScanKeyData * biss_ScanKeys
Definition: execnodes.h:1747
List * indexqual
Definition: plannodes.h:526
Snapshot es_snapshot
Definition: execnodes.h:632
Plan * plan
Definition: execnodes.h:1126
EState * state
Definition: execnodes.h:1128
ExprContext * ps_ExprContext
Definition: execnodes.h:1165
ExecProcNodeMtd ExecProcNode
Definition: execnodes.h:1132
Relation ss_currentRelation
Definition: execnodes.h:1574
PlanState ps
Definition: execnodes.h:1573
struct TableScanDescData * ss_currentScanDesc
Definition: execnodes.h:1575
Index scanrelid
Definition: plannodes.h:390

References Assert, BitmapIndexScanState::biss_ArrayKeys, 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:557
bool ExecIndexEvalArrayKeys(ExprContext *econtext, IndexArrayKeyInfo *arrayKeys, int numArrayKeys)
void ExecIndexEvalRuntimeKeys(ExprContext *econtext, IndexRuntimeKeyInfo *runtimeKeys, int numRuntimeKeys)
IndexArrayKeyInfo * biss_ArrayKeys
Definition: execnodes.h:1751

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 * 1024L,
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:76
int work_mem
Definition: globals.c:130
int64 index_getbitmap(IndexScanDesc scan, TIDBitmap *bitmap)
Definition: indexam.c:720
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:122
bool ExecIndexAdvanceArrayKeys(IndexArrayKeyInfo *arrayKeys, int numArrayKeys)
struct dsa_area * es_query_dsa
Definition: execnodes.h:717
Definition: nodes.h:129
Instrumentation * instrument
Definition: execnodes.h:1136
TIDBitmap * tbm_create(long maxbytes, dsa_area *dsa)
Definition: tidbitmap.c:266

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().