summaryrefslogtreecommitdiff
path: root/src/backend/access/rtree/rtget.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/access/rtree/rtget.c')
-rw-r--r--src/backend/access/rtree/rtget.c281
1 files changed, 0 insertions, 281 deletions
diff --git a/src/backend/access/rtree/rtget.c b/src/backend/access/rtree/rtget.c
deleted file mode 100644
index 010a493d20e..00000000000
--- a/src/backend/access/rtree/rtget.c
+++ /dev/null
@@ -1,281 +0,0 @@
-/*-------------------------------------------------------------------------
- *
- * rtget.c
- * fetch tuples from an rtree scan.
- *
- * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
- * Portions Copyright (c) 1994, Regents of the University of California
- *
- *
- * IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/access/rtree/rtget.c,v 1.37 2005/10/15 02:49:09 momjian Exp $
- *
- *-------------------------------------------------------------------------
- */
-
-#include "postgres.h"
-
-#include "access/iqual.h"
-#include "access/relscan.h"
-#include "access/rtree.h"
-#include "pgstat.h"
-
-
-static OffsetNumber findnext(IndexScanDesc s, OffsetNumber n,
- ScanDirection dir);
-static bool rtnext(IndexScanDesc s, ScanDirection dir);
-
-
-Datum
-rtgettuple(PG_FUNCTION_ARGS)
-{
- IndexScanDesc s = (IndexScanDesc) PG_GETARG_POINTER(0);
- ScanDirection dir = (ScanDirection) PG_GETARG_INT32(1);
- RTreeScanOpaque so = (RTreeScanOpaque) s->opaque;
- Page page;
- OffsetNumber offnum;
-
- /*
- * If we've already produced a tuple and the executor has informed us that
- * it should be marked "killed", do so now.
- */
- if (s->kill_prior_tuple && ItemPointerIsValid(&(s->currentItemData)))
- {
- offnum = ItemPointerGetOffsetNumber(&(s->currentItemData));
- page = BufferGetPage(so->curbuf);
- PageGetItemId(page, offnum)->lp_flags |= LP_DELETE;
- SetBufferCommitInfoNeedsSave(so->curbuf);
- }
-
- /*
- * Get the next tuple that matches the search key; if asked to skip killed
- * tuples, find the first non-killed tuple that matches. Return as soon as
- * we've run out of matches or we've found an acceptable match.
- */
- for (;;)
- {
- bool res = rtnext(s, dir);
-
- if (res && s->ignore_killed_tuples)
- {
- offnum = ItemPointerGetOffsetNumber(&(s->currentItemData));
- page = BufferGetPage(so->curbuf);
- if (ItemIdDeleted(PageGetItemId(page, offnum)))
- continue;
- }
-
- PG_RETURN_BOOL(res);
- }
-}
-
-Datum
-rtgetmulti(PG_FUNCTION_ARGS)
-{
- IndexScanDesc s = (IndexScanDesc) PG_GETARG_POINTER(0);
- ItemPointer tids = (ItemPointer) PG_GETARG_POINTER(1);
- int32 max_tids = PG_GETARG_INT32(2);
- int32 *returned_tids = (int32 *) PG_GETARG_POINTER(3);
- RTreeScanOpaque so = (RTreeScanOpaque) s->opaque;
- bool res = true;
- int32 ntids = 0;
-
- /* XXX generic implementation: loop around guts of rtgettuple */
- while (ntids < max_tids)
- {
- res = rtnext(s, ForwardScanDirection);
- if (res && s->ignore_killed_tuples)
- {
- Page page;
- OffsetNumber offnum;
-
- offnum = ItemPointerGetOffsetNumber(&(s->currentItemData));
- page = BufferGetPage(so->curbuf);
- if (ItemIdDeleted(PageGetItemId(page, offnum)))
- continue;
- }
-
- if (!res)
- break;
- tids[ntids] = s->xs_ctup.t_self;
- ntids++;
- }
-
- *returned_tids = ntids;
- PG_RETURN_BOOL(res);
-}
-
-static bool
-rtnext(IndexScanDesc s, ScanDirection dir)
-{
- Page p;
- OffsetNumber n;
- RTreePageOpaque po;
- RTreeScanOpaque so;
-
- so = (RTreeScanOpaque) s->opaque;
-
- if (!ItemPointerIsValid(&(s->currentItemData)))
- {
- /* first call: start at the root */
- Assert(BufferIsValid(so->curbuf) == false);
- so->curbuf = ReadBuffer(s->indexRelation, P_ROOT);
- pgstat_count_index_scan(&s->xs_pgstat_info);
- }
-
- p = BufferGetPage(so->curbuf);
- po = (RTreePageOpaque) PageGetSpecialPointer(p);
-
- if (!ItemPointerIsValid(&(s->currentItemData)))
- {
- /* first call: start at first/last offset */
- if (ScanDirectionIsForward(dir))
- n = FirstOffsetNumber;
- else
- n = PageGetMaxOffsetNumber(p);
- }
- else
- {
- /* go on to the next offset */
- n = ItemPointerGetOffsetNumber(&(s->currentItemData));
- if (ScanDirectionIsForward(dir))
- n = OffsetNumberNext(n);
- else
- n = OffsetNumberPrev(n);
- }
-
- for (;;)
- {
- IndexTuple it;
- RTSTACK *stk;
-
- n = findnext(s, n, dir);
-
- /* no match on this page, so read in the next stack entry */
- if (n == InvalidOffsetNumber)
- {
- /* if out of stack entries, we're done */
- if (so->s_stack == NULL)
- {
- ReleaseBuffer(so->curbuf);
- so->curbuf = InvalidBuffer;
- return false;
- }
-
- stk = so->s_stack;
- so->curbuf = ReleaseAndReadBuffer(so->curbuf, s->indexRelation,
- stk->rts_blk);
- p = BufferGetPage(so->curbuf);
- 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);
-
- continue;
- }
-
- if (po->flags & F_LEAF)
- {
- ItemPointerSet(&(s->currentItemData),
- BufferGetBlockNumber(so->curbuf),
- n);
- it = (IndexTuple) PageGetItem(p, PageGetItemId(p, n));
- s->xs_ctup.t_self = it->t_tid;
- return true;
- }
- else
- {
- BlockNumber blk;
-
- stk = (RTSTACK *) palloc(sizeof(RTSTACK));
- stk->rts_child = n;
- stk->rts_blk = BufferGetBlockNumber(so->curbuf);
- stk->rts_parent = so->s_stack;
- so->s_stack = stk;
-
- it = (IndexTuple) PageGetItem(p, PageGetItemId(p, n));
- blk = ItemPointerGetBlockNumber(&(it->t_tid));
-
- /*
- * Note that we release the pin on the page as we descend down the
- * tree, even though there's a good chance we'll eventually need
- * to re-read the buffer later in this scan. This may or may not
- * be optimal, but it doesn't seem likely to make a huge
- * performance difference either way.
- */
- so->curbuf = ReleaseAndReadBuffer(so->curbuf, s->indexRelation, blk);
- p = BufferGetPage(so->curbuf);
- po = (RTreePageOpaque) PageGetSpecialPointer(p);
-
- if (ScanDirectionIsBackward(dir))
- n = PageGetMaxOffsetNumber(p);
- else
- n = FirstOffsetNumber;
- }
- }
-}
-
-/*
- * Return the offset of the next matching index entry. We begin the
- * search at offset "n" and search for matches in the direction
- * "dir". If no more matching entries are found on the page,
- * InvalidOffsetNumber is returned.
- */
-static OffsetNumber
-findnext(IndexScanDesc s, OffsetNumber n, ScanDirection dir)
-{
- OffsetNumber maxoff;
- IndexTuple it;
- RTreePageOpaque po;
- RTreeScanOpaque so;
- Page p;
-
- so = (RTreeScanOpaque) s->opaque;
- p = BufferGetPage(so->curbuf);
-
- maxoff = PageGetMaxOffsetNumber(p);
- po = (RTreePageOpaque) PageGetSpecialPointer(p);
-
- /*
- * 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,
- RelationGetDescr(s->indexRelation),
- s->numberOfKeys, s->keyData))
- break;
- }
- else
- {
- if (index_keytest(it,
- RelationGetDescr(s->indexRelation),
- so->s_internalNKey, so->s_internalKey))
- break;
- }
-
- if (ScanDirectionIsBackward(dir))
- n = OffsetNumberPrev(n);
- else
- n = OffsetNumberNext(n);
- }
-
- if (n >= FirstOffsetNumber && n <= maxoff)
- return n; /* found a match on this page */
- else
- return InvalidOffsetNumber; /* no match, go to next page */
-}