summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVadim B. Mikheev1998-07-30 05:05:05 +0000
committerVadim B. Mikheev1998-07-30 05:05:05 +0000
commitf73fc6eb2908104e4ca0a28106806364cc085c98 (patch)
treee9bb90edc2302c1cf6780ac91fc57f5cb9107dee
parent957ff1a0b5ed8db496b7c5e7e8a71a27576d15ac (diff)
Fix scan adjustment.
-rw-r--r--src/backend/access/nbtree/nbtree.c105
-rw-r--r--src/backend/access/nbtree/nbtscan.c29
-rw-r--r--src/include/access/nbtree.h26
3 files changed, 148 insertions, 12 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;
+ }
}
}
diff --git a/src/include/access/nbtree.h b/src/include/access/nbtree.h
index c7012005563..5e3d03af3b8 100644
--- a/src/include/access/nbtree.h
+++ b/src/include/access/nbtree.h
@@ -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;