diff options
Diffstat (limited to 'src/backend/access/nbtree/nbtree.c')
-rw-r--r-- | src/backend/access/nbtree/nbtree.c | 129 |
1 files changed, 55 insertions, 74 deletions
diff --git a/src/backend/access/nbtree/nbtree.c b/src/backend/access/nbtree/nbtree.c index b174d303176..072d4000705 100644 --- a/src/backend/access/nbtree/nbtree.c +++ b/src/backend/access/nbtree/nbtree.c @@ -12,7 +12,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtree.c,v 1.61 2000/07/14 22:17:33 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtree.c,v 1.62 2000/07/21 06:42:32 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -26,6 +26,7 @@ #include "executor/executor.h" #include "miscadmin.h" + bool BuildingBtree = false; /* see comment in btbuild() */ bool FastBuild = true; /* use sort/build instead of insertion * build */ @@ -206,8 +207,8 @@ btbuild(PG_FUNCTION_ARGS) * btree pages - NULLs greater NOT_NULLs and NULL = NULL is TRUE. * Sure, it's just rule for placing/finding items and no more - * keytest'll return FALSE for a = 5 for items having 'a' isNULL. - * Look at _bt_skeycmp, _bt_compare and _bt_itemcmp for how it - * works. - vadim 03/23/97 + * Look at _bt_compare for how it works. + * - vadim 03/23/97 * * if (itup->t_info & INDEX_NULL_MASK) { pfree(itup); continue; } */ @@ -321,14 +322,6 @@ btinsert(PG_FUNCTION_ARGS) /* generate an index tuple */ itup = index_formtuple(RelationGetDescr(rel), datum, nulls); itup->t_tid = *ht_ctid; - - /* - * See comments in btbuild. - * - * if (itup->t_info & INDEX_NULL_MASK) - * PG_RETURN_POINTER((InsertIndexResult) NULL); - */ - btitem = _bt_formitem(itup); res = _bt_doinsert(rel, btitem, rel->rd_uniqueindex, heapRel); @@ -357,10 +350,10 @@ btgettuple(PG_FUNCTION_ARGS) if (ItemPointerIsValid(&(scan->currentItemData))) { - /* * Restore scan position using heap TID returned by previous call - * to btgettuple(). _bt_restscan() locks buffer. + * to btgettuple(). _bt_restscan() re-grabs the read lock on + * the buffer, too. */ _bt_restscan(scan); res = _bt_next(scan, dir); @@ -369,8 +362,9 @@ btgettuple(PG_FUNCTION_ARGS) res = _bt_first(scan, dir); /* - * Save heap TID to use it in _bt_restscan. Unlock buffer before - * leaving index ! + * Save heap TID to use it in _bt_restscan. Then release the read + * lock on the buffer so that we aren't blocking other backends. + * NOTE: we do keep the pin on the buffer! */ if (res) { @@ -419,7 +413,18 @@ btrescan(PG_FUNCTION_ARGS) so = (BTScanOpaque) scan->opaque; - /* we don't hold a read lock on the current page in the scan */ + if (so == NULL) /* if called from btbeginscan */ + { + so = (BTScanOpaque) palloc(sizeof(BTScanOpaqueData)); + so->btso_curbuf = so->btso_mrkbuf = InvalidBuffer; + so->keyData = (ScanKey) NULL; + if (scan->numberOfKeys > 0) + so->keyData = (ScanKey) palloc(scan->numberOfKeys * sizeof(ScanKeyData)); + scan->opaque = so; + scan->flags = 0x0; + } + + /* we aren't holding any read locks, but gotta drop the pins */ if (ItemPointerIsValid(iptr = &(scan->currentItemData))) { ReleaseBuffer(so->btso_curbuf); @@ -427,7 +432,6 @@ btrescan(PG_FUNCTION_ARGS) ItemPointerSetInvalid(iptr); } - /* and we don't hold a read lock on the last marked item in the scan */ if (ItemPointerIsValid(iptr = &(scan->currentMarkData))) { ReleaseBuffer(so->btso_mrkbuf); @@ -435,17 +439,6 @@ btrescan(PG_FUNCTION_ARGS) ItemPointerSetInvalid(iptr); } - if (so == NULL) /* if called from btbeginscan */ - { - so = (BTScanOpaque) palloc(sizeof(BTScanOpaqueData)); - so->btso_curbuf = so->btso_mrkbuf = InvalidBuffer; - so->keyData = (ScanKey) NULL; - if (scan->numberOfKeys > 0) - so->keyData = (ScanKey) palloc(scan->numberOfKeys * sizeof(ScanKeyData)); - scan->opaque = so; - scan->flags = 0x0; - } - /* * Reset the scan keys. Note that keys ordering stuff moved to * _bt_first. - vadim 05/05/97 @@ -472,7 +465,7 @@ btmovescan(IndexScanDesc scan, Datum v) so = (BTScanOpaque) scan->opaque; - /* we don't hold a read lock on the current page in the scan */ + /* we aren't holding any read locks, but gotta drop the pin */ if (ItemPointerIsValid(iptr = &(scan->currentItemData))) { ReleaseBuffer(so->btso_curbuf); @@ -480,7 +473,6 @@ btmovescan(IndexScanDesc scan, Datum v) ItemPointerSetInvalid(iptr); } -/* scan->keyData[0].sk_argument = v; */ so->keyData[0].sk_argument = v; } @@ -496,7 +488,7 @@ btendscan(PG_FUNCTION_ARGS) so = (BTScanOpaque) scan->opaque; - /* we don't hold any read locks */ + /* we aren't holding any read locks, but gotta drop the pins */ if (ItemPointerIsValid(iptr = &(scan->currentItemData))) { if (BufferIsValid(so->btso_curbuf)) @@ -534,7 +526,7 @@ btmarkpos(PG_FUNCTION_ARGS) so = (BTScanOpaque) scan->opaque; - /* we don't hold any read locks */ + /* we aren't holding any read locks, but gotta drop the pin */ if (ItemPointerIsValid(iptr = &(scan->currentMarkData))) { ReleaseBuffer(so->btso_mrkbuf); @@ -542,7 +534,7 @@ btmarkpos(PG_FUNCTION_ARGS) ItemPointerSetInvalid(iptr); } - /* bump pin on current buffer */ + /* bump pin on current buffer for assignment to mark buffer */ if (ItemPointerIsValid(&(scan->currentItemData))) { so->btso_mrkbuf = ReadBuffer(scan->relation, @@ -566,7 +558,7 @@ btrestrpos(PG_FUNCTION_ARGS) so = (BTScanOpaque) scan->opaque; - /* we don't hold any read locks */ + /* we aren't holding any read locks, but gotta drop the pin */ if (ItemPointerIsValid(iptr = &(scan->currentItemData))) { ReleaseBuffer(so->btso_curbuf); @@ -579,7 +571,6 @@ btrestrpos(PG_FUNCTION_ARGS) { so->btso_curbuf = ReadBuffer(scan->relation, BufferGetBlockNumber(so->btso_mrkbuf)); - scan->currentItemData = scan->currentMarkData; so->curHeapIptr = so->mrkHeapIptr; } @@ -603,6 +594,9 @@ btdelete(PG_FUNCTION_ARGS) PG_RETURN_VOID(); } +/* + * Restore scan position when btgettuple is called to continue a scan. + */ static void _bt_restscan(IndexScanDesc scan) { @@ -618,7 +612,12 @@ _bt_restscan(IndexScanDesc scan) BTItem item; BlockNumber blkno; - LockBuffer(buf, BT_READ); /* lock buffer first! */ + /* + * Get back the read lock we were holding on the buffer. + * (We still have a reference-count pin on it, though.) + */ + LockBuffer(buf, BT_READ); + page = BufferGetPage(buf); maxoff = PageGetMaxOffsetNumber(page); opaque = (BTPageOpaque) PageGetSpecialPointer(page); @@ -631,43 +630,40 @@ _bt_restscan(IndexScanDesc scan) */ if (!ItemPointerIsValid(&target)) { - ItemPointerSetOffsetNumber(&(scan->currentItemData), - OffsetNumberPrev(P_RIGHTMOST(opaque) ? P_HIKEY : P_FIRSTKEY)); + ItemPointerSetOffsetNumber(current, + OffsetNumberPrev(P_FIRSTDATAKEY(opaque))); return; } - if (maxoff >= offnum) + /* + * The item we were on may have moved right due to insertions. + * Find it again. + */ + for (;;) { - - /* - * if the item is where we left it or has just moved right on this - * page, we're done - */ + /* Check for item on this page */ 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 && \ + 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 (;;) - { + /* + * By here, the item we're looking for moved right at least one page + */ if (P_RIGHTMOST(opaque)) - elog(FATAL, "_bt_restscan: my bits moved right off the end of the world!\ -\n\tRecreate index %s.", RelationGetRelationName(rel)); + elog(FATAL, "_bt_restscan: my bits moved right off the end of the world!" + "\n\tRecreate index %s.", RelationGetRelationName(rel)); blkno = opaque->btpo_next; _bt_relbuf(rel, buf, BT_READ); @@ -675,23 +671,8 @@ _bt_restscan(IndexScanDesc scan) 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; - } - } + offnum = P_FIRSTDATAKEY(opaque); + ItemPointerSet(current, blkno, offnum); + so->btso_curbuf = buf; } } |