8
8
*
9
9
*
10
10
* 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 $
12
12
*
13
13
*-------------------------------------------------------------------------
14
14
*/
@@ -43,6 +43,7 @@ MultiExecBitmapIndexScan(BitmapIndexScanState *node)
43
43
ItemPointerData tids [MAX_TIDS ];
44
44
int32 ntids ;
45
45
double nTuples = 0 ;
46
+ bool doscan ;
46
47
47
48
/* must provide our own instrumentation support */
48
49
if (node -> ss .ps .instrument )
@@ -55,9 +56,18 @@ MultiExecBitmapIndexScan(BitmapIndexScanState *node)
55
56
56
57
/*
57
58
* 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.
58
62
*/
59
- if (node -> biss_RuntimeKeyInfo && !node -> biss_RuntimeKeysReady )
63
+ if (!node -> biss_RuntimeKeysReady &&
64
+ (node -> biss_NumRuntimeKeys != 0 || node -> biss_NumArrayKeys != 0 ))
65
+ {
60
66
ExecReScan ((PlanState * ) node , NULL );
67
+ doscan = node -> biss_RuntimeKeysReady ;
68
+ }
69
+ else
70
+ doscan = true;
61
71
62
72
/*
63
73
* Prepare the result bitmap. Normally we just create a new one to pass
@@ -79,7 +89,7 @@ MultiExecBitmapIndexScan(BitmapIndexScanState *node)
79
89
/*
80
90
* Get TIDs from index and insert into bitmap
81
91
*/
82
- for (;; )
92
+ while ( doscan )
83
93
{
84
94
bool more = index_getmulti (scandesc , tids , MAX_TIDS , & ntids );
85
95
@@ -89,10 +99,15 @@ MultiExecBitmapIndexScan(BitmapIndexScanState *node)
89
99
nTuples += ntids ;
90
100
}
91
101
92
- if (!more )
93
- break ;
94
-
95
102
CHECK_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
+ }
96
111
}
97
112
98
113
/* must provide our own instrumentation support */
@@ -113,10 +128,8 @@ void
113
128
ExecBitmapIndexReScan (BitmapIndexScanState * node , ExprContext * exprCtxt )
114
129
{
115
130
ExprContext * econtext ;
116
- ExprState * * runtimeKeyInfo ;
117
131
118
132
econtext = node -> biss_RuntimeContext ; /* context for runtime keys */
119
- runtimeKeyInfo = node -> biss_RuntimeKeyInfo ;
120
133
121
134
if (econtext )
122
135
{
@@ -137,19 +150,27 @@ ExecBitmapIndexReScan(BitmapIndexScanState *node, ExprContext *exprCtxt)
137
150
138
151
/*
139
152
* 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.
141
158
*/
142
- if (runtimeKeyInfo )
143
- {
159
+ if (node -> biss_NumRuntimeKeys != 0 )
144
160
ExecIndexEvalRuntimeKeys (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
148
169
node -> biss_RuntimeKeysReady = true;
149
- }
150
170
151
171
/* 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 );
153
174
}
154
175
155
176
/* ----------------------------------------------------------------
@@ -193,10 +214,6 @@ BitmapIndexScanState *
193
214
ExecInitBitmapIndexScan (BitmapIndexScan * node , EState * estate )
194
215
{
195
216
BitmapIndexScanState * indexstate ;
196
- ScanKey scanKeys ;
197
- int numScanKeys ;
198
- ExprState * * runtimeKeyInfo ;
199
- bool have_runtime_keys ;
200
217
201
218
/*
202
219
* create state structure
@@ -236,26 +253,25 @@ ExecInitBitmapIndexScan(BitmapIndexScan *node, EState *estate)
236
253
/*
237
254
* build the index scan keys from the index qualification
238
255
*/
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 );
251
266
252
267
/*
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.
257
272
*/
258
- if (have_runtime_keys )
273
+ if (indexstate -> biss_NumRuntimeKeys != 0 ||
274
+ indexstate -> biss_NumArrayKeys != 0 )
259
275
{
260
276
ExprContext * stdecontext = indexstate -> ss .ps .ps_ExprContext ;
261
277
@@ -286,8 +302,8 @@ ExecInitBitmapIndexScan(BitmapIndexScan *node, EState *estate)
286
302
indexstate -> biss_ScanDesc =
287
303
index_beginscan_multi (indexstate -> biss_RelationDesc ,
288
304
estate -> es_snapshot ,
289
- numScanKeys ,
290
- scanKeys );
305
+ indexstate -> biss_NumScanKeys ,
306
+ indexstate -> biss_ScanKeys );
291
307
292
308
/*
293
309
* all done.
0 commit comments