88 *
99 *
1010 * IDENTIFICATION
11- * $PostgreSQL: pgsql/src/backend/executor/nodeBitmapIndexscan.c,v 1.11 2005/11/22 18:17:10 momjian Exp $
11+ * $PostgreSQL: pgsql/src/backend/executor/nodeBitmapIndexscan.c,v 1.12 2005/11/25 19:47:49 tgl Exp $
1212 *
1313 *-------------------------------------------------------------------------
1414 */
@@ -43,6 +43,7 @@ MultiExecBitmapIndexScan(BitmapIndexScanState *node)
4343ItemPointerData tids [MAX_TIDS ];
4444int32 ntids ;
4545double nTuples = 0 ;
46+ bool doscan ;
4647
4748/* must provide our own instrumentation support */
4849if (node -> ss .ps .instrument )
@@ -55,9 +56,18 @@ MultiExecBitmapIndexScan(BitmapIndexScanState *node)
5556
5657/*
5758 * If we have runtime keys and they've not already been set up, do it now.
59+ * Array keys are also treated as runtime keys; note that if ExecReScan
60+ * returns with biss_RuntimeKeysReady still false, then there is an
61+ * empty array key so we should do nothing.
5862 */
59- if (node -> biss_RuntimeKeyInfo && !node -> biss_RuntimeKeysReady )
63+ if (!node -> biss_RuntimeKeysReady &&
64+ (node -> biss_NumRuntimeKeys != 0 || node -> biss_NumArrayKeys != 0 ))
65+ {
6066ExecReScan ((PlanState * )node ,NULL );
67+ doscan = node -> biss_RuntimeKeysReady ;
68+ }
69+ else
70+ doscan = true;
6171
6272/*
6373 * Prepare the result bitmap. Normally we just create a new one to pass
@@ -79,7 +89,7 @@ MultiExecBitmapIndexScan(BitmapIndexScanState *node)
7989/*
8090 * Get TIDs from index and insert into bitmap
8191 */
82- for (;; )
92+ while ( doscan )
8393{
8494bool more = index_getmulti (scandesc ,tids ,MAX_TIDS ,& ntids );
8595
@@ -89,10 +99,15 @@ MultiExecBitmapIndexScan(BitmapIndexScanState *node)
8999nTuples += ntids ;
90100}
91101
92- if (!more )
93- break ;
94-
95102CHECK_FOR_INTERRUPTS ();
103+
104+ if (!more )
105+ {
106+ doscan = ExecIndexAdvanceArrayKeys (node -> biss_ArrayKeys ,
107+ node -> biss_NumArrayKeys );
108+ if (doscan )/* reset index scan */
109+ index_rescan (node -> biss_ScanDesc ,node -> biss_ScanKeys );
110+ }
96111}
97112
98113/* must provide our own instrumentation support */
@@ -113,10 +128,8 @@ void
113128ExecBitmapIndexReScan (BitmapIndexScanState * node ,ExprContext * exprCtxt )
114129{
115130ExprContext * econtext ;
116- ExprState * * runtimeKeyInfo ;
117131
118132econtext = node -> biss_RuntimeContext ;/* context for runtime keys */
119- runtimeKeyInfo = node -> biss_RuntimeKeyInfo ;
120133
121134if (econtext )
122135{
@@ -137,19 +150,27 @@ ExecBitmapIndexReScan(BitmapIndexScanState *node, ExprContext *exprCtxt)
137150
138151/*
139152 * If we are doing runtime key calculations (ie, the index keys depend on
140- * data from an outer scan), compute the new key values
153+ * data from an outer scan), compute the new key values.
154+ *
155+ * Array keys are also treated as runtime keys; note that if we
156+ * return with biss_RuntimeKeysReady still false, then there is an
157+ * empty array key so no index scan is needed.
141158 */
142- if (runtimeKeyInfo )
143- {
159+ if (node -> biss_NumRuntimeKeys != 0 )
144160ExecIndexEvalRuntimeKeys (econtext ,
145- runtimeKeyInfo ,
146- node -> biss_ScanKeys ,
147- node -> biss_NumScanKeys );
161+ node -> biss_RuntimeKeys ,
162+ node -> biss_NumRuntimeKeys );
163+ if (node -> biss_NumArrayKeys != 0 )
164+ node -> biss_RuntimeKeysReady =
165+ ExecIndexEvalArrayKeys (econtext ,
166+ node -> biss_ArrayKeys ,
167+ node -> biss_NumArrayKeys );
168+ else
148169node -> biss_RuntimeKeysReady = true;
149- }
150170
151171/* reset index scan */
152- index_rescan (node -> biss_ScanDesc ,node -> biss_ScanKeys );
172+ if (node -> biss_RuntimeKeysReady )
173+ index_rescan (node -> biss_ScanDesc ,node -> biss_ScanKeys );
153174}
154175
155176/* ----------------------------------------------------------------
@@ -193,10 +214,6 @@ BitmapIndexScanState *
193214ExecInitBitmapIndexScan (BitmapIndexScan * node ,EState * estate )
194215{
195216BitmapIndexScanState * indexstate ;
196- ScanKey scanKeys ;
197- int numScanKeys ;
198- ExprState * * runtimeKeyInfo ;
199- bool have_runtime_keys ;
200217
201218/*
202219 * create state structure
@@ -236,26 +253,25 @@ ExecInitBitmapIndexScan(BitmapIndexScan *node, EState *estate)
236253/*
237254 * build the index scan keys from the index qualification
238255 */
239- have_runtime_keys =
240- ExecIndexBuildScanKeys ((PlanState * )indexstate ,
241- node -> indexqual ,
242- node -> indexstrategy ,
243- node -> indexsubtype ,
244- & runtimeKeyInfo ,
245- & scanKeys ,
246- & numScanKeys );
247-
248- indexstate -> biss_RuntimeKeyInfo = runtimeKeyInfo ;
249- indexstate -> biss_ScanKeys = scanKeys ;
250- indexstate -> biss_NumScanKeys = numScanKeys ;
256+ ExecIndexBuildScanKeys ((PlanState * )indexstate ,
257+ node -> indexqual ,
258+ node -> indexstrategy ,
259+ node -> indexsubtype ,
260+ & indexstate -> biss_ScanKeys ,
261+ & indexstate -> biss_NumScanKeys ,
262+ & indexstate -> biss_RuntimeKeys ,
263+ & indexstate -> biss_NumRuntimeKeys ,
264+ & indexstate -> biss_ArrayKeys ,
265+ & indexstate -> biss_NumArrayKeys );
251266
252267/*
253- * If we have runtime keys, we need an ExprContext to evaluate them. We
254- * could just create a "standard" plan node exprcontext, but to keep the
255- * code looking similar to nodeIndexscan.c, it seems better to stick with
256- * the approach of using a separate ExprContext.
268+ * If we have runtime keys or array keys , we need an ExprContext to
269+ *evaluate them. We could just create a "standard" plan node exprcontext,
270+ *but to keep the code looking similar to nodeIndexscan.c, it seems
271+ *better to stick with the approach of using a separate ExprContext.
257272 */
258- if (have_runtime_keys )
273+ if (indexstate -> biss_NumRuntimeKeys != 0 ||
274+ indexstate -> biss_NumArrayKeys != 0 )
259275{
260276ExprContext * stdecontext = indexstate -> ss .ps .ps_ExprContext ;
261277
@@ -286,8 +302,8 @@ ExecInitBitmapIndexScan(BitmapIndexScan *node, EState *estate)
286302indexstate -> biss_ScanDesc =
287303index_beginscan_multi (indexstate -> biss_RelationDesc ,
288304estate -> es_snapshot ,
289- numScanKeys ,
290- scanKeys );
305+ indexstate -> biss_NumScanKeys ,
306+ indexstate -> biss_ScanKeys );
291307
292308/*
293309 * all done.