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 160 of file nodeBitmapIndexscan.c.

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

Referenced by ExecEndNode().

161 {
162  Relation indexRelationDesc;
163  IndexScanDesc indexScanDesc;
164 
165  /*
166  * extract information from the node
167  */
168  indexRelationDesc = node->biss_RelationDesc;
169  indexScanDesc = node->biss_ScanDesc;
170 
171  /*
172  * Free the exprcontext ... now dead code, see ExecFreeExprContext
173  */
174 #ifdef NOT_USED
175  if (node->biss_RuntimeContext)
177 #endif
178 
179  /*
180  * close the index relation (no-op if we didn't open it)
181  */
182  if (indexScanDesc)
183  index_endscan(indexScanDesc);
184  if (indexRelationDesc)
185  index_close(indexRelationDesc, NoLock);
186 }
Relation biss_RelationDesc
Definition: execnodes.h:1463
#define NoLock
Definition: lockdefs.h:34
void index_endscan(IndexScanDesc scan)
Definition: indexam.c:340
IndexScanDesc biss_ScanDesc
Definition: execnodes.h:1464
void FreeExprContext(ExprContext *econtext, bool isCommit)
Definition: execUtils.c:339
void index_close(Relation relation, LOCKMODE lockmode)
Definition: indexam.c:176
ExprContext * biss_RuntimeContext
Definition: execnodes.h:1462
BitmapIndexScanState* ExecInitBitmapIndexScan ( BitmapIndexScan node,
EState estate,
int  eflags 
)

Definition at line 195 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(), ExecIndexBuildScanKeys(), ExecRelationIsTargetRelation(), index_beginscan_bitmap(), index_open(), index_rescan(), BitmapIndexScan::indexid, BitmapIndexScan::indexqual, makeNode, NoLock, NULL, 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().

196 {
197  BitmapIndexScanState *indexstate;
198  bool relistarget;
199 
200  /* check for unsupported flags */
201  Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK)));
202 
203  /*
204  * create state structure
205  */
206  indexstate = makeNode(BitmapIndexScanState);
207  indexstate->ss.ps.plan = (Plan *) node;
208  indexstate->ss.ps.state = estate;
209 
210  /* normally we don't make the result bitmap till runtime */
211  indexstate->biss_result = NULL;
212 
213  /*
214  * Miscellaneous initialization
215  *
216  * We do not need a standard exprcontext for this node, though we may
217  * decide below to create a runtime-key exprcontext
218  */
219 
220  /*
221  * initialize child expressions
222  *
223  * We don't need to initialize targetlist or qual since neither are used.
224  *
225  * Note: we don't initialize all of the indexqual expression, only the
226  * sub-parts corresponding to runtime keys (see below).
227  */
228 
229  /*
230  * We do not open or lock the base relation here. We assume that an
231  * ancestor BitmapHeapScan node is holding AccessShareLock (or better) on
232  * the heap relation throughout the execution of the plan tree.
233  */
234 
235  indexstate->ss.ss_currentRelation = NULL;
236  indexstate->ss.ss_currentScanDesc = NULL;
237 
238  /*
239  * If we are just doing EXPLAIN (ie, aren't going to run the plan), stop
240  * here. This allows an index-advisor plugin to EXPLAIN a plan containing
241  * references to nonexistent indexes.
242  */
243  if (eflags & EXEC_FLAG_EXPLAIN_ONLY)
244  return indexstate;
245 
246  /*
247  * Open the index relation.
248  *
249  * If the parent table is one of the target relations of the query, then
250  * InitPlan already opened and write-locked the index, so we can avoid
251  * taking another lock here. Otherwise we need a normal reader's lock.
252  */
253  relistarget = ExecRelationIsTargetRelation(estate, node->scan.scanrelid);
254  indexstate->biss_RelationDesc = index_open(node->indexid,
255  relistarget ? NoLock : AccessShareLock);
256 
257  /*
258  * Initialize index-specific scan state
259  */
260  indexstate->biss_RuntimeKeysReady = false;
261  indexstate->biss_RuntimeKeys = NULL;
262  indexstate->biss_NumRuntimeKeys = 0;
263 
264  /*
265  * build the index scan keys from the index qualification
266  */
267  ExecIndexBuildScanKeys((PlanState *) indexstate,
268  indexstate->biss_RelationDesc,
269  node->indexqual,
270  false,
271  &indexstate->biss_ScanKeys,
272  &indexstate->biss_NumScanKeys,
273  &indexstate->biss_RuntimeKeys,
274  &indexstate->biss_NumRuntimeKeys,
275  &indexstate->biss_ArrayKeys,
276  &indexstate->biss_NumArrayKeys);
277 
278  /*
279  * If we have runtime keys or array keys, we need an ExprContext to
280  * evaluate them. We could just create a "standard" plan node exprcontext,
281  * but to keep the code looking similar to nodeIndexscan.c, it seems
282  * better to stick with the approach of using a separate ExprContext.
283  */
284  if (indexstate->biss_NumRuntimeKeys != 0 ||
285  indexstate->biss_NumArrayKeys != 0)
286  {
287  ExprContext *stdecontext = indexstate->ss.ps.ps_ExprContext;
288 
289  ExecAssignExprContext(estate, &indexstate->ss.ps);
290  indexstate->biss_RuntimeContext = indexstate->ss.ps.ps_ExprContext;
291  indexstate->ss.ps.ps_ExprContext = stdecontext;
292  }
293  else
294  {
295  indexstate->biss_RuntimeContext = NULL;
296  }
297 
298  /*
299  * Initialize scan descriptor.
300  */
301  indexstate->biss_ScanDesc =
303  estate->es_snapshot,
304  indexstate->biss_NumScanKeys);
305 
306  /*
307  * If no run-time keys to calculate, go ahead and pass the scankeys to the
308  * index AM.
309  */
310  if (indexstate->biss_NumRuntimeKeys == 0 &&
311  indexstate->biss_NumArrayKeys == 0)
312  index_rescan(indexstate->biss_ScanDesc,
313  indexstate->biss_ScanKeys, indexstate->biss_NumScanKeys,
314  NULL, 0);
315 
316  /*
317  * all done.
318  */
319  return indexstate;
320 }
IndexScanDesc index_beginscan_bitmap(Relation indexRelation, Snapshot snapshot, int nkeys)
Definition: indexam.c:247
IndexRuntimeKeyInfo * biss_RuntimeKeys
Definition: execnodes.h:1457
Index scanrelid
Definition: plannodes.h:306
ExprContext * ps_ExprContext
Definition: execnodes.h:1078
List * indexqual
Definition: plannodes.h:423
Relation biss_RelationDesc
Definition: execnodes.h:1463
#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:370
Relation ss_currentRelation
Definition: execnodes.h:1289
EState * state
Definition: execnodes.h:1049
PlanState ps
Definition: execnodes.h:1288
#define EXEC_FLAG_BACKWARD
Definition: executor.h:60
#define NoLock
Definition: lockdefs.h:34
IndexScanDesc biss_ScanDesc
Definition: execnodes.h:1464
TIDBitmap * biss_result
Definition: execnodes.h:1454
Plan * plan
Definition: execnodes.h:1047
#define makeNode(_type_)
Definition: nodes.h:556
#define NULL
Definition: c.h:226
#define Assert(condition)
Definition: c.h:671
#define EXEC_FLAG_MARK
Definition: executor.h:61
void ExecAssignExprContext(EState *estate, PlanState *planstate)
Definition: execUtils.c:408
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:1290
IndexArrayKeyInfo * biss_ArrayKeys
Definition: execnodes.h:1459
ExprContext * biss_RuntimeContext
Definition: execnodes.h:1462
#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:746
void ExecReScanBitmapIndexScan ( BitmapIndexScanState node)

Definition at line 116 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(), NULL, and ResetExprContext.

Referenced by ExecReScan().

