Fix pg_dump bug in the database-level collation patch. "datcollate" and
[PostgreSQL.git] / src / backend / executor / nodeBitmapIndexscan.c
blob30f0e158de3f9fac7be13f516b98e8da94cbb668
1 /*-------------------------------------------------------------------------
3 * nodeBitmapIndexscan.c
4 * Routines to support bitmapped index scans of relations
6 * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
10 * IDENTIFICATION
11 * $PostgreSQL$
13 *-------------------------------------------------------------------------
16 * INTERFACE ROUTINES
17 * MultiExecBitmapIndexScan scans a relation using index.
18 * ExecInitBitmapIndexScan creates and initializes state info.
19 * ExecBitmapIndexReScan prepares to rescan the plan.
20 * ExecEndBitmapIndexScan releases all storage.
22 #include "postgres.h"
24 #include "access/genam.h"
25 #include "executor/execdebug.h"
26 #include "executor/instrument.h"
27 #include "executor/nodeBitmapIndexscan.h"
28 #include "executor/nodeIndexscan.h"
29 #include "miscadmin.h"
30 #include "utils/memutils.h"
33 /* ----------------------------------------------------------------
34 * MultiExecBitmapIndexScan(node)
35 * ----------------------------------------------------------------
37 Node *
38 MultiExecBitmapIndexScan(BitmapIndexScanState *node)
40 TIDBitmap *tbm;
41 IndexScanDesc scandesc;
42 double nTuples = 0;
43 bool doscan;
45 /* must provide our own instrumentation support */
46 if (node->ss.ps.instrument)
47 InstrStartNode(node->ss.ps.instrument);
50 * extract necessary information from index scan node
52 scandesc = node->biss_ScanDesc;
55 * If we have runtime keys and they've not already been set up, do it now.
56 * Array keys are also treated as runtime keys; note that if ExecReScan
57 * returns with biss_RuntimeKeysReady still false, then there is an empty
58 * array key so we should do nothing.
60 if (!node->biss_RuntimeKeysReady &&
61 (node->biss_NumRuntimeKeys != 0 || node->biss_NumArrayKeys != 0))
63 ExecReScan((PlanState *) node, NULL);
64 doscan = node->biss_RuntimeKeysReady;
66 else
67 doscan = true;
70 * Prepare the result bitmap. Normally we just create a new one to pass
71 * back; however, our parent node is allowed to store a pre-made one into
72 * node->biss_result, in which case we just OR our tuple IDs into the
73 * existing bitmap. (This saves needing explicit UNION steps.)
75 if (node->biss_result)
77 tbm = node->biss_result;
78 node->biss_result = NULL; /* reset for next time */
80 else
82 /* XXX should we use less than work_mem for this? */
83 tbm = tbm_create(work_mem * 1024L);
87 * Get TIDs from index and insert into bitmap
89 while (doscan)
91 nTuples += (double) index_getbitmap(scandesc, tbm);
93 CHECK_FOR_INTERRUPTS();
95 doscan = ExecIndexAdvanceArrayKeys(node->biss_ArrayKeys,
96 node->biss_NumArrayKeys);
97 if (doscan) /* reset index scan */
98 index_rescan(node->biss_ScanDesc, node->biss_ScanKeys);
101 /* must provide our own instrumentation support */
102 if (node->ss.ps.instrument)
103 InstrStopNode(node->ss.ps.instrument, nTuples);
105 return (Node *) tbm;
108 /* ----------------------------------------------------------------
109 * ExecBitmapIndexReScan(node)
111 * Recalculates the value of the scan keys whose value depends on
112 * information known at runtime and rescans the indexed relation.
113 * ----------------------------------------------------------------
115 void
116 ExecBitmapIndexReScan(BitmapIndexScanState *node, ExprContext *exprCtxt)
118 ExprContext *econtext;
120 econtext = node->biss_RuntimeContext; /* context for runtime keys */
122 if (econtext)
125 * If we are being passed an outer tuple, save it for runtime key
126 * calc.
128 if (exprCtxt != NULL)
129 econtext->ecxt_outertuple = exprCtxt->ecxt_outertuple;
132 * Reset the runtime-key context so we don't leak memory as each outer
133 * tuple is scanned. Note this assumes that we will recalculate *all*
134 * runtime keys on each call.
136 ResetExprContext(econtext);
140 * If we are doing runtime key calculations (ie, the index keys depend on
141 * data from an outer scan), compute the new key values.
143 * Array keys are also treated as runtime keys; note that if we return
144 * with biss_RuntimeKeysReady still false, then there is an empty array
145 * key so no index scan is needed.
147 if (node->biss_NumRuntimeKeys != 0)
148 ExecIndexEvalRuntimeKeys(econtext,
149 node->biss_RuntimeKeys,
150 node->biss_NumRuntimeKeys);
151 if (node->biss_NumArrayKeys != 0)
152 node->biss_RuntimeKeysReady =
153 ExecIndexEvalArrayKeys(econtext,
154 node->biss_ArrayKeys,
155 node->biss_NumArrayKeys);
156 else
157 node->biss_RuntimeKeysReady = true;
159 /* reset index scan */
160 if (node->biss_RuntimeKeysReady)
161 index_rescan(node->biss_ScanDesc, node->biss_ScanKeys);
164 /* ----------------------------------------------------------------
165 * ExecEndBitmapIndexScan
166 * ----------------------------------------------------------------
168 void
169 ExecEndBitmapIndexScan(BitmapIndexScanState *node)
171 Relation indexRelationDesc;
172 IndexScanDesc indexScanDesc;
175 * extract information from the node
177 indexRelationDesc = node->biss_RelationDesc;
178 indexScanDesc = node->biss_ScanDesc;
181 * Free the exprcontext ... now dead code, see ExecFreeExprContext
183 #ifdef NOT_USED
184 if (node->biss_RuntimeContext)
185 FreeExprContext(node->biss_RuntimeContext);
186 #endif
189 * close the index relation (no-op if we didn't open it)
191 if (indexScanDesc)
192 index_endscan(indexScanDesc);
193 if (indexRelationDesc)
194 index_close(indexRelationDesc, NoLock);
197 /* ----------------------------------------------------------------
198 * ExecInitBitmapIndexScan
200 * Initializes the index scan's state information.
201 * ----------------------------------------------------------------
203 BitmapIndexScanState *
204 ExecInitBitmapIndexScan(BitmapIndexScan *node, EState *estate, int eflags)
206 BitmapIndexScanState *indexstate;
207 bool relistarget;
209 /* check for unsupported flags */
210 Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK)));
213 * create state structure
215 indexstate = makeNode(BitmapIndexScanState);
216 indexstate->ss.ps.plan = (Plan *) node;
217 indexstate->ss.ps.state = estate;
219 /* normally we don't make the result bitmap till runtime */
220 indexstate->biss_result = NULL;
223 * Miscellaneous initialization
225 * We do not need a standard exprcontext for this node, though we may
226 * decide below to create a runtime-key exprcontext
230 * initialize child expressions
232 * We don't need to initialize targetlist or qual since neither are used.
234 * Note: we don't initialize all of the indexqual expression, only the
235 * sub-parts corresponding to runtime keys (see below).
238 #define BITMAPINDEXSCAN_NSLOTS 0
241 * We do not open or lock the base relation here. We assume that an
242 * ancestor BitmapHeapScan node is holding AccessShareLock (or better) on
243 * the heap relation throughout the execution of the plan tree.
246 indexstate->ss.ss_currentRelation = NULL;
247 indexstate->ss.ss_currentScanDesc = NULL;
250 * If we are just doing EXPLAIN (ie, aren't going to run the plan), stop
251 * here. This allows an index-advisor plugin to EXPLAIN a plan containing
252 * references to nonexistent indexes.
254 if (eflags & EXEC_FLAG_EXPLAIN_ONLY)
255 return indexstate;
258 * Open the index relation.
260 * If the parent table is one of the target relations of the query, then
261 * InitPlan already opened and write-locked the index, so we can avoid
262 * taking another lock here. Otherwise we need a normal reader's lock.
264 relistarget = ExecRelationIsTargetRelation(estate, node->scan.scanrelid);
265 indexstate->biss_RelationDesc = index_open(node->indexid,
266 relistarget ? NoLock : AccessShareLock);
269 * Initialize index-specific scan state
271 indexstate->biss_RuntimeKeysReady = false;
274 * build the index scan keys from the index qualification
276 ExecIndexBuildScanKeys((PlanState *) indexstate,
277 indexstate->biss_RelationDesc,
278 node->scan.scanrelid,
279 node->indexqual,
280 &indexstate->biss_ScanKeys,
281 &indexstate->biss_NumScanKeys,
282 &indexstate->biss_RuntimeKeys,
283 &indexstate->biss_NumRuntimeKeys,
284 &indexstate->biss_ArrayKeys,
285 &indexstate->biss_NumArrayKeys);
288 * If we have runtime keys or array keys, we need an ExprContext to
289 * evaluate them. We could just create a "standard" plan node exprcontext,
290 * but to keep the code looking similar to nodeIndexscan.c, it seems
291 * better to stick with the approach of using a separate ExprContext.
293 if (indexstate->biss_NumRuntimeKeys != 0 ||
294 indexstate->biss_NumArrayKeys != 0)
296 ExprContext *stdecontext = indexstate->ss.ps.ps_ExprContext;
298 ExecAssignExprContext(estate, &indexstate->ss.ps);
299 indexstate->biss_RuntimeContext = indexstate->ss.ps.ps_ExprContext;
300 indexstate->ss.ps.ps_ExprContext = stdecontext;
302 else
304 indexstate->biss_RuntimeContext = NULL;
308 * Initialize scan descriptor.
310 indexstate->biss_ScanDesc =
311 index_beginscan_bitmap(indexstate->biss_RelationDesc,
312 estate->es_snapshot,
313 indexstate->biss_NumScanKeys,
314 indexstate->biss_ScanKeys);
317 * all done.
319 return indexstate;
323 ExecCountSlotsBitmapIndexScan(BitmapIndexScan *node)
325 return ExecCountSlotsNode(outerPlan((Plan *) node)) +
326 ExecCountSlotsNode(innerPlan((Plan *) node)) + BITMAPINDEXSCAN_NSLOTS;