summaryrefslogtreecommitdiff
path: root/src/backend/access/nbtree/nbtscan.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/access/nbtree/nbtscan.c')
-rw-r--r--src/backend/access/nbtree/nbtscan.c173
1 files changed, 60 insertions, 113 deletions
diff --git a/src/backend/access/nbtree/nbtscan.c b/src/backend/access/nbtree/nbtscan.c
index b5e7d1207c..a2a6707d19 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.19 1999/02/13 23:14:36 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/nbtree/Attic/nbtscan.c,v 1.20 1999/03/28 20:31:58 vadim Exp $
*
*
* NOTES
@@ -43,8 +43,7 @@ typedef BTScanListData *BTScanList;
static BTScanList BTScans = (BTScanList) NULL;
-static void _bt_scandel(IndexScanDesc scan, int op, BlockNumber blkno, OffsetNumber offno);
-static bool _bt_scantouched(IndexScanDesc scan, BlockNumber blkno, OffsetNumber offno);
+static void _bt_scandel(IndexScanDesc scan, BlockNumber blkno, OffsetNumber offno);
/*
* _bt_regscan() -- register a new scan.
@@ -91,7 +90,7 @@ _bt_dropscan(IndexScanDesc scan)
* for a given deletion or insertion
*/
void
-_bt_adjscans(Relation rel, ItemPointer tid, int op)
+_bt_adjscans(Relation rel, ItemPointer tid)
{
BTScanList l;
Oid relid;
@@ -100,41 +99,25 @@ _bt_adjscans(Relation rel, ItemPointer tid, int op)
for (l = BTScans; l != (BTScanList) NULL; l = l->btsl_next)
{
if (relid == RelationGetRelid(l->btsl_scan->relation))
- _bt_scandel(l->btsl_scan, op,
+ _bt_scandel(l->btsl_scan,
ItemPointerGetBlockNumber(tid),
ItemPointerGetOffsetNumber(tid));
}
}
/*
- * _bt_scandel() -- adjust a single scan
+ * _bt_scandel() -- adjust a single scan on deletion
*
- * because each index page is always maintained as an ordered array of
- * index tuples, the index tuples on a given page shift beneath any
- * given scan. an index modification "behind" a scan position (i.e.,
- * same page, lower or equal offset number) will therefore force us to
- * adjust the scan in the following ways:
- *
- * - on insertion, we shift the scan forward by one item.
- * - on deletion, we shift the scan backward by one item.
- *
- * note that:
- *
- * - we need not worry about the actual ScanDirection of the scan
- * itself, since the problem is that the "current" scan position has
- * shifted.
- * - modifications "ahead" of our scan position do not change the
- * array index of the current scan position and so can be ignored.
*/
static void
-_bt_scandel(IndexScanDesc scan, int op, BlockNumber blkno, OffsetNumber offno)
+_bt_scandel(IndexScanDesc scan, BlockNumber blkno, OffsetNumber offno)
{
- ItemPointer current;
- Buffer buf;
- BTScanOpaque so;
-
- if (!_bt_scantouched(scan, blkno, offno))
- return;
+ ItemPointer current;
+ Buffer buf;
+ BTScanOpaque so;
+ OffsetNumber start;
+ Page page;
+ BTPageOpaque opaque;
so = (BTScanOpaque) scan->opaque;
buf = so->btso_curbuf;
@@ -144,33 +127,23 @@ _bt_scandel(IndexScanDesc scan, int op, BlockNumber blkno, OffsetNumber offno)
&& ItemPointerGetBlockNumber(current) == blkno
&& ItemPointerGetOffsetNumber(current) >= 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;
- default:
- elog(ERROR, "_bt_scandel: bad operation '%d'", op);
- /* NOTREACHED */
- }
- so->btso_curbuf = buf;
- if (ItemPointerIsValid(current))
+ page = BufferGetPage(buf);
+ opaque = (BTPageOpaque) PageGetSpecialPointer(page);
+ start = P_RIGHTMOST(opaque) ? P_HIKEY : P_FIRSTKEY;
+ if (ItemPointerGetOffsetNumber(current) == start)
+ ItemPointerSetInvalid(&(so->curHeapIptr));
+ else
{
- Page page = BufferGetPage(buf);
- BTItem btitem = (BTItem) PageGetItem(page,
- PageGetItemId(page, ItemPointerGetOffsetNumber(current)));
-
- so->curHeapIptr = btitem->bti_itup.t_tid;
+ _bt_step(scan, &buf, BackwardScanDirection);
+ so->btso_curbuf = buf;
+ if (ItemPointerIsValid(current))
+ {
+ Page pg = BufferGetPage(buf);
+ BTItem btitem = (BTItem) PageGetItem(pg,
+ PageGetItemId(pg, ItemPointerGetOffsetNumber(current)));
+
+ so->curHeapIptr = btitem->bti_itup.t_tid;
+ }
}
}
@@ -179,65 +152,39 @@ _bt_scandel(IndexScanDesc scan, int op, BlockNumber blkno, OffsetNumber offno)
&& ItemPointerGetBlockNumber(current) == blkno
&& ItemPointerGetOffsetNumber(current) >= offno)
{
- ItemPointerData tmp;
-
- tmp = *current;
- *current = scan->currentItemData;
- scan->currentItemData = tmp;
- so->btso_curbuf = so->btso_mrkbuf;
- so->btso_mrkbuf = buf;
- 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;
- default:
- elog(ERROR, "_bt_scandel: bad operation '%d'", op);
- /* NOTREACHED */
- }
- so->btso_curbuf = so->btso_mrkbuf;
- so->btso_mrkbuf = buf;
- 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;
+ page = BufferGetPage(so->btso_mrkbuf);
+ opaque = (BTPageOpaque) PageGetSpecialPointer(page);
+ start = P_RIGHTMOST(opaque) ? P_HIKEY : P_FIRSTKEY;
+
+ if (ItemPointerGetOffsetNumber(current) == start)
+ ItemPointerSetInvalid(&(so->mrkHeapIptr));
+ else
+ {
+ ItemPointerData tmp;
+
+ tmp = *current;
+ *current = scan->currentItemData;
+ scan->currentItemData = tmp;
+ so->btso_curbuf = so->btso_mrkbuf;
+ so->btso_mrkbuf = buf;
+ buf = so->btso_curbuf;
+
+ _bt_step(scan, &buf, BackwardScanDirection);
+
+ so->btso_curbuf = so->btso_mrkbuf;
+ so->btso_mrkbuf = buf;
+ tmp = *current;
+ *current = scan->currentItemData;
+ scan->currentItemData = tmp;
+ if (ItemPointerIsValid(current))
+ {
+ Page pg = BufferGetPage(buf);
+ BTItem btitem = (BTItem) PageGetItem(pg,
+ PageGetItemId(pg, ItemPointerGetOffsetNumber(current)));
+
+ so->mrkHeapIptr = btitem->bti_itup.t_tid;
+ }
}
}
}
-
-/*
- * _bt_scantouched() -- check to see if a scan is affected by a given
- * change to the index
- */
-static bool
-_bt_scantouched(IndexScanDesc scan, BlockNumber blkno, OffsetNumber offno)
-{
- ItemPointer current;
-
- current = &(scan->currentItemData);
- if (ItemPointerIsValid(current)
- && ItemPointerGetBlockNumber(current) == blkno
- && ItemPointerGetOffsetNumber(current) >= offno)
- return true;
-
- current = &(scan->currentMarkData);
- if (ItemPointerIsValid(current)
- && ItemPointerGetBlockNumber(current) == blkno
- && ItemPointerGetOffsetNumber(current) >= offno)
- return true;
-
- return false;
-}