117 {
118  ExprContext *econtext = node->biss_RuntimeContext;
119 
120  /*
121  * Reset the runtime-key context so we don't leak memory as each outer
122  * tuple is scanned. Note this assumes that we will recalculate *all*
123  * runtime keys on each call.
124  */
125  if (econtext)
126  ResetExprContext(econtext);
127 
128  /*
129  * If we are doing runtime key calculations (ie, any of the index key
130  * values weren't simple Consts), compute the new key values.
131  *
132  * Array keys are also treated as runtime keys; note that if we return
133  * with biss_RuntimeKeysReady still false, then there is an empty array
134  * key so no index scan is needed.
135  */
136  if (node->biss_NumRuntimeKeys != 0)
137  ExecIndexEvalRuntimeKeys(econtext,
138  node->biss_RuntimeKeys,
139  node->biss_NumRuntimeKeys);
140  if (node->biss_NumArrayKeys != 0)
141  node->biss_RuntimeKeysReady =
142  ExecIndexEvalArrayKeys(econtext,
143  node->biss_ArrayKeys,
144  node->biss_NumArrayKeys);
145  else
146  node->biss_RuntimeKeysReady = true;
147 
148  /* reset index scan */
149  if (node->biss_RuntimeKeysReady)
151  node->biss_ScanKeys, node->biss_NumScanKeys,
152  NULL, 0);
153 }
IndexRuntimeKeyInfo * biss_RuntimeKeys
Definition: execnodes.h:1457
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:1464
#define NULL
Definition: c.h:226
void ExecIndexEvalRuntimeKeys(ExprContext *econtext, IndexRuntimeKeyInfo *runtimeKeys, int numRuntimeKeys)
IndexArrayKeyInfo * biss_ArrayKeys
Definition: execnodes.h:1459
ExprContext * biss_RuntimeContext
Definition: execnodes.h:1462
#define ResetExprContext(econtext)
Definition: executor.h:332
Node* MultiExecBitmapIndexScan ( BitmapIndexScanState node)

Definition at line 36 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, ExecIndexAdvanceArrayKeys(), ExecReScan(), index_getbitmap(), index_rescan(), InstrStartNode(), InstrStopNode(), PlanState::instrument, NULL, ScanState::ps, BitmapIndexScanState::ss, tbm_create(), and work_mem.

Referenced by MultiExecProcNode().

37 {
38  TIDBitmap *tbm;
39  IndexScanDesc scandesc;
40  double nTuples = 0;
41  bool doscan;
42 
43  /* must provide our own instrumentation support */
44  if (node->ss.ps.instrument)
46 
47  /*
48  * extract necessary information from index scan node
49  */
50  scandesc = node->biss_ScanDesc;
51 
52  /*
53  * If we have runtime keys and they've not already been set up, do it now.
54  * Array keys are also treated as runtime keys; note that if ExecReScan
55  * returns with biss_RuntimeKeysReady still false, then there is an empty
56  * array key so we should do nothing.
57  */
58  if (!node->biss_RuntimeKeysReady &&
59  (node->biss_NumRuntimeKeys != 0 || node->biss_NumArrayKeys != 0))
60  {
61  ExecReScan((PlanState *) node);
62  doscan = node->biss_RuntimeKeysReady;
63  }
64  else
65  doscan = true;
66 
67  /*
68  * Prepare the result bitmap. Normally we just create a new one to pass
69  * back; however, our parent node is allowed to store a pre-made one into
70  * node->biss_result, in which case we just OR our tuple IDs into the
71  * existing bitmap. (This saves needing explicit UNION steps.)
72  */
73  if (node->biss_result)
74  {
75  tbm = node->biss_result;
76  node->biss_result = NULL; /* reset for next time */
77  }
78  else
79  {
80  /* XXX should we use less than work_mem for this? */
81  tbm = tbm_create(work_mem * 1024L);
82  }
83 
84  /*
85  * Get TIDs from index and insert into bitmap
86  */
87  while (doscan)
88  {
89  nTuples += (double) index_getbitmap(scandesc, tbm);
90 
92 
94  node->biss_NumArrayKeys);
95  if (doscan) /* reset index scan */
97  node->biss_ScanKeys, node->biss_NumScanKeys,
98  NULL, 0);
99  }
100 
101  /* must provide our own instrumentation support */
102  if (node->ss.ps.instrument)
103  InstrStopNode(node->ss.ps.instrument, nTuples);
104 
105  return (Node *) tbm;
106 }
void InstrStopNode(Instrumentation *instr, double nTuples)
Definition: instrument.c:80
Instrumentation * instrument
Definition: execnodes.h:1053
bool ExecIndexAdvanceArrayKeys(IndexArrayKeyInfo *arrayKeys, int numArrayKeys)
void ExecReScan(PlanState *node)
Definition: execAmi.c:73
void index_rescan(IndexScanDesc scan, ScanKey keys, int nkeys, ScanKey orderbys, int norderbys)
Definition: indexam.c:310
Definition: nodes.h:508
PlanState ps
Definition: execnodes.h:1288
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:1464
int work_mem
Definition: globals.c:112
TIDBitmap * biss_result
Definition: execnodes.h:1454
#define NULL
Definition: c.h:226
TIDBitmap * tbm_create(long maxbytes)
Definition: tidbitmap.c:210
IndexArrayKeyInfo * biss_ArrayKeys
Definition: execnodes.h:1459
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:97