@@ -105,16 +105,6 @@ BitmapHeapNext(BitmapHeapScanState *node)
105
105
*/
106
106
if (!node -> initialized )
107
107
{
108
- /*
109
- * We can potentially skip fetching heap pages if we do not need any
110
- * columns of the table, either for checking non-indexable quals or
111
- * for returning data. This test is a bit simplistic, as it checks
112
- * the stronger condition that there's no qual or return tlist at all.
113
- * But in most cases it's probably not worth working harder than that.
114
- */
115
- node -> can_skip_fetch = (node -> ss .ps .plan -> qual == NIL &&
116
- node -> ss .ps .plan -> targetlist == NIL );
117
-
118
108
if (!pstate )
119
109
{
120
110
tbm = (TIDBitmap * ) MultiExecProcNode (outerPlanState (node ));
@@ -195,10 +185,24 @@ BitmapHeapNext(BitmapHeapScanState *node)
195
185
*/
196
186
if (!scan )
197
187
{
188
+ bool need_tuples = false;
189
+
190
+ /*
191
+ * We can potentially skip fetching heap pages if we do not need
192
+ * any columns of the table, either for checking non-indexable
193
+ * quals or for returning data. This test is a bit simplistic, as
194
+ * it checks the stronger condition that there's no qual or return
195
+ * tlist at all. But in most cases it's probably not worth working
196
+ * harder than that.
197
+ */
198
+ need_tuples = (node -> ss .ps .plan -> qual != NIL ||
199
+ node -> ss .ps .plan -> targetlist != NIL );
200
+
198
201
scan = table_beginscan_bm (node -> ss .ss_currentRelation ,
199
202
node -> ss .ps .state -> es_snapshot ,
200
203
0 ,
201
- NULL );
204
+ NULL ,
205
+ need_tuples );
202
206
203
207
node -> ss .ss_currentScanDesc = scan ;
204
208
}
@@ -208,7 +212,7 @@ BitmapHeapNext(BitmapHeapScanState *node)
208
212
209
213
for (;;)
210
214
{
211
- bool skip_fetch ;
215
+ bool valid_block ;
212
216
213
217
CHECK_FOR_INTERRUPTS ();
214
218
@@ -229,37 +233,14 @@ BitmapHeapNext(BitmapHeapScanState *node)
229
233
230
234
BitmapAdjustPrefetchIterator (node , tbmres );
231
235
236
+ valid_block = table_scan_bitmap_next_block (scan , tbmres );
237
+
232
238
if (tbmres -> ntuples >= 0 )
233
239
node -> exact_pages ++ ;
234
240
else
235
241
node -> lossy_pages ++ ;
236
242
237
- /*
238
- * We can skip fetching the heap page if we don't need any fields
239
- * from the heap, and the bitmap entries don't need rechecking,
240
- * and all tuples on the page are visible to our transaction.
241
- *
242
- * XXX: It's a layering violation that we do these checks above
243
- * tableam, they should probably moved below it at some point.
244
- */
245
- skip_fetch = (node -> can_skip_fetch &&
246
- !tbmres -> recheck &&
247
- VM_ALL_VISIBLE (node -> ss .ss_currentRelation ,
248
- tbmres -> blockno ,
249
- & node -> vmbuffer ));
250
-
251
- if (skip_fetch )
252
- {
253
- /* can't be lossy in the skip_fetch case */
254
- Assert (tbmres -> ntuples >= 0 );
255
-
256
- /*
257
- * The number of tuples on this page is put into
258
- * node->return_empty_tuples.
259
- */
260
- node -> return_empty_tuples = tbmres -> ntuples ;
261
- }
262
- else if (!table_scan_bitmap_next_block (scan , tbmres ))
243
+ if (!valid_block )
263
244
{
264
245
/* AM doesn't think this block is valid, skip */
265
246
continue ;
@@ -302,52 +283,33 @@ BitmapHeapNext(BitmapHeapScanState *node)
302
283
* should happen only when we have determined there is still something
303
284
* to do on the current page, else we may uselessly prefetch the same
304
285
* page we are just about to request for real.
305
- *
306
- * XXX: It's a layering violation that we do these checks above
307
- * tableam, they should probably moved below it at some point.
308
286
*/
309
287
BitmapPrefetch (node , scan );
310
288
311
- if (node -> return_empty_tuples > 0 )
289
+ /*
290
+ * Attempt to fetch tuple from AM.
291
+ */
292
+ if (!table_scan_bitmap_next_tuple (scan , tbmres , slot ))
312
293
{
313
- /*
314
- * If we don't have to fetch the tuple, just return nulls.
315
- */
316
- ExecStoreAllNullTuple (slot );
317
-
318
- if (-- node -> return_empty_tuples == 0 )
319
- {
320
- /* no more tuples to return in the next round */
321
- node -> tbmres = tbmres = NULL ;
322
- }
294
+ /* nothing more to look at on this page */
295
+ node -> tbmres = tbmres = NULL ;
296
+ continue ;
323
297
}
324
- else
298
+
299
+ /*
300
+ * If we are using lossy info, we have to recheck the qual conditions
301
+ * at every tuple.
302
+ */
303
+ if (tbmres -> recheck )
325
304
{
326
- /*
327
- * Attempt to fetch tuple from AM.
328
- */
329
- if (!table_scan_bitmap_next_tuple (scan , tbmres , slot ))
305
+ econtext -> ecxt_scantuple = slot ;
306
+ if (!ExecQualAndReset (node -> bitmapqualorig , econtext ))
330
307
{
331
- /* nothing more to look at on this page */
332
- node -> tbmres = tbmres = NULL ;
308
+ /* Fails recheck, so drop it and loop back for another */
309
+ InstrCountFiltered2 (node , 1 );
310
+ ExecClearTuple (slot );
333
311
continue ;
334
312
}
335
-
336
- /*
337
- * If we are using lossy info, we have to recheck the qual
338
- * conditions at every tuple.
339
- */
340
- if (tbmres -> recheck )
341
- {
342
- econtext -> ecxt_scantuple = slot ;
343
- if (!ExecQualAndReset (node -> bitmapqualorig , econtext ))
344
- {
345
- /* Fails recheck, so drop it and loop back for another */
346
- InstrCountFiltered2 (node , 1 );
347
- ExecClearTuple (slot );
348
- continue ;
349
- }
350
- }
351
313
}
352
314
353
315
/* OK to return this tuple */
@@ -519,7 +481,7 @@ BitmapPrefetch(BitmapHeapScanState *node, TableScanDesc scan)
519
481
* it did for the current heap page; which is not a certainty
520
482
* but is true in many cases.
521
483
*/
522
- skip_fetch = (node -> can_skip_fetch &&
484
+ skip_fetch = (!( scan -> rs_flags & SO_NEED_TUPLES ) &&
523
485
(node -> tbmres ? !node -> tbmres -> recheck : false) &&
524
486
VM_ALL_VISIBLE (node -> ss .ss_currentRelation ,
525
487
tbmpre -> blockno ,
@@ -570,7 +532,7 @@ BitmapPrefetch(BitmapHeapScanState *node, TableScanDesc scan)
570
532
}
571
533
572
534
/* As above, skip prefetch if we expect not to need page */
573
- skip_fetch = (node -> can_skip_fetch &&
535
+ skip_fetch = (!( scan -> rs_flags & SO_NEED_TUPLES ) &&
574
536
(node -> tbmres ? !node -> tbmres -> recheck : false) &&
575
537
VM_ALL_VISIBLE (node -> ss .ss_currentRelation ,
576
538
tbmpre -> blockno ,
@@ -640,8 +602,6 @@ ExecReScanBitmapHeapScan(BitmapHeapScanState *node)
640
602
tbm_end_shared_iterate (node -> shared_prefetch_iterator );
641
603
if (node -> tbm )
642
604
tbm_free (node -> tbm );
643
- if (node -> vmbuffer != InvalidBuffer )
644
- ReleaseBuffer (node -> vmbuffer );
645
605
if (node -> pvmbuffer != InvalidBuffer )
646
606
ReleaseBuffer (node -> pvmbuffer );
647
607
node -> tbm = NULL ;
@@ -651,7 +611,6 @@ ExecReScanBitmapHeapScan(BitmapHeapScanState *node)
651
611
node -> initialized = false;
652
612
node -> shared_tbmiterator = NULL ;
653
613
node -> shared_prefetch_iterator = NULL ;
654
- node -> vmbuffer = InvalidBuffer ;
655
614
node -> pvmbuffer = InvalidBuffer ;
656
615
657
616
ExecScanReScan (& node -> ss );
@@ -696,8 +655,6 @@ ExecEndBitmapHeapScan(BitmapHeapScanState *node)
696
655
tbm_end_shared_iterate (node -> shared_tbmiterator );
697
656
if (node -> shared_prefetch_iterator )
698
657
tbm_end_shared_iterate (node -> shared_prefetch_iterator );
699
- if (node -> vmbuffer != InvalidBuffer )
700
- ReleaseBuffer (node -> vmbuffer );
701
658
if (node -> pvmbuffer != InvalidBuffer )
702
659
ReleaseBuffer (node -> pvmbuffer );
703
660
@@ -741,8 +698,6 @@ ExecInitBitmapHeapScan(BitmapHeapScan *node, EState *estate, int eflags)
741
698
scanstate -> tbm = NULL ;
742
699
scanstate -> tbmiterator = NULL ;
743
700
scanstate -> tbmres = NULL ;
744
- scanstate -> return_empty_tuples = 0 ;
745
- scanstate -> vmbuffer = InvalidBuffer ;
746
701
scanstate -> pvmbuffer = InvalidBuffer ;
747
702
scanstate -> exact_pages = 0 ;
748
703
scanstate -> lossy_pages = 0 ;
@@ -753,7 +708,6 @@ ExecInitBitmapHeapScan(BitmapHeapScan *node, EState *estate, int eflags)
753
708
scanstate -> shared_tbmiterator = NULL ;
754
709
scanstate -> shared_prefetch_iterator = NULL ;
755
710
scanstate -> pstate = NULL ;
756
- scanstate -> can_skip_fetch = false;
757
711
758
712
/*
759
713
* Miscellaneous initialization
0 commit comments