Skip to content
Snippets Groups Projects
Commit f73fc6eb authored by Vadim B. Mikheev's avatar Vadim B. Mikheev
Browse files

Fix scan adjustment.

parent 957ff1a0
No related branches found
No related tags found
No related merge requests found
......@@ -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;
}
}
}
}
......@@ -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;
}
}
}
......
......@@ -6,7 +6,7 @@
*
* 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,18 +62,26 @@ typedef BTPageOpaqueData *BTPageOpaque;
* semop() calls, which are expensive.
*
* 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
{
Buffer btso_curbuf;
Buffer btso_mrkbuf;
uint16 qual_ok; /* 0 for quals like key == 1 && key > 2 */
uint16 numberOfKeys; /* number of keys */
uint16 numberOfFirstKeys; /* number of keys for 1st
* attribute */
ScanKey keyData; /* key descriptor */
Buffer btso_curbuf;
Buffer btso_mrkbuf;
ItemPointerData curHeapIptr;
ItemPointerData mrkHeapIptr;
uint16 qual_ok; /* 0 for quals like key == 1 && key > 2 */
uint16 numberOfKeys; /* number of keys */
uint16 numberOfFirstKeys; /* number of keys for 1st
* attribute */
ScanKey keyData; /* key descriptor */
} BTScanOpaqueData;
typedef BTScanOpaqueData *BTScanOpaque;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment