8
8
*
9
9
*
10
10
* IDENTIFICATION
11
- * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtree.c,v 1.27 1998/07/27 19:37:40 vadim Exp $
11
+ * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtree.c,v 1.28 1998/07/30 05:04:49 vadim Exp $
12
12
*
13
13
* NOTES
14
14
* This file contains only the public interface routines.
@@ -44,6 +44,8 @@ bool BuildingBtree = false; /* see comment in btbuild() */
44
44
bool FastBuild = true; /* use sort/build instead of insertion
45
45
* build */
46
46
47
+ static void _bt_restscan (IndexScanDesc scan );
48
+
47
49
/*
48
50
* btbuild() -- build a new btree index.
49
51
*
@@ -374,8 +376,10 @@ btinsert(Relation rel, Datum *datum, char *nulls, ItemPointer ht_ctid, Relation
374
376
pfree (btitem );
375
377
pfree (itup );
376
378
379
+ #if 0
377
380
/* adjust any active scans that will be affected by this insertion */
378
381
_bt_adjscans (rel , & (res -> pointerData ), BT_INSERT );
382
+ #endif
379
383
380
384
return (res );
381
385
}
@@ -395,10 +399,28 @@ btgettuple(IndexScanDesc scan, ScanDirection dir)
395
399
*/
396
400
397
401
if (ItemPointerIsValid (& (scan -> currentItemData )))
402
+ {
403
+ /*
404
+ * Now we don't adjust scans on insertion (comments in
405
+ * nbtscan.c:_bt_scandel()) and I hope that we will unlock
406
+ * current index page before leaving index in LLL: this
407
+ * means that current index tuple could be moved right
408
+ * before we get here and we have to restore our scan
409
+ * position. We save heap TID pointed by current index
410
+ * tuple and use it. This will work untill we start
411
+ * to re-use (move heap tuples) without vacuum...
412
+ * - vadim 07/29/98
413
+ */
414
+ _bt_restscan (scan );
398
415
res = _bt_next (scan , dir );
416
+ }
399
417
else
400
418
res = _bt_first (scan , dir );
401
-
419
+
420
+ /* Save heap TID to use it in _bt_restscan */
421
+ if (res )
422
+ ((BTScanOpaque )scan -> opaque )-> curHeapIptr = res -> heap_iptr ;
423
+
402
424
return ((char * ) res );
403
425
}
404
426
@@ -555,6 +577,7 @@ btmarkpos(IndexScanDesc scan)
555
577
BufferGetBlockNumber (so -> btso_curbuf ),
556
578
BT_READ );
557
579
scan -> currentMarkData = scan -> currentItemData ;
580
+ so -> mrkHeapIptr = so -> curHeapIptr ;
558
581
}
559
582
}
560
583
@@ -585,6 +608,7 @@ btrestrpos(IndexScanDesc scan)
585
608
BT_READ );
586
609
587
610
scan -> currentItemData = scan -> currentMarkData ;
611
+ so -> curHeapIptr = so -> mrkHeapIptr ;
588
612
}
589
613
}
590
614
@@ -598,3 +622,80 @@ btdelete(Relation rel, ItemPointer tid)
598
622
/* delete the data from the page */
599
623
_bt_pagedel (rel , tid );
600
624
}
625
+
626
+ /*
627
+ * Reasons are in btgettuple... We have to find index item that
628
+ * points to heap tuple returned by previous call to btgettuple().
629
+ */
630
+ static void
631
+ _bt_restscan (IndexScanDesc scan )
632
+ {
633
+ Relation rel = scan -> relation ;
634
+ BTScanOpaque so = (BTScanOpaque ) scan -> opaque ;
635
+ Buffer buf = so -> btso_curbuf ;
636
+ Page page = BufferGetPage (buf );
637
+ ItemPointer current = & (scan -> currentItemData );
638
+ OffsetNumber offnum = ItemPointerGetOffsetNumber (current ),
639
+ maxoff = PageGetMaxOffsetNumber (page );
640
+ BTPageOpaque opaque = (BTPageOpaque ) PageGetSpecialPointer (page );
641
+ ItemPointerData target = so -> curHeapIptr ;
642
+ BTItem item ;
643
+ BlockNumber blkno ;
644
+
645
+ if (maxoff >= offnum )
646
+ {
647
+ /*
648
+ * if the item is where we left it or has just moved right
649
+ * on this page, we're done
650
+ */
651
+ for ( ;
652
+ offnum <= maxoff ;
653
+ offnum = OffsetNumberNext (offnum ))
654
+ {
655
+ item = (BTItem ) PageGetItem (page , PageGetItemId (page , offnum ));
656
+ if (item -> bti_itup .t_tid .ip_blkid .bi_hi == \
657
+ target .ip_blkid .bi_hi && \
658
+ item -> bti_itup .t_tid .ip_blkid .bi_lo == \
659
+ target .ip_blkid .bi_lo && \
660
+ item -> bti_itup .t_tid .ip_posid == target .ip_posid )
661
+ {
662
+ current -> ip_posid = offnum ;
663
+ return ;
664
+ }
665
+ }
666
+ }
667
+
668
+ /*
669
+ * By here, the item we're looking for moved right at least one page
670
+ */
671
+ for (;;)
672
+ {
673
+ if (P_RIGHTMOST (opaque ))
674
+ elog (FATAL , "_bt_restscan: my bits moved right off the end of the world!" );
675
+
676
+ blkno = opaque -> btpo_next ;
677
+ _bt_relbuf (rel , buf , BT_READ );
678
+ buf = _bt_getbuf (rel , blkno , BT_READ );
679
+ page = BufferGetPage (buf );
680
+ maxoff = PageGetMaxOffsetNumber (page );
681
+ opaque = (BTPageOpaque ) PageGetSpecialPointer (page );
682
+
683
+ /* see if it's on this page */
684
+ for (offnum = P_RIGHTMOST (opaque ) ? P_HIKEY : P_FIRSTKEY ;
685
+ offnum <= maxoff ;
686
+ offnum = OffsetNumberNext (offnum ))
687
+ {
688
+ item = (BTItem ) PageGetItem (page , PageGetItemId (page , offnum ));
689
+ if (item -> bti_itup .t_tid .ip_blkid .bi_hi == \
690
+ target .ip_blkid .bi_hi && \
691
+ item -> bti_itup .t_tid .ip_blkid .bi_lo == \
692
+ target .ip_blkid .bi_lo && \
693
+ item -> bti_itup .t_tid .ip_posid == target .ip_posid )
694
+ {
695
+ ItemPointerSet (current , blkno , offnum );
696
+ so -> btso_curbuf = buf ;
697
+ return ;
698
+ }
699
+ }
700
+ }
701
+ }
0 commit comments