@@ -364,6 +364,56 @@ heap_setscanlimits(TableScanDesc sscan, BlockNumber startBlk, BlockNumber numBlk
364
364
scan -> rs_numblocks = numBlks ;
365
365
}
366
366
367
+ /*
368
+ * Per-tuple loop for heapgetpage() in pagemode. Pulled out so it can be
369
+ * called multiple times, with constant arguments for all_visible,
370
+ * check_serializable.
371
+ */
372
+ pg_attribute_always_inline
373
+ static int
374
+ heapgetpage_collect (HeapScanDesc scan , Snapshot snapshot ,
375
+ Page page , Buffer buffer ,
376
+ BlockNumber block , int lines ,
377
+ bool all_visible , bool check_serializable )
378
+ {
379
+ int ntup = 0 ;
380
+ OffsetNumber lineoff ;
381
+
382
+ for (lineoff = FirstOffsetNumber ; lineoff <= lines ; lineoff ++ )
383
+ {
384
+ ItemId lpp = PageGetItemId (page , lineoff );
385
+ HeapTupleData loctup ;
386
+ bool valid ;
387
+
388
+ if (!ItemIdIsNormal (lpp ))
389
+ continue ;
390
+
391
+ loctup .t_data = (HeapTupleHeader ) PageGetItem (page , lpp );
392
+ loctup .t_len = ItemIdGetLength (lpp );
393
+ loctup .t_tableOid = RelationGetRelid (scan -> rs_base .rs_rd );
394
+ ItemPointerSet (& (loctup .t_self ), block , lineoff );
395
+
396
+ if (all_visible )
397
+ valid = true;
398
+ else
399
+ valid = HeapTupleSatisfiesVisibility (& loctup , snapshot , buffer );
400
+
401
+ if (check_serializable )
402
+ HeapCheckForSerializableConflictOut (valid , scan -> rs_base .rs_rd ,
403
+ & loctup , buffer , snapshot );
404
+
405
+ if (valid )
406
+ {
407
+ scan -> rs_vistuples [ntup ] = lineoff ;
408
+ ntup ++ ;
409
+ }
410
+ }
411
+
412
+ Assert (ntup <= MaxHeapTuplesPerPage );
413
+
414
+ return ntup ;
415
+ }
416
+
367
417
/*
368
418
* heap_prepare_pagescan - Prepare current scan page to be scanned in pagemode
369
419
*
@@ -379,9 +429,8 @@ heap_prepare_pagescan(TableScanDesc sscan)
379
429
Snapshot snapshot ;
380
430
Page page ;
381
431
int lines ;
382
- int ntup ;
383
- OffsetNumber lineoff ;
384
432
bool all_visible ;
433
+ bool check_serializable ;
385
434
386
435
Assert (BufferGetBlockNumber (buffer ) == block );
387
436
@@ -403,7 +452,6 @@ heap_prepare_pagescan(TableScanDesc sscan)
403
452
404
453
page = BufferGetPage (buffer );
405
454
lines = PageGetMaxOffsetNumber (page );
406
- ntup = 0 ;
407
455
408
456
/*
409
457
* If the all-visible flag indicates that all tuples on the page are
@@ -426,37 +474,35 @@ heap_prepare_pagescan(TableScanDesc sscan)
426
474
* tuple for visibility the hard way.
427
475
*/
428
476
all_visible = PageIsAllVisible (page ) && !snapshot -> takenDuringRecovery ;
477
+ check_serializable =
478
+ CheckForSerializableConflictOutNeeded (scan -> rs_base .rs_rd , snapshot );
429
479
430
- for (lineoff = FirstOffsetNumber ; lineoff <= lines ; lineoff ++ )
480
+ /*
481
+ * We call heapgetpage_collect() with constant arguments, to get the
482
+ * compiler to constant fold the constant arguments. Separate calls with
483
+ * constant arguments, rather than variables, are needed on several
484
+ * compilers to actually perform constant folding.
485
+ */
486
+ if (likely (all_visible ))
431
487
{
432
- ItemId lpp = PageGetItemId (page , lineoff );
433
- HeapTupleData loctup ;
434
- bool valid ;
435
-
436
- if (!ItemIdIsNormal (lpp ))
437
- continue ;
438
-
439
- loctup .t_tableOid = RelationGetRelid (scan -> rs_base .rs_rd );
440
- loctup .t_data = (HeapTupleHeader ) PageGetItem (page , lpp );
441
- loctup .t_len = ItemIdGetLength (lpp );
442
- ItemPointerSet (& (loctup .t_self ), block , lineoff );
443
-
444
- if (all_visible )
445
- valid = true;
488
+ if (likely (!check_serializable ))
489
+ scan -> rs_ntuples = heapgetpage_collect (scan , snapshot , page , buffer ,
490
+ block , lines , true, false);
446
491
else
447
- valid = HeapTupleSatisfiesVisibility (& loctup , snapshot , buffer );
448
-
449
- HeapCheckForSerializableConflictOut (valid , scan -> rs_base .rs_rd ,
450
- & loctup , buffer , snapshot );
451
-
452
- if (valid )
453
- scan -> rs_vistuples [ntup ++ ] = lineoff ;
492
+ scan -> rs_ntuples = heapgetpage_collect (scan , snapshot , page , buffer ,
493
+ block , lines , true, true);
494
+ }
495
+ else
496
+ {
497
+ if (likely (!check_serializable ))
498
+ scan -> rs_ntuples = heapgetpage_collect (scan , snapshot , page , buffer ,
499
+ block , lines , false, false);
500
+ else
501
+ scan -> rs_ntuples = heapgetpage_collect (scan , snapshot , page , buffer ,
502
+ block , lines , false, true);
454
503
}
455
504
456
505
LockBuffer (buffer , BUFFER_LOCK_UNLOCK );
457
-
458
- Assert (ntup <= MaxHeapTuplesPerPage );
459
- scan -> rs_ntuples = ntup ;
460
506
}
461
507
462
508
/*
0 commit comments