PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
nodeBitmapIndexscan.h File Reference
#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)
 

Function Documentation

void ExecEndBitmapIndexScan ( BitmapIndexScanState node)

Definition at line 175 of file nodeBitmapIndexscan.c.

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

Referenced by ExecEndNode().

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  * Free the exprcontext ... now dead code, see ExecFreeExprContext
188  */
189 #ifdef NOT_USED
190  if (node->biss_RuntimeContext)
192 #endif
193 
194  /*
195  * close the index relation (no-op if we didn't open it)
196  */
197  if (indexScanDesc)
198  index_endscan(indexScanDesc);
199  if (indexRelationDesc)
200  index_close(indexRelationDesc, NoLock);
201 }
Relation biss_RelationDesc
Definition: execnodes.h:1276
#define NoLock
Definition: lockdefs.h:34
void index_endscan(IndexScanDesc scan)
Definition: indexam.c:340
IndexScanDesc biss_ScanDesc
Definition: execnodes.h:1277
void FreeExprContext(ExprContext *econtext, bool isCommit)
Definition: execUtils.c:354
void index_close(Relation relation, LOCKMODE lockmode)
Definition: indexam.c:176
ExprContext * biss_RuntimeContext
Definition: execnodes.h:1275
BitmapIndexScanState* ExecInitBitmapIndexScan ( BitmapIndexScan node,
EState estate,
int  eflags 
)

Definition at line 210 of file nodeBitmapIndexscan.c.

References AccessShareLock, 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, ExecAssignExprContext(), ExecBitmapIndexScan(), ExecIndexBuildScanKeys(), PlanState::ExecProcNode, ExecRelationIsTargetRelation(), index_beginscan_bitmap(), index_open(), index_rescan(), BitmapIndexScan::indexid, BitmapIndexScan::indexqual, makeNode, NoLock, 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().

211 {
212  BitmapIndexScanState *indexstate;
213  bool relistarget;
214 
215  /* check for unsupported flags */
216  Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK)));
217 
218  /*
219  * create state structure
220  */
221  indexstate = makeNode(BitmapIndexScanState);
222  indexstate->ss.ps.plan = (Plan *) node;
223  indexstate->ss.ps.state = estate;
224  indexstate->ss.ps.ExecProcNode = ExecBitmapIndexScan;
225 
226  /* normally we don't make the result bitmap till runtime */
227  indexstate->biss_result = NULL;
228 
229  /*
230  * Miscellaneous initialization
231  *
232  * We do not need a standard exprcontext for this node, though we may
233  * decide below to create a runtime-key exprcontext
234  */
235 
236  /*
237  * initialize child expressions
238  *
239  * We don't need to initialize targetlist or qual since neither are used.
240  *
241  * Note: we don't initialize all of the indexqual expression, only the
242  * sub-parts corresponding to runtime keys (see below).
243  */
244 
245  /*
246  * We do not open or lock the base relation here. We assume that an
247  * ancestor BitmapHeapScan node is holding AccessShareLock (or better) on
248  * the heap relation throughout the execution of the plan tree.
249  */
250 
251  indexstate->ss.ss_currentRelation = NULL;
252  indexstate->ss.ss_currentScanDesc = NULL;
253 
254  /*
255  * If we are just doing EXPLAIN (ie, aren't going to run the plan), stop
256  * here. This allows an index-advisor plugin to EXPLAIN a plan containing
257  * references to nonexistent indexes.
258  */
259  if (eflags & EXEC_FLAG_EXPLAIN_ONLY)
260  return indexstate;
261 
262  /*
263  * Open the index relation.
264  *
265  * If the parent table is one of the target relations of the query, then
266  * InitPlan already opened and write-locked the index, so we can avoid
267  * taking another lock here. Otherwise we need a normal reader's lock.
268  */
269  relistarget = ExecRelationIsTargetRelation(estate, node->scan.scanrelid);
270  indexstate->biss_RelationDesc = index_open(node->indexid,
271  relistarget ? NoLock : AccessShareLock);
272 
273  /*
274  * Initialize index-specific scan state
275  */
276  indexstate->biss_RuntimeKeysReady = false;
277  indexstate->biss_RuntimeKeys = NULL;
278  indexstate->biss_NumRuntimeKeys = 0;
279 
280  /*
281  * build the index scan keys from the index qualification
282  */
283  ExecIndexBuildScanKeys((PlanState *) indexstate,
284  indexstate->biss_RelationDesc,
285  node->indexqual,
286  false,
287  &indexstate->biss_ScanKeys,
288  &indexstate->biss_NumScanKeys,
289  &indexstate->biss_RuntimeKeys,
290  &indexstate->biss_NumRuntimeKeys,
291  &indexstate->biss_ArrayKeys,
292  &indexstate->biss_NumArrayKeys);
293 
294  /*
295  * If we have runtime keys or array keys, we need an ExprContext to
296  * evaluate them. We could just create a "standard" plan node exprcontext,
297  * but to keep the code looking similar to nodeIndexscan.c, it seems
298  * better to stick with the approach of using a separate ExprContext.
299  */
300  if (indexstate->biss_NumRuntimeKeys != 0 ||
301  indexstate->biss_NumArrayKeys != 0)
302  {
303  ExprContext *stdecontext = indexstate->ss.ps.ps_ExprContext;
304 
305  ExecAssignExprContext(estate, &indexstate->ss.ps);
306  indexstate->biss_RuntimeContext = indexstate->ss.ps.ps_ExprContext;
307  indexstate->ss.ps.ps_ExprContext = stdecontext;
308  }
309  else
310  {
311  indexstate->biss_RuntimeContext = NULL;
312  }
313 
314  /*
315  * Initialize scan descriptor.
316  */
317  indexstate->biss_ScanDesc =
319  estate->es_snapshot,
320  indexstate->biss_NumScanKeys);
321 
322  /*
323  * If no run-time keys to calculate, go ahead and pass the scankeys to the
324  * index AM.
325  */
326  if (indexstate->biss_NumRuntimeKeys == 0 &&
327  indexstate->biss_NumArrayKeys == 0)
328  index_rescan(indexstate->biss_ScanDesc,
329  indexstate->biss_ScanKeys, indexstate->biss_NumScanKeys,
330  NULL, 0);
331 
332  /*
333  * all done.
334  */
335  return indexstate;
336 }
IndexScanDesc index_beginscan_bitmap(Relation indexRelation, Snapshot snapshot, int nkeys)
Definition: indexam.c:247
IndexRuntimeKeyInfo * biss_RuntimeKeys
Definition: execnodes.h:1270
Index scanrelid
Definition: plannodes.h:329
ExprContext * ps_ExprContext
Definition: execnodes.h:881
List * indexqual
Definition: plannodes.h:447
Relation biss_RelationDesc
Definition: execnodes.h:1276
#define AccessShareLock
Definition: lockdefs.h:36
void index_rescan(IndexScanDesc scan, ScanKey keys, int nkeys, ScanKey orderbys, int norderbys)
Definition: indexam.c:310
Snapshot es_snapshot
Definition: execnodes.h:429
Relation ss_currentRelation
Definition: execnodes.h:1102
EState * state
Definition: execnodes.h:849
PlanState ps
Definition: execnodes.h:1101
#define EXEC_FLAG_BACKWARD
Definition: executor.h:60
#define NoLock
Definition: lockdefs.h:34
ExecProcNodeMtd ExecProcNode
Definition: execnodes.h:853
IndexScanDesc biss_ScanDesc
Definition: execnodes.h:1277
TIDBitmap * biss_result
Definition: execnodes.h:1267
Plan * plan
Definition: execnodes.h:847
#define makeNode(_type_)
Definition: nodes.h:558
#define Assert(condition)
Definition: c.h:681
#define EXEC_FLAG_MARK
Definition: executor.h:61
static TupleTableSlot * ExecBitmapIndexScan(PlanState *pstate)
void ExecAssignExprContext(EState *estate, PlanState *planstate)
Definition: execUtils.c:423
void ExecIndexBuildScanKeys(PlanState *planstate, Relation index, List *quals, bool isorderby, ScanKey *scanKeys, int *numScanKeys, IndexRuntimeKeyInfo **runtimeKeys, int *numRuntimeKeys, IndexArrayKeyInfo **arrayKeys, int *numArrayKeys)
HeapScanDesc ss_currentScanDesc
Definition: execnodes.h:1103
IndexArrayKeyInfo * biss_ArrayKeys
Definition: execnodes.h:1272
ExprContext * biss_RuntimeContext
Definition: execnodes.h:1275
#define EXEC_FLAG_EXPLAIN_ONLY
Definition: executor.h:58
Relation index_open(Oid relationId, LOCKMODE lockmode)
Definition: indexam.c:151
bool ExecRelationIsTargetRelation(EState *estate, Index scanrelid)
Definition: execUtils.c:582
void ExecReScanBitmapIndexScan ( BitmapIndexScanState node)

Definition at line 131 of file nodeBitmapIndexscan.c.

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

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)
152  ExecIndexEvalRuntimeKeys(econtext,
153  node->biss_RuntimeKeys,
154  node->biss_NumRuntimeKeys);
155  if (node->biss_NumArrayKeys != 0)
156  node->biss_RuntimeKeysReady =
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 }
IndexRuntimeKeyInfo * biss_RuntimeKeys
Definition: execnodes.h:1270
void index_rescan(IndexScanDesc scan, ScanKey keys, int nkeys, ScanKey orderbys, int norderbys)
Definition: indexam.c:310
bool ExecIndexEvalArrayKeys(ExprContext *econtext, IndexArrayKeyInfo *arrayKeys, int numArrayKeys)
IndexScanDesc biss_ScanDesc
Definition: execnodes.h:1277
void ExecIndexEvalRuntimeKeys(ExprContext *econtext, IndexRuntimeKeyInfo *runtimeKeys, int numRuntimeKeys)
IndexArrayKeyInfo * biss_ArrayKeys
Definition: execnodes.h:1272
ExprContext * biss_RuntimeContext
Definition: execnodes.h:1275
#define ResetExprContext(econtext)
Definition: executor.h:471
Node* MultiExecBitmapIndexScan ( BitmapIndexScanState node)

Definition at line 49 of file nodeBitmapIndexscan.c.

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

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 InstrStopNode(Instrumentation *instr, double nTuples)
Definition: instrument.c:80
struct dsa_area * es_query_dsa
Definition: execnodes.h:511
Instrumentation * instrument
Definition: execnodes.h:857
TIDBitmap * tbm_create(long maxbytes, dsa_area *dsa)
Definition: tidbitmap.c:265
bool ExecIndexAdvanceArrayKeys(IndexArrayKeyInfo *arrayKeys, int numArrayKeys)
void ExecReScan(PlanState *node)
Definition: execAmi.c:76
void index_rescan(IndexScanDesc scan, ScanKey keys, int nkeys, ScanKey orderbys, int norderbys)
Definition: indexam.c:310
Definition: nodes.h:510
EState * state
Definition: execnodes.h:849
PlanState ps
Definition: execnodes.h:1101
void InstrStartNode(Instrumentation *instr)
Definition: instrument.c:63
int64 index_getbitmap(IndexScanDesc scan, TIDBitmap *bitmap)
Definition: indexam.c:713
IndexScanDesc biss_ScanDesc
Definition: execnodes.h:1277
int work_mem
Definition: globals.c:113
TIDBitmap * biss_result
Definition: execnodes.h:1267
Plan * plan
Definition: execnodes.h:847
IndexArrayKeyInfo * biss_ArrayKeys
Definition: execnodes.h:1272
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:98