Commit f73fc6eb authored by Vadim B. Mikheev's avatar Vadim B. Mikheev

Fix scan adjustment.

parent 957ff1a0
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 * NOTES
* This file contains only the public interface routines. * This file contains only the public interface routines.
...@@ -44,6 +44,8 @@ bool BuildingBtree = false; /* see comment in btbuild() */ ...@@ -44,6 +44,8 @@ bool BuildingBtree = false; /* see comment in btbuild() */
bool FastBuild = true; /* use sort/build instead of insertion bool FastBuild = true; /* use sort/build instead of insertion
* build */ * build */
static void _bt_restscan(IndexScanDesc scan);
/* /*
* btbuild() -- build a new btree index. * btbuild() -- build a new btree index.
* *
...@@ -374,8 +376,10 @@ btinsert(Relation rel, Datum *datum, char *nulls, ItemPointer ht_ctid, Relation ...@@ -374,8 +376,10 @@ btinsert(Relation rel, Datum *datum, char *nulls, ItemPointer ht_ctid, Relation
pfree(btitem); pfree(btitem);
pfree(itup); pfree(itup);
#if 0
/* adjust any active scans that will be affected by this insertion */ /* adjust any active scans that will be affected by this insertion */
_bt_adjscans(rel, &(res->pointerData), BT_INSERT); _bt_adjscans(rel, &(res->pointerData), BT_INSERT);
#endif
return (res); return (res);
} }
...@@ -395,10 +399,28 @@ btgettuple(IndexScanDesc scan, ScanDirection dir) ...@@ -395,10 +399,28 @@ btgettuple(IndexScanDesc scan, ScanDirection dir)
*/ */
if (ItemPointerIsValid(&(scan->currentItemData))) 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); res = _bt_next(scan, dir);
}
else else
res = _bt_first(scan, dir); 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); return ((char *) res);
} }
...@@ -555,6 +577,7 @@ btmarkpos(IndexScanDesc scan) ...@@ -555,6 +577,7 @@ btmarkpos(IndexScanDesc scan)
BufferGetBlockNumber(so->btso_curbuf), BufferGetBlockNumber(so->btso_curbuf),
BT_READ); BT_READ);
scan->currentMarkData = scan->currentItemData; scan->currentMarkData = scan->currentItemData;
so->mrkHeapIptr = so->curHeapIptr;
} }
} }
...@@ -585,6 +608,7 @@ btrestrpos(IndexScanDesc scan) ...@@ -585,6 +608,7 @@ btrestrpos(IndexScanDesc scan)
BT_READ); BT_READ);
scan->currentItemData = scan->currentMarkData; scan->currentItemData = scan->currentMarkData;
so->curHeapIptr = so->mrkHeapIptr;
} }
} }
...@@ -598,3 +622,80 @@ btdelete(Relation rel, ItemPointer tid) ...@@ -598,3 +622,80 @@ btdelete(Relation rel, ItemPointer tid)
/* delete the data from the page */ /* delete the data from the page */
_bt_pagedel(rel, tid); _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;
}
}
}
}
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * 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 * NOTES
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#include <postgres.h> #include <postgres.h>
#include <storage/bufpage.h> #include <storage/bufpage.h>
#include <storage/bufmgr.h>
#include <access/nbtree.h> #include <access/nbtree.h>
typedef struct BTScanListData typedef struct BTScanListData
...@@ -145,9 +146,16 @@ _bt_scandel(IndexScanDesc scan, int op, BlockNumber blkno, OffsetNumber offno) ...@@ -145,9 +146,16 @@ _bt_scandel(IndexScanDesc scan, int op, BlockNumber blkno, OffsetNumber offno)
{ {
switch (op) 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: case BT_INSERT:
_bt_step(scan, &buf, ForwardScanDirection); _bt_step(scan, &buf, ForwardScanDirection);
break; break;
*/
case BT_DELETE: case BT_DELETE:
_bt_step(scan, &buf, BackwardScanDirection); _bt_step(scan, &buf, BackwardScanDirection);
break; break;
...@@ -156,6 +164,14 @@ _bt_scandel(IndexScanDesc scan, int op, BlockNumber blkno, OffsetNumber offno) ...@@ -156,6 +164,14 @@ _bt_scandel(IndexScanDesc scan, int op, BlockNumber blkno, OffsetNumber offno)
/* NOTREACHED */ /* NOTREACHED */
} }
so->btso_curbuf = buf; 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); current = &(scan->currentMarkData);
...@@ -173,9 +189,12 @@ _bt_scandel(IndexScanDesc scan, int op, BlockNumber blkno, OffsetNumber offno) ...@@ -173,9 +189,12 @@ _bt_scandel(IndexScanDesc scan, int op, BlockNumber blkno, OffsetNumber offno)
buf = so->btso_curbuf; buf = so->btso_curbuf;
switch (op) switch (op)
{ {
/*
* ...comments are above...
case BT_INSERT: case BT_INSERT:
_bt_step(scan, &buf, ForwardScanDirection); _bt_step(scan, &buf, ForwardScanDirection);
break; break;
*/
case BT_DELETE: case BT_DELETE:
_bt_step(scan, &buf, BackwardScanDirection); _bt_step(scan, &buf, BackwardScanDirection);
break; break;
...@@ -188,6 +207,14 @@ _bt_scandel(IndexScanDesc scan, int op, BlockNumber blkno, OffsetNumber offno) ...@@ -188,6 +207,14 @@ _bt_scandel(IndexScanDesc scan, int op, BlockNumber blkno, OffsetNumber offno)
tmp = *current; tmp = *current;
*current = scan->currentItemData; *current = scan->currentItemData;
scan->currentItemData = tmp; 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;
}
} }
} }
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* *
* Copyright (c) 1994, Regents of the University of California * Copyright (c) 1994, Regents of the University of California
* *
* $Id: nbtree.h,v 1.20 1998/02/26 04:40:22 momjian Exp $ * $Id: nbtree.h,v 1.21 1998/07/30 05:05:05 vadim Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -62,13 +62,21 @@ typedef BTPageOpaqueData *BTPageOpaque; ...@@ -62,13 +62,21 @@ typedef BTPageOpaqueData *BTPageOpaque;
* semop() calls, which are expensive. * semop() calls, which are expensive.
* *
* And it's used to remember actual scankey info (we need in it * And it's used to remember actual scankey info (we need in it
* if some scankeys evaled at runtime. * if some scankeys evaled at runtime).
*
* curHeapIptr & mrkHeapIptr are heap iptr-s from current/marked
* index tuples: we don't adjust scans on insertions (and, if LLL
* is ON, don't hold locks on index pages between passes) - we
* use these pointers to restore index scan positions...
* - vadim 07/29/98
*/ */
typedef struct BTScanOpaqueData typedef struct BTScanOpaqueData
{ {
Buffer btso_curbuf; Buffer btso_curbuf;
Buffer btso_mrkbuf; Buffer btso_mrkbuf;
ItemPointerData curHeapIptr;
ItemPointerData mrkHeapIptr;
uint16 qual_ok; /* 0 for quals like key == 1 && key > 2 */ uint16 qual_ok; /* 0 for quals like key == 1 && key > 2 */
uint16 numberOfKeys; /* number of keys */ uint16 numberOfKeys; /* number of keys */
uint16 numberOfFirstKeys; /* number of keys for 1st uint16 numberOfFirstKeys; /* number of keys for 1st
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment