Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit f73fc6e

Browse files
committed
Fix scan adjustment.
1 parent 957ff1a commit f73fc6e

File tree

3 files changed

+148
-12
lines changed

3 files changed

+148
-12
lines changed

src/backend/access/nbtree/nbtree.c

Lines changed: 103 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* 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 $
1212
*
1313
* NOTES
1414
* This file contains only the public interface routines.
@@ -44,6 +44,8 @@ bool BuildingBtree = false; /* see comment in btbuild() */
4444
bool FastBuild = true; /* use sort/build instead of insertion
4545
* build */
4646

47+
static void _bt_restscan(IndexScanDesc scan);
48+
4749
/*
4850
* btbuild() -- build a new btree index.
4951
*
@@ -374,8 +376,10 @@ btinsert(Relation rel, Datum *datum, char *nulls, ItemPointer ht_ctid, Relation
374376
pfree(btitem);
375377
pfree(itup);
376378

379+
#if 0
377380
/* adjust any active scans that will be affected by this insertion */
378381
_bt_adjscans(rel, &(res->pointerData), BT_INSERT);
382+
#endif
379383

380384
return (res);
381385
}
@@ -395,10 +399,28 @@ btgettuple(IndexScanDesc scan, ScanDirection dir)
395399
*/
396400

397401
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);
398415
res = _bt_next(scan, dir);
416+
}
399417
else
400418
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+
402424
return ((char *) res);
403425
}
404426

@@ -555,6 +577,7 @@ btmarkpos(IndexScanDesc scan)
555577
BufferGetBlockNumber(so->btso_curbuf),
556578
BT_READ);
557579
scan->currentMarkData = scan->currentItemData;
580+
so->mrkHeapIptr = so->curHeapIptr;
558581
}
559582
}
560583

@@ -585,6 +608,7 @@ btrestrpos(IndexScanDesc scan)
585608
BT_READ);
586609

587610
scan->currentItemData = scan->currentMarkData;
611+
so->curHeapIptr = so->mrkHeapIptr;
588612
}
589613
}
590614

@@ -598,3 +622,80 @@ btdelete(Relation rel, ItemPointer tid)
598622
/* delete the data from the page */
599623
_bt_pagedel(rel, tid);
600624
}
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+
}

src/backend/access/nbtree/nbtscan.c

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/Attic/nbtscan.c,v 1.14 1998/06/15 19:27:57 momjian Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/Attic/nbtscan.c,v 1.15 1998/07/30 05:04:50 vadim Exp $
1111
*
1212
*
1313
* NOTES
@@ -30,6 +30,7 @@
3030
#include <postgres.h>
3131

3232
#include <storage/bufpage.h>
33+
#include <storage/bufmgr.h>
3334
#include <access/nbtree.h>
3435

3536
typedef struct BTScanListData
@@ -145,9 +146,16 @@ _bt_scandel(IndexScanDesc scan, int op, BlockNumber blkno, OffsetNumber offno)
145146
{
146147
switch (op)
147148
{
149+
/*
150+
* Problems occure when current scan page is splitted!
151+
* We saw "Non-functional updates" (ie index tuples were read twice)
152+
* and partial updates ("good" tuples were not read at all) - due to
153+
* losing scan position here. Look @ nbtree.c:btgettuple()
154+
* what we do now... - vadim 07/29/98
148155
case BT_INSERT:
149156
_bt_step(scan, &buf, ForwardScanDirection);
150157
break;
158+
*/
151159
case BT_DELETE:
152160
_bt_step(scan, &buf, BackwardScanDirection);
153161
break;
@@ -156,6 +164,14 @@ _bt_scandel(IndexScanDesc scan, int op, BlockNumber blkno, OffsetNumber offno)
156164
/* NOTREACHED */
157165
}
158166
so->btso_curbuf = buf;
167+
if (ItemPointerIsValid(current))
168+
{
169+
Page page = BufferGetPage(buf);
170+
BTItem btitem = (BTItem) PageGetItem(page,
171+
PageGetItemId(page, ItemPointerGetOffsetNumber(current)));
172+
173+
so->curHeapIptr = btitem->bti_itup.t_tid;
174+
}
159175
}
160176

161177
current = &(scan->currentMarkData);
@@ -173,9 +189,12 @@ _bt_scandel(IndexScanDesc scan, int op, BlockNumber blkno, OffsetNumber offno)
173189
buf = so->btso_curbuf;
174190
switch (op)
175191
{
192+
/*
193+
* ...comments are above...
176194
case BT_INSERT:
177195
_bt_step(scan, &buf, ForwardScanDirection);
178196
break;
197+
*/
179198
case BT_DELETE:
180199
_bt_step(scan, &buf, BackwardScanDirection);
181200
break;
@@ -188,6 +207,14 @@ _bt_scandel(IndexScanDesc scan, int op, BlockNumber blkno, OffsetNumber offno)
188207
tmp = *current;
189208
*current = scan->currentItemData;
190209
scan->currentItemData = tmp;
210+
if (ItemPointerIsValid(current))
211+
{
212+
Page page = BufferGetPage(buf);
213+
BTItem btitem = (BTItem) PageGetItem(page,
214+
PageGetItemId(page, ItemPointerGetOffsetNumber(current)));
215+
216+
so->mrkHeapIptr = btitem->bti_itup.t_tid;
217+
}
191218
}
192219
}
193220

src/include/access/nbtree.h

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
*
77
* Copyright (c) 1994, Regents of the University of California
88
*
9-
* $Id: nbtree.h,v 1.20 1998/02/26 04:40:22 momjian Exp $
9+
* $Id: nbtree.h,v 1.21 1998/07/30 05:05:05 vadim Exp $
1010
*
1111
*-------------------------------------------------------------------------
1212
*/
@@ -62,18 +62,26 @@ typedef BTPageOpaqueData *BTPageOpaque;
6262
* semop() calls, which are expensive.
6363
*
6464
* And it's used to remember actual scankey info (we need in it
65-
* if some scankeys evaled at runtime.
65+
* if some scankeys evaled at runtime).
66+
*
67+
* curHeapIptr & mrkHeapIptr are heap iptr-s from current/marked
68+
* index tuples: we don't adjust scans on insertions (and, if LLL
69+
* is ON, don't hold locks on index pages between passes) - we
70+
* use these pointers to restore index scan positions...
71+
* - vadim 07/29/98
6672
*/
6773

6874
typedef struct BTScanOpaqueData
6975
{
70-
Buffer btso_curbuf;
71-
Buffer btso_mrkbuf;
72-
uint16 qual_ok; /* 0 for quals like key == 1 && key > 2 */
73-
uint16 numberOfKeys; /* number of keys */
74-
uint16 numberOfFirstKeys; /* number of keys for 1st
75-
* attribute */
76-
ScanKey keyData; /* key descriptor */
76+
Buffer btso_curbuf;
77+
Buffer btso_mrkbuf;
78+
ItemPointerData curHeapIptr;
79+
ItemPointerData mrkHeapIptr;
80+
uint16 qual_ok; /* 0 for quals like key == 1 && key > 2 */
81+
uint16 numberOfKeys; /* number of keys */
82+
uint16 numberOfFirstKeys; /* number of keys for 1st
83+
* attribute */
84+
ScanKey keyData; /* key descriptor */
7785
} BTScanOpaqueData;
7886

7987
typedef BTScanOpaqueData *BTScanOpaque;

0 commit comments

Comments
 (0)