diff options
author | Vadim B. Mikheev <vadim4o@yahoo.com> | 1998-07-30 05:05:05 +0000 |
---|---|---|
committer | Vadim B. Mikheev <vadim4o@yahoo.com> | 1998-07-30 05:05:05 +0000 |
commit | f73fc6eb2908104e4ca0a28106806364cc085c98 (patch) | |
tree | e9bb90edc2302c1cf6780ac91fc57f5cb9107dee /src/backend | |
parent | 957ff1a0b5ed8db496b7c5e7e8a71a27576d15ac (diff) | |
download | postgresql-f73fc6eb2908104e4ca0a28106806364cc085c98.tar.gz postgresql-f73fc6eb2908104e4ca0a28106806364cc085c98.zip |
Fix scan adjustment.
Diffstat (limited to 'src/backend')
-rw-r--r-- | src/backend/access/nbtree/nbtree.c | 105 | ||||
-rw-r--r-- | src/backend/access/nbtree/nbtscan.c | 29 |
2 files changed, 131 insertions, 3 deletions
diff --git a/src/backend/access/nbtree/nbtree.c b/src/backend/access/nbtree/nbtree.c index c4ea6aa6127..c30d7d56aca 100644 --- a/src/backend/access/nbtree/nbtree.c +++ b/src/backend/access/nbtree/nbtree.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtree.c,v 1.27 1998/07/27 19:37:40 vadim Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtree.c,v 1.28 1998/07/30 05:04:49 vadim Exp $ * * NOTES * This file contains only the public interface routines. @@ -44,6 +44,8 @@ bool BuildingBtree = false; /* see comment in btbuild() */ bool FastBuild = true; /* use sort/build instead of insertion * build */ +static void _bt_restscan(IndexScanDesc scan); + /* * btbuild() -- build a new btree index. * @@ -374,8 +376,10 @@ btinsert(Relation rel, Datum *datum, char *nulls, ItemPointer ht_ctid, Relation pfree(btitem); pfree(itup); +#if 0 /* adjust any active scans that will be affected by this insertion */ _bt_adjscans(rel, &(res->pointerData), BT_INSERT); +#endif return (res); } @@ -395,10 +399,28 @@ btgettuple(IndexScanDesc scan, ScanDirection dir) */ if (ItemPointerIsValid(&(scan->currentItemData))) + { + /* + * Now we don't adjust scans on insertion (comments in + * nbtscan.c:_bt_scandel()) and I hope that we will unlock + * current index page before leaving index in LLL: this + * means that current index tuple could be moved right + * before we get here and we have to restore our scan + * position. We save heap TID pointed by current index + * tuple and use it. This will work untill we start + * to re-use (move heap tuples) without vacuum... + * - vadim 07/29/98 + */ + _bt_restscan(scan); res = _bt_next(scan, dir); + } else res = _bt_first(scan, dir); - + + /* Save heap TID to use it in _bt_restscan */ + if (res) + ((BTScanOpaque)scan->opaque)->curHeapIptr = res->heap_iptr; + return ((char *) res); } @@ -555,6 +577,7 @@ btmarkpos(IndexScanDesc scan) BufferGetBlockNumber(so->btso_curbuf), BT_READ); scan->currentMarkData = scan->currentItemData; + so->mrkHeapIptr = so->curHeapIptr; } } @@ -585,6 +608,7 @@ btrestrpos(IndexScanDesc scan) BT_READ); scan->currentItemData = scan->currentMarkData; + so->curHeapIptr = so->mrkHeapIptr; } } @@ -598,3 +622,80 @@ btdelete(Relation rel, ItemPointer tid) /* delete the data from the page */ _bt_pagedel(rel, tid); } + +/* + * Reasons are in btgettuple... We have to find index item that + * points to heap tuple returned by previous call to btgettuple(). + */ +static void +_bt_restscan(IndexScanDesc scan) +{ + Relation rel = scan->relation; + BTScanOpaque so = (BTScanOpaque) scan->opaque; + Buffer buf = so->btso_curbuf; + Page page = BufferGetPage(buf); + ItemPointer current = &(scan->currentItemData); + OffsetNumber offnum = ItemPointerGetOffsetNumber(current), + maxoff = PageGetMaxOffsetNumber(page); + BTPageOpaque opaque = (BTPageOpaque) PageGetSpecialPointer(page); + ItemPointerData target = so->curHeapIptr; + BTItem item; + BlockNumber blkno; + + if (maxoff >= offnum) + { + /* + * if the item is where we left it or has just moved right + * on this page, we're done + */ + for ( ; + offnum <= maxoff; + offnum = OffsetNumberNext(offnum)) + { + item = (BTItem) PageGetItem(page, PageGetItemId(page, offnum)); + if (item->bti_itup.t_tid.ip_blkid.bi_hi == \ + target.ip_blkid.bi_hi && \ + item->bti_itup.t_tid.ip_blkid.bi_lo == \ + target.ip_blkid.bi_lo && \ + item->bti_itup.t_tid.ip_posid == target.ip_posid) + { + current->ip_posid = offnum; + return; + } + } + } + + /* + * By here, the item we're looking for moved right at least one page + */ + for (;;) + { + if (P_RIGHTMOST(opaque)) + elog(FATAL, "_bt_restscan: my bits moved right off the end of the world!"); + + blkno = opaque->btpo_next; + _bt_relbuf(rel, buf, BT_READ); + buf = _bt_getbuf(rel, blkno, BT_READ); + page = BufferGetPage(buf); + maxoff = PageGetMaxOffsetNumber(page); + opaque = (BTPageOpaque) PageGetSpecialPointer(page); + + /* see if it's on this page */ + for (offnum = P_RIGHTMOST(opaque) ? P_HIKEY : P_FIRSTKEY ; + offnum <= maxoff; + offnum = OffsetNumberNext(offnum)) + { + item = (BTItem) PageGetItem(page, PageGetItemId(page, offnum)); + if (item->bti_itup.t_tid.ip_blkid.bi_hi == \ + target.ip_blkid.bi_hi && \ + item->bti_itup.t_tid.ip_blkid.bi_lo == \ + target.ip_blkid.bi_lo && \ + item->bti_itup.t_tid.ip_posid == target.ip_posid) + { + ItemPointerSet(current, blkno, offnum); + so->btso_curbuf = buf; + return; + } + } + } +} diff --git a/src/backend/access/nbtree/nbtscan.c b/src/backend/access/nbtree/nbtscan.c index 8fc6e736c69..7aa9d2ac571 100644 --- a/src/backend/access/nbtree/nbtscan.c +++ b/src/backend/access/nbtree/nbtscan.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/access/nbtree/Attic/nbtscan.c,v 1.14 1998/06/15 19:27:57 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/nbtree/Attic/nbtscan.c,v 1.15 1998/07/30 05:04:50 vadim Exp $ * * * NOTES @@ -30,6 +30,7 @@ #include <postgres.h> #include <storage/bufpage.h> +#include <storage/bufmgr.h> #include <access/nbtree.h> typedef struct BTScanListData @@ -145,9 +146,16 @@ _bt_scandel(IndexScanDesc scan, int op, BlockNumber blkno, OffsetNumber offno) { switch (op) { +/* + * Problems occure when current scan page is splitted! + * We saw "Non-functional updates" (ie index tuples were read twice) + * and partial updates ("good" tuples were not read at all) - due to + * losing scan position here. Look @ nbtree.c:btgettuple() + * what we do now... - vadim 07/29/98 case BT_INSERT: _bt_step(scan, &buf, ForwardScanDirection); break; + */ case BT_DELETE: _bt_step(scan, &buf, BackwardScanDirection); break; @@ -156,6 +164,14 @@ _bt_scandel(IndexScanDesc scan, int op, BlockNumber blkno, OffsetNumber offno) /* NOTREACHED */ } so->btso_curbuf = buf; + if (ItemPointerIsValid(current)) + { + Page page = BufferGetPage(buf); + BTItem btitem = (BTItem) PageGetItem(page, + PageGetItemId(page, ItemPointerGetOffsetNumber(current))); + + so->curHeapIptr = btitem->bti_itup.t_tid; + } } current = &(scan->currentMarkData); @@ -173,9 +189,12 @@ _bt_scandel(IndexScanDesc scan, int op, BlockNumber blkno, OffsetNumber offno) buf = so->btso_curbuf; switch (op) { +/* + * ...comments are above... case BT_INSERT: _bt_step(scan, &buf, ForwardScanDirection); break; + */ case BT_DELETE: _bt_step(scan, &buf, BackwardScanDirection); break; @@ -188,6 +207,14 @@ _bt_scandel(IndexScanDesc scan, int op, BlockNumber blkno, OffsetNumber offno) tmp = *current; *current = scan->currentItemData; scan->currentItemData = tmp; + if (ItemPointerIsValid(current)) + { + Page page = BufferGetPage(buf); + BTItem btitem = (BTItem) PageGetItem(page, + PageGetItemId(page, ItemPointerGetOffsetNumber(current))); + + so->mrkHeapIptr = btitem->bti_itup.t_tid; + } } } |