diff options
Diffstat (limited to 'src/backend/access/rtree/rtget.c')
-rw-r--r-- | src/backend/access/rtree/rtget.c | 544 |
1 files changed, 291 insertions, 253 deletions
diff --git a/src/backend/access/rtree/rtget.c b/src/backend/access/rtree/rtget.c index 09f10f1aa98..eaf16c1ae9d 100644 --- a/src/backend/access/rtree/rtget.c +++ b/src/backend/access/rtree/rtget.c @@ -1,19 +1,19 @@ /*------------------------------------------------------------------------- * * rtget.c-- - * fetch tuples from an rtree scan. + * fetch tuples from an rtree scan. * * Copyright (c) 1994, Regents of the University of California * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtget.c,v 1.7 1996/11/21 06:13:43 vadim Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtget.c,v 1.8 1997/09/07 04:39:11 momjian Exp $ * *------------------------------------------------------------------------- */ #include <postgres.h> - + #include <storage/bufmgr.h> #include <access/sdir.h> #include <access/relscan.h> @@ -21,14 +21,15 @@ #include <access/rtree.h> #include <storage/bufpage.h> #ifndef HAVE_MEMMOVE -# include <regex/utils.h> +#include <regex/utils.h> #else -# include <string.h> +#include <string.h> #endif -static OffsetNumber findnext(IndexScanDesc s, Page p, OffsetNumber n, - ScanDirection dir); +static OffsetNumber +findnext(IndexScanDesc s, Page p, OffsetNumber n, + ScanDirection dir); static RetrieveIndexResult rtscancache(IndexScanDesc s, ScanDirection dir); static RetrieveIndexResult rtfirst(IndexScanDesc s, ScanDirection dir); static RetrieveIndexResult rtnext(IndexScanDesc s, ScanDirection dir); @@ -38,278 +39,315 @@ static ItemPointer rtheapptr(Relation r, ItemPointer itemp); RetrieveIndexResult rtgettuple(IndexScanDesc s, ScanDirection dir) { - RetrieveIndexResult res; - - /* if we have it cached in the scan desc, just return the value */ - if ((res = rtscancache(s, dir)) != (RetrieveIndexResult) NULL) + RetrieveIndexResult res; + + /* if we have it cached in the scan desc, just return the value */ + if ((res = rtscancache(s, dir)) != (RetrieveIndexResult) NULL) + return (res); + + /* not cached, so we'll have to do some work */ + if (ItemPointerIsValid(&(s->currentItemData))) + { + res = rtnext(s, dir); + } + else + { + res = rtfirst(s, dir); + } return (res); - - /* not cached, so we'll have to do some work */ - if (ItemPointerIsValid(&(s->currentItemData))) { - res = rtnext(s, dir); - } else { - res = rtfirst(s, dir); - } - return (res); } -static RetrieveIndexResult +static RetrieveIndexResult rtfirst(IndexScanDesc s, ScanDirection dir) { - Buffer b; - Page p; - OffsetNumber n; - OffsetNumber maxoff; - RetrieveIndexResult res; - RTreePageOpaque po; - RTreeScanOpaque so; - RTSTACK *stk; - BlockNumber blk; - IndexTuple it; - - b = ReadBuffer(s->relation, P_ROOT); - p = BufferGetPage(b); - po = (RTreePageOpaque) PageGetSpecialPointer(p); - so = (RTreeScanOpaque) s->opaque; - - for (;;) { - maxoff = PageGetMaxOffsetNumber(p); - if (ScanDirectionIsBackward(dir)) - n = findnext(s, p, maxoff, dir); - else - n = findnext(s, p, FirstOffsetNumber, dir); - - while (n < FirstOffsetNumber || n > maxoff) { - - ReleaseBuffer(b); - if (so->s_stack == (RTSTACK *) NULL) - return ((RetrieveIndexResult) NULL); - - stk = so->s_stack; - b = ReadBuffer(s->relation, stk->rts_blk); - p = BufferGetPage(b); - po = (RTreePageOpaque) PageGetSpecialPointer(p); - maxoff = PageGetMaxOffsetNumber(p); - - if (ScanDirectionIsBackward(dir)) { - n = OffsetNumberPrev(stk->rts_child); - } else { - n = OffsetNumberNext(stk->rts_child); - } - so->s_stack = stk->rts_parent; - pfree(stk); - - n = findnext(s, p, n, dir); - } - if (po->flags & F_LEAF) { - ItemPointerSet(&(s->currentItemData), BufferGetBlockNumber(b), n); - - it = (IndexTuple) PageGetItem(p, PageGetItemId(p, n)); - - res = FormRetrieveIndexResult(&(s->currentItemData), &(it->t_tid)); - - ReleaseBuffer(b); - return (res); - } else { - stk = (RTSTACK *) palloc(sizeof(RTSTACK)); - stk->rts_child = n; - stk->rts_blk = BufferGetBlockNumber(b); - stk->rts_parent = so->s_stack; - so->s_stack = stk; - - it = (IndexTuple) PageGetItem(p, PageGetItemId(p, n)); - blk = ItemPointerGetBlockNumber(&(it->t_tid)); - - ReleaseBuffer(b); - b = ReadBuffer(s->relation, blk); - p = BufferGetPage(b); - po = (RTreePageOpaque) PageGetSpecialPointer(p); + Buffer b; + Page p; + OffsetNumber n; + OffsetNumber maxoff; + RetrieveIndexResult res; + RTreePageOpaque po; + RTreeScanOpaque so; + RTSTACK *stk; + BlockNumber blk; + IndexTuple it; + + b = ReadBuffer(s->relation, P_ROOT); + p = BufferGetPage(b); + po = (RTreePageOpaque) PageGetSpecialPointer(p); + so = (RTreeScanOpaque) s->opaque; + + for (;;) + { + maxoff = PageGetMaxOffsetNumber(p); + if (ScanDirectionIsBackward(dir)) + n = findnext(s, p, maxoff, dir); + else + n = findnext(s, p, FirstOffsetNumber, dir); + + while (n < FirstOffsetNumber || n > maxoff) + { + + ReleaseBuffer(b); + if (so->s_stack == (RTSTACK *) NULL) + return ((RetrieveIndexResult) NULL); + + stk = so->s_stack; + b = ReadBuffer(s->relation, stk->rts_blk); + p = BufferGetPage(b); + po = (RTreePageOpaque) PageGetSpecialPointer(p); + maxoff = PageGetMaxOffsetNumber(p); + + if (ScanDirectionIsBackward(dir)) + { + n = OffsetNumberPrev(stk->rts_child); + } + else + { + n = OffsetNumberNext(stk->rts_child); + } + so->s_stack = stk->rts_parent; + pfree(stk); + + n = findnext(s, p, n, dir); + } + if (po->flags & F_LEAF) + { + ItemPointerSet(&(s->currentItemData), BufferGetBlockNumber(b), n); + + it = (IndexTuple) PageGetItem(p, PageGetItemId(p, n)); + + res = FormRetrieveIndexResult(&(s->currentItemData), &(it->t_tid)); + + ReleaseBuffer(b); + return (res); + } + else + { + stk = (RTSTACK *) palloc(sizeof(RTSTACK)); + stk->rts_child = n; + stk->rts_blk = BufferGetBlockNumber(b); + stk->rts_parent = so->s_stack; + so->s_stack = stk; + + it = (IndexTuple) PageGetItem(p, PageGetItemId(p, n)); + blk = ItemPointerGetBlockNumber(&(it->t_tid)); + + ReleaseBuffer(b); + b = ReadBuffer(s->relation, blk); + p = BufferGetPage(b); + po = (RTreePageOpaque) PageGetSpecialPointer(p); + } } - } } -static RetrieveIndexResult +static RetrieveIndexResult rtnext(IndexScanDesc s, ScanDirection dir) { - Buffer b; - Page p; - OffsetNumber n; - OffsetNumber maxoff; - RetrieveIndexResult res; - RTreePageOpaque po; - RTreeScanOpaque so; - RTSTACK *stk; - BlockNumber blk; - IndexTuple it; - - blk = ItemPointerGetBlockNumber(&(s->currentItemData)); - n = ItemPointerGetOffsetNumber(&(s->currentItemData)); - - if (ScanDirectionIsForward(dir)) { - n = OffsetNumberNext(n); - } else { - n = OffsetNumberPrev(n); - } - - b = ReadBuffer(s->relation, blk); - p = BufferGetPage(b); - po = (RTreePageOpaque) PageGetSpecialPointer(p); - so = (RTreeScanOpaque) s->opaque; - - for (;;) { - maxoff = PageGetMaxOffsetNumber(p); - n = findnext(s, p, n, dir); - - while (n < FirstOffsetNumber || n > maxoff) { - - ReleaseBuffer(b); - if (so->s_stack == (RTSTACK *) NULL) - return ((RetrieveIndexResult) NULL); - - stk = so->s_stack; - b = ReadBuffer(s->relation, stk->rts_blk); - p = BufferGetPage(b); - maxoff = PageGetMaxOffsetNumber(p); - po = (RTreePageOpaque) PageGetSpecialPointer(p); - - if (ScanDirectionIsBackward(dir)) { - n = OffsetNumberPrev(stk->rts_child); - } else { - n = OffsetNumberNext(stk->rts_child); - } - so->s_stack = stk->rts_parent; - pfree(stk); - - n = findnext(s, p, n, dir); + Buffer b; + Page p; + OffsetNumber n; + OffsetNumber maxoff; + RetrieveIndexResult res; + RTreePageOpaque po; + RTreeScanOpaque so; + RTSTACK *stk; + BlockNumber blk; + IndexTuple it; + + blk = ItemPointerGetBlockNumber(&(s->currentItemData)); + n = ItemPointerGetOffsetNumber(&(s->currentItemData)); + + if (ScanDirectionIsForward(dir)) + { + n = OffsetNumberNext(n); + } + else + { + n = OffsetNumberPrev(n); } - if (po->flags & F_LEAF) { - ItemPointerSet(&(s->currentItemData), BufferGetBlockNumber(b), n); - - it = (IndexTuple) PageGetItem(p, PageGetItemId(p, n)); - - res = FormRetrieveIndexResult(&(s->currentItemData), &(it->t_tid)); - - ReleaseBuffer(b); - return (res); - } else { - stk = (RTSTACK *) palloc(sizeof(RTSTACK)); - stk->rts_child = n; - stk->rts_blk = BufferGetBlockNumber(b); - stk->rts_parent = so->s_stack; - so->s_stack = stk; - - it = (IndexTuple) PageGetItem(p, PageGetItemId(p, n)); - blk = ItemPointerGetBlockNumber(&(it->t_tid)); - - ReleaseBuffer(b); - b = ReadBuffer(s->relation, blk); - p = BufferGetPage(b); - po = (RTreePageOpaque) PageGetSpecialPointer(p); - - if (ScanDirectionIsBackward(dir)) { - n = PageGetMaxOffsetNumber(p); - } else { - n = FirstOffsetNumber; - } + + b = ReadBuffer(s->relation, blk); + p = BufferGetPage(b); + po = (RTreePageOpaque) PageGetSpecialPointer(p); + so = (RTreeScanOpaque) s->opaque; + + for (;;) + { + maxoff = PageGetMaxOffsetNumber(p); + n = findnext(s, p, n, dir); + + while (n < FirstOffsetNumber || n > maxoff) + { + + ReleaseBuffer(b); + if (so->s_stack == (RTSTACK *) NULL) + return ((RetrieveIndexResult) NULL); + + stk = so->s_stack; + b = ReadBuffer(s->relation, stk->rts_blk); + p = BufferGetPage(b); + maxoff = PageGetMaxOffsetNumber(p); + po = (RTreePageOpaque) PageGetSpecialPointer(p); + + if (ScanDirectionIsBackward(dir)) + { + n = OffsetNumberPrev(stk->rts_child); + } + else + { + n = OffsetNumberNext(stk->rts_child); + } + so->s_stack = stk->rts_parent; + pfree(stk); + + n = findnext(s, p, n, dir); + } + if (po->flags & F_LEAF) + { + ItemPointerSet(&(s->currentItemData), BufferGetBlockNumber(b), n); + + it = (IndexTuple) PageGetItem(p, PageGetItemId(p, n)); + + res = FormRetrieveIndexResult(&(s->currentItemData), &(it->t_tid)); + + ReleaseBuffer(b); + return (res); + } + else + { + stk = (RTSTACK *) palloc(sizeof(RTSTACK)); + stk->rts_child = n; + stk->rts_blk = BufferGetBlockNumber(b); + stk->rts_parent = so->s_stack; + so->s_stack = stk; + + it = (IndexTuple) PageGetItem(p, PageGetItemId(p, n)); + blk = ItemPointerGetBlockNumber(&(it->t_tid)); + + ReleaseBuffer(b); + b = ReadBuffer(s->relation, blk); + p = BufferGetPage(b); + po = (RTreePageOpaque) PageGetSpecialPointer(p); + + if (ScanDirectionIsBackward(dir)) + { + n = PageGetMaxOffsetNumber(p); + } + else + { + n = FirstOffsetNumber; + } + } } - } } -static OffsetNumber +static OffsetNumber findnext(IndexScanDesc s, Page p, OffsetNumber n, ScanDirection dir) { - OffsetNumber maxoff; - IndexTuple it; - RTreePageOpaque po; - RTreeScanOpaque so; - - maxoff = PageGetMaxOffsetNumber(p); - po = (RTreePageOpaque) PageGetSpecialPointer(p); - so = (RTreeScanOpaque) s->opaque; - - /* - * If we modified the index during the scan, we may have a pointer to - * a ghost tuple, before the scan. If this is the case, back up one. - */ - - if (so->s_flags & RTS_CURBEFORE) { - so->s_flags &= ~RTS_CURBEFORE; - n = OffsetNumberPrev(n); - } - - while (n >= FirstOffsetNumber && n <= maxoff) { - it = (IndexTuple) PageGetItem(p, PageGetItemId(p, n)); - if (po->flags & F_LEAF) { - if (index_keytest(it, - RelationGetTupleDescriptor(s->relation), - s->numberOfKeys, s->keyData)) - break; - } else { - if (index_keytest(it, - RelationGetTupleDescriptor(s->relation), - so->s_internalNKey, so->s_internalKey)) - break; + OffsetNumber maxoff; + IndexTuple it; + RTreePageOpaque po; + RTreeScanOpaque so; + + maxoff = PageGetMaxOffsetNumber(p); + po = (RTreePageOpaque) PageGetSpecialPointer(p); + so = (RTreeScanOpaque) s->opaque; + + /* + * If we modified the index during the scan, we may have a pointer to + * a ghost tuple, before the scan. If this is the case, back up one. + */ + + if (so->s_flags & RTS_CURBEFORE) + { + so->s_flags &= ~RTS_CURBEFORE; + n = OffsetNumberPrev(n); } - - if (ScanDirectionIsBackward(dir)) { - n = OffsetNumberPrev(n); - } else { - n = OffsetNumberNext(n); + + while (n >= FirstOffsetNumber && n <= maxoff) + { + it = (IndexTuple) PageGetItem(p, PageGetItemId(p, n)); + if (po->flags & F_LEAF) + { + if (index_keytest(it, + RelationGetTupleDescriptor(s->relation), + s->numberOfKeys, s->keyData)) + break; + } + else + { + if (index_keytest(it, + RelationGetTupleDescriptor(s->relation), + so->s_internalNKey, so->s_internalKey)) + break; + } + + if (ScanDirectionIsBackward(dir)) + { + n = OffsetNumberPrev(n); + } + else + { + n = OffsetNumberNext(n); + } } - } - - return (n); + + return (n); } -static RetrieveIndexResult +static RetrieveIndexResult rtscancache(IndexScanDesc s, ScanDirection dir) { - RetrieveIndexResult res; - ItemPointer ip; - - if (!(ScanDirectionIsNoMovement(dir) - && ItemPointerIsValid(&(s->currentItemData)))) { - - return ((RetrieveIndexResult) NULL); - } - - ip = rtheapptr(s->relation, &(s->currentItemData)); - - if (ItemPointerIsValid(ip)) - res = FormRetrieveIndexResult(&(s->currentItemData), ip); - else - res = (RetrieveIndexResult) NULL; - - pfree (ip); - - return (res); + RetrieveIndexResult res; + ItemPointer ip; + + if (!(ScanDirectionIsNoMovement(dir) + && ItemPointerIsValid(&(s->currentItemData)))) + { + + return ((RetrieveIndexResult) NULL); + } + + ip = rtheapptr(s->relation, &(s->currentItemData)); + + if (ItemPointerIsValid(ip)) + res = FormRetrieveIndexResult(&(s->currentItemData), ip); + else + res = (RetrieveIndexResult) NULL; + + pfree(ip); + + return (res); } /* - * rtheapptr returns the item pointer to the tuple in the heap relation - * for which itemp is the index relation item pointer. + * rtheapptr returns the item pointer to the tuple in the heap relation + * for which itemp is the index relation item pointer. */ -static ItemPointer +static ItemPointer rtheapptr(Relation r, ItemPointer itemp) { - Buffer b; - Page p; - IndexTuple it; - ItemPointer ip; - OffsetNumber n; - - ip = (ItemPointer) palloc(sizeof(ItemPointerData)); - if (ItemPointerIsValid(itemp)) { - b = ReadBuffer(r, ItemPointerGetBlockNumber(itemp)); - p = BufferGetPage(b); - n = ItemPointerGetOffsetNumber(itemp); - it = (IndexTuple) PageGetItem(p, PageGetItemId(p, n)); - memmove((char *) ip, (char *) &(it->t_tid), - sizeof(ItemPointerData)); - ReleaseBuffer(b); - } else { - ItemPointerSetInvalid(ip); - } - - return (ip); + Buffer b; + Page p; + IndexTuple it; + ItemPointer ip; + OffsetNumber n; + + ip = (ItemPointer) palloc(sizeof(ItemPointerData)); + if (ItemPointerIsValid(itemp)) + { + b = ReadBuffer(r, ItemPointerGetBlockNumber(itemp)); + p = BufferGetPage(b); + n = ItemPointerGetOffsetNumber(itemp); + it = (IndexTuple) PageGetItem(p, PageGetItemId(p, n)); + memmove((char *) ip, (char *) &(it->t_tid), + sizeof(ItemPointerData)); + ReleaseBuffer(b); + } + else + { + ItemPointerSetInvalid(ip); + } + + return (ip); } |