1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-10 17:42:29 +03:00

Restructure indexscan API (index_beginscan, index_getnext) per

yesterday's proposal to pghackers.  Also remove unnecessary parameters
to heap_beginscan, heap_rescan.  I modified pg_proc.h to reflect the
new numbers of parameters for the AM interface routines, but did not
force an initdb because nothing actually looks at those fields.
This commit is contained in:
Tom Lane
2002-05-20 23:51:44 +00:00
parent c961474c96
commit 44fbe20d62
59 changed files with 834 additions and 1283 deletions

View File

@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/common/indextuple.c,v 1.55 2001/10/25 05:49:20 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/access/common/indextuple.c,v 1.56 2002/05/20 23:51:40 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -398,23 +398,6 @@ nocache_index_getattr(IndexTuple tup,
}
}
RetrieveIndexResult
FormRetrieveIndexResult(ItemPointer indexItemPointer,
ItemPointer heapItemPointer)
{
RetrieveIndexResult result;
Assert(ItemPointerIsValid(indexItemPointer));
Assert(ItemPointerIsValid(heapItemPointer));
result = (RetrieveIndexResult) palloc(sizeof *result);
result->index_iptr = *indexItemPointer;
result->heap_iptr = *heapItemPointer;
return result;
}
/*
* Copies source into target. If *target == NULL, we palloc space; otherwise
* we assume we have space that is already palloc'ed.
@@ -423,12 +406,10 @@ void
CopyIndexTuple(IndexTuple source, IndexTuple *target)
{
Size size;
IndexTuple ret;
size = IndexTupleSize(source);
if (*target == NULL)
*target = (IndexTuple) palloc(size);
ret = *target;
memmove((char *) ret, (char *) source, size);
memmove((char *) *target, (char *) source, size);
}

View File

@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/gist/gist.c,v 1.91 2002/03/06 06:09:15 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/access/gist/gist.c,v 1.92 2002/05/20 23:51:40 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1590,7 +1590,6 @@ gistbulkdelete(PG_FUNCTION_ARGS)
BlockNumber num_pages;
double tuples_removed;
double num_index_tuples;
RetrieveIndexResult res;
IndexScanDesc iscan;
tuples_removed = 0;
@@ -1607,23 +1606,20 @@ gistbulkdelete(PG_FUNCTION_ARGS)
*/
/* walk through the entire index */
iscan = index_beginscan(rel, false, 0, (ScanKey) NULL);
iscan = index_beginscan(NULL, rel, SnapshotAny, 0, (ScanKey) NULL);
while ((res = index_getnext(iscan, ForwardScanDirection))
!= (RetrieveIndexResult) NULL)
while (index_getnext_indexitem(iscan, ForwardScanDirection))
{
ItemPointer heapptr = &res->heap_iptr;
if (callback(heapptr, callback_state))
if (callback(&iscan->xs_ctup.t_self, callback_state))
{
ItemPointer indexptr = &res->index_iptr;
ItemPointerData indextup = iscan->currentItemData;
BlockNumber blkno;
OffsetNumber offnum;
Buffer buf;
Page page;
blkno = ItemPointerGetBlockNumber(indexptr);
offnum = ItemPointerGetOffsetNumber(indexptr);
blkno = ItemPointerGetBlockNumber(&indextup);
offnum = ItemPointerGetOffsetNumber(&indextup);
/* adjust any scans that will be affected by this deletion */
gistadjscans(rel, GISTOP_DEL, blkno, offnum);
@@ -1640,8 +1636,6 @@ gistbulkdelete(PG_FUNCTION_ARGS)
}
else
num_index_tuples += 1;
pfree(res);
}
index_endscan(iscan);

View File

@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/gist/gistget.c,v 1.32 2002/03/05 05:30:31 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/access/gist/gistget.c,v 1.33 2002/05/20 23:51:41 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -20,10 +20,9 @@
static OffsetNumber gistfindnext(IndexScanDesc s, Page p, OffsetNumber n,
ScanDirection dir);
static RetrieveIndexResult gistscancache(IndexScanDesc s, ScanDirection dir);
static RetrieveIndexResult gistfirst(IndexScanDesc s, ScanDirection dir);
static RetrieveIndexResult gistnext(IndexScanDesc s, ScanDirection dir);
static ItemPointer gistheapptr(Relation r, ItemPointer itemp);
static bool gistscancache(IndexScanDesc s, ScanDirection dir);
static bool gistfirst(IndexScanDesc s, ScanDirection dir);
static bool gistnext(IndexScanDesc s, ScanDirection dir);
static bool gistindex_keytest(IndexTuple tuple,
int scanKeySize, ScanKey key, GISTSTATE *giststate,
Relation r, Page p, OffsetNumber offset);
@@ -34,35 +33,34 @@ gistgettuple(PG_FUNCTION_ARGS)
{
IndexScanDesc s = (IndexScanDesc) PG_GETARG_POINTER(0);
ScanDirection dir = (ScanDirection) PG_GETARG_INT32(1);
RetrieveIndexResult res;
bool res;
/* if we have it cached in the scan desc, just return the value */
if ((res = gistscancache(s, dir)) != (RetrieveIndexResult) NULL)
PG_RETURN_POINTER(res);
if (gistscancache(s, dir))
PG_RETURN_BOOL(true);
/* not cached, so we'll have to do some work */
if (ItemPointerIsValid(&(s->currentItemData)))
res = gistnext(s, dir);
else
res = gistfirst(s, dir);
PG_RETURN_POINTER(res);
PG_RETURN_BOOL(res);
}
static RetrieveIndexResult
static bool
gistfirst(IndexScanDesc s, ScanDirection dir)
{
Buffer b;
Page p;
OffsetNumber n;
OffsetNumber maxoff;
RetrieveIndexResult res;
GISTPageOpaque po;
GISTScanOpaque so;
GISTSTACK *stk;
BlockNumber blk;
IndexTuple it;
b = ReadBuffer(s->relation, GISTP_ROOT);
b = ReadBuffer(s->indexRelation, GISTP_ROOT);
p = BufferGetPage(b);
po = (GISTPageOpaque) PageGetSpecialPointer(p);
so = (GISTScanOpaque) s->opaque;
@@ -77,13 +75,12 @@ gistfirst(IndexScanDesc s, ScanDirection dir)
while (n < FirstOffsetNumber || n > maxoff)
{
ReleaseBuffer(b);
if (so->s_stack == (GISTSTACK *) NULL)
return (RetrieveIndexResult) NULL;
return false;
stk = so->s_stack;
b = ReadBuffer(s->relation, stk->gs_blk);
b = ReadBuffer(s->indexRelation, stk->gs_blk);
p = BufferGetPage(b);
po = (GISTPageOpaque) PageGetSpecialPointer(p);
maxoff = PageGetMaxOffsetNumber(p);
@@ -103,10 +100,10 @@ gistfirst(IndexScanDesc s, ScanDirection dir)
it = (IndexTuple) PageGetItem(p, PageGetItemId(p, n));
res = FormRetrieveIndexResult(&(s->currentItemData), &(it->t_tid));
s->xs_ctup.t_self = it->t_tid;
ReleaseBuffer(b);
return res;
return true;
}
else
{
@@ -120,21 +117,20 @@ gistfirst(IndexScanDesc s, ScanDirection dir)
blk = ItemPointerGetBlockNumber(&(it->t_tid));
ReleaseBuffer(b);
b = ReadBuffer(s->relation, blk);
b = ReadBuffer(s->indexRelation, blk);
p = BufferGetPage(b);
po = (GISTPageOpaque) PageGetSpecialPointer(p);
}
}
}
static RetrieveIndexResult
static bool
gistnext(IndexScanDesc s, ScanDirection dir)
{
Buffer b;
Page p;
OffsetNumber n;
OffsetNumber maxoff;
RetrieveIndexResult res;
GISTPageOpaque po;
GISTScanOpaque so;
GISTSTACK *stk;
@@ -149,7 +145,7 @@ gistnext(IndexScanDesc s, ScanDirection dir)
else
n = OffsetNumberPrev(n);
b = ReadBuffer(s->relation, blk);
b = ReadBuffer(s->indexRelation, blk);
p = BufferGetPage(b);
po = (GISTPageOpaque) PageGetSpecialPointer(p);
so = (GISTScanOpaque) s->opaque;
@@ -161,13 +157,12 @@ gistnext(IndexScanDesc s, ScanDirection dir)
while (n < FirstOffsetNumber || n > maxoff)
{
ReleaseBuffer(b);
if (so->s_stack == (GISTSTACK *) NULL)
return (RetrieveIndexResult) NULL;
return false;
stk = so->s_stack;
b = ReadBuffer(s->relation, stk->gs_blk);
b = ReadBuffer(s->indexRelation, stk->gs_blk);
p = BufferGetPage(b);
maxoff = PageGetMaxOffsetNumber(p);
po = (GISTPageOpaque) PageGetSpecialPointer(p);
@@ -187,10 +182,10 @@ gistnext(IndexScanDesc s, ScanDirection dir)
it = (IndexTuple) PageGetItem(p, PageGetItemId(p, n));
res = FormRetrieveIndexResult(&(s->currentItemData), &(it->t_tid));
s->xs_ctup.t_self = it->t_tid;
ReleaseBuffer(b);
return res;
return true;
}
else
{
@@ -204,7 +199,7 @@ gistnext(IndexScanDesc s, ScanDirection dir)
blk = ItemPointerGetBlockNumber(&(it->t_tid));
ReleaseBuffer(b);
b = ReadBuffer(s->relation, blk);
b = ReadBuffer(s->indexRelation, blk);
p = BufferGetPage(b);
po = (GISTPageOpaque) PageGetSpecialPointer(p);
@@ -233,7 +228,6 @@ gistindex_keytest(IndexTuple tuple,
IncrIndexProcessed();
while (scanKeySize > 0)
{
datum = index_getattr(tuple,
@@ -314,7 +308,7 @@ gistfindnext(IndexScanDesc s, Page p, OffsetNumber n, ScanDirection dir)
it = (IndexTuple) PageGetItem(p, PageGetItemId(p, n));
if (gistindex_keytest(it,
s->numberOfKeys, s->keyData, giststate,
s->relation, p, n))
s->indexRelation, p, n))
break;
if (ScanDirectionIsBackward(dir))
@@ -326,57 +320,25 @@ gistfindnext(IndexScanDesc s, Page p, OffsetNumber n, ScanDirection dir)
return n;
}
static RetrieveIndexResult
static bool
gistscancache(IndexScanDesc s, ScanDirection dir)
{
RetrieveIndexResult res;
ItemPointer ip;
if (!(ScanDirectionIsNoMovement(dir)
&& ItemPointerIsValid(&(s->currentItemData))))
{
return (RetrieveIndexResult) NULL;
}
ip = gistheapptr(s->relation, &(s->currentItemData));
if (ItemPointerIsValid(ip))
res = FormRetrieveIndexResult(&(s->currentItemData), ip);
else
res = (RetrieveIndexResult) NULL;
pfree(ip);
return res;
}
/*
* gistheapptr returns the item pointer to the tuple in the heap relation
* for which itemp is the index relation item pointer.
*/
static ItemPointer
gistheapptr(Relation r, ItemPointer itemp)
{
Buffer b;
Page p;
IndexTuple it;
ItemPointer ip;
OffsetNumber n;
IndexTuple it;
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);
if (!(ScanDirectionIsNoMovement(dir)
&& ItemPointerIsValid(&(s->currentItemData))))
return false;
return ip;
b = ReadBuffer(s->indexRelation,
ItemPointerGetBlockNumber(&(s->currentItemData)));
p = BufferGetPage(b);
n = ItemPointerGetOffsetNumber(&(s->currentItemData));
it = (IndexTuple) PageGetItem(p, PageGetItemId(p, n));
s->xs_ctup.t_self = it->t_tid;
ReleaseBuffer(b);
return true;
}

View File

@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/gist/gistscan.c,v 1.41 2002/03/05 05:30:35 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/access/gist/gistscan.c,v 1.42 2002/05/20 23:51:41 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -53,12 +53,11 @@ Datum
gistbeginscan(PG_FUNCTION_ARGS)
{
Relation r = (Relation) PG_GETARG_POINTER(0);
bool fromEnd = PG_GETARG_BOOL(1);
uint16 nkeys = PG_GETARG_UINT16(2);
ScanKey key = (ScanKey) PG_GETARG_POINTER(3);
int nkeys = PG_GETARG_INT32(1);
ScanKey key = (ScanKey) PG_GETARG_POINTER(2);
IndexScanDesc s;
s = RelationGetIndexScan(r, fromEnd, nkeys, key);
s = RelationGetIndexScan(r, nkeys, key);
gistregscan(s);
@@ -69,8 +68,7 @@ Datum
gistrescan(PG_FUNCTION_ARGS)
{
IndexScanDesc s = (IndexScanDesc) PG_GETARG_POINTER(0);
bool fromEnd = PG_GETARG_BOOL(1);
ScanKey key = (ScanKey) PG_GETARG_POINTER(2);
ScanKey key = (ScanKey) PG_GETARG_POINTER(1);
GISTScanOpaque p;
int i;
@@ -80,18 +78,6 @@ gistrescan(PG_FUNCTION_ARGS)
ItemPointerSetInvalid(&s->currentItemData);
ItemPointerSetInvalid(&s->currentMarkData);
/*
* Set flags.
*/
if (RelationGetNumberOfBlocks(s->relation) == 0)
s->flags = ScanUnmarked;
else if (fromEnd)
s->flags = ScanUnmarked | ScanUncheckedPrevious;
else
s->flags = ScanUnmarked | ScanUncheckedNext;
s->scanFromEnd = fromEnd;
if (s->numberOfKeys > 0)
{
memmove(s->keyData,
@@ -109,7 +95,8 @@ gistrescan(PG_FUNCTION_ARGS)
for (i = 0; i < s->numberOfKeys; i++)
{
s->keyData[i].sk_procedure
= RelationGetGISTStrategy(s->relation, s->keyData[i].sk_attno,
= RelationGetGISTStrategy(s->indexRelation,
s->keyData[i].sk_attno,
s->keyData[i].sk_procedure);
s->keyData[i].sk_func = p->giststate->consistentFn[s->keyData[i].sk_attno - 1];
}
@@ -122,7 +109,7 @@ gistrescan(PG_FUNCTION_ARGS)
p->s_flags = 0x0;
s->opaque = p;
p->giststate = (GISTSTATE *) palloc(sizeof(GISTSTATE));
initGISTstate(p->giststate, s->relation);
initGISTstate(p->giststate, s->indexRelation);
if (s->numberOfKeys > 0)
/*
@@ -133,15 +120,10 @@ gistrescan(PG_FUNCTION_ARGS)
*/
for (i = 0; i < s->numberOfKeys; i++)
{
/*----------
* s->keyData[i].sk_procedure =
* index_getprocid(s->relation, 1, GIST_CONSISTENT_PROC);
*----------
*/
s->keyData[i].sk_procedure
= RelationGetGISTStrategy(s->relation, s->keyData[i].sk_attno,
s->keyData[i].sk_procedure);
s->keyData[i].sk_procedure =
RelationGetGISTStrategy(s->indexRelation,
s->keyData[i].sk_attno,
s->keyData[i].sk_procedure);
s->keyData[i].sk_func = p->giststate->consistentFn[s->keyData[i].sk_attno - 1];
}
}
@@ -309,7 +291,7 @@ gistadjscans(Relation rel, int op, BlockNumber blkno, OffsetNumber offnum)
relid = RelationGetRelid(rel);
for (l = GISTScans; l != (GISTScanList) NULL; l = l->gsl_next)
{
if (l->gsl_scan->relation->rd_id == relid)
if (l->gsl_scan->indexRelation->rd_id == relid)
gistadjone(l->gsl_scan, op, blkno, offnum);
}
}

View File

@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/hash/hash.c,v 1.56 2002/03/09 17:35:35 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/access/hash/hash.c,v 1.57 2002/05/20 23:51:41 tgl Exp $
*
* NOTES
* This file contains only the public interface routines.
@@ -210,7 +210,7 @@ hashgettuple(PG_FUNCTION_ARGS)
{
IndexScanDesc scan = (IndexScanDesc) PG_GETARG_POINTER(0);
ScanDirection dir = (ScanDirection) PG_GETARG_INT32(1);
RetrieveIndexResult res;
bool res;
/*
* If we've already initialized this scan, we can just advance it in
@@ -223,7 +223,7 @@ hashgettuple(PG_FUNCTION_ARGS)
else
res = _hash_first(scan, dir);
PG_RETURN_POINTER(res);
PG_RETURN_BOOL(res);
}
@@ -234,17 +234,15 @@ Datum
hashbeginscan(PG_FUNCTION_ARGS)
{
Relation rel = (Relation) PG_GETARG_POINTER(0);
bool fromEnd = PG_GETARG_BOOL(1);
uint16 keysz = PG_GETARG_UINT16(2);
ScanKey scankey = (ScanKey) PG_GETARG_POINTER(3);
int keysz = PG_GETARG_INT32(1);
ScanKey scankey = (ScanKey) PG_GETARG_POINTER(2);
IndexScanDesc scan;
HashScanOpaque so;
scan = RelationGetIndexScan(rel, fromEnd, keysz, scankey);
scan = RelationGetIndexScan(rel, keysz, scankey);
so = (HashScanOpaque) palloc(sizeof(HashScanOpaqueData));
so->hashso_curbuf = so->hashso_mrkbuf = InvalidBuffer;
scan->opaque = so;
scan->flags = 0x0;
/* register scan in case we change pages it's using */
_hash_regscan(scan);
@@ -259,11 +257,7 @@ Datum
hashrescan(PG_FUNCTION_ARGS)
{
IndexScanDesc scan = (IndexScanDesc) PG_GETARG_POINTER(0);
#ifdef NOT_USED /* XXX surely it's wrong to ignore this? */
bool fromEnd = PG_GETARG_BOOL(1);
#endif
ScanKey scankey = (ScanKey) PG_GETARG_POINTER(2);
ScanKey scankey = (ScanKey) PG_GETARG_POINTER(1);
ItemPointer iptr;
HashScanOpaque so;
@@ -272,13 +266,13 @@ hashrescan(PG_FUNCTION_ARGS)
/* we hold a read lock on the current page in the scan */
if (ItemPointerIsValid(iptr = &(scan->currentItemData)))
{
_hash_relbuf(scan->relation, so->hashso_curbuf, HASH_READ);
_hash_relbuf(scan->indexRelation, so->hashso_curbuf, HASH_READ);
so->hashso_curbuf = InvalidBuffer;
ItemPointerSetInvalid(iptr);
}
if (ItemPointerIsValid(iptr = &(scan->currentMarkData)))
{
_hash_relbuf(scan->relation, so->hashso_mrkbuf, HASH_READ);
_hash_relbuf(scan->indexRelation, so->hashso_mrkbuf, HASH_READ);
so->hashso_mrkbuf = InvalidBuffer;
ItemPointerSetInvalid(iptr);
}
@@ -309,7 +303,7 @@ hashendscan(PG_FUNCTION_ARGS)
/* release any locks we still hold */
if (ItemPointerIsValid(iptr = &(scan->currentItemData)))
{
_hash_relbuf(scan->relation, so->hashso_curbuf, HASH_READ);
_hash_relbuf(scan->indexRelation, so->hashso_curbuf, HASH_READ);
so->hashso_curbuf = InvalidBuffer;
ItemPointerSetInvalid(iptr);
}
@@ -317,7 +311,7 @@ hashendscan(PG_FUNCTION_ARGS)
if (ItemPointerIsValid(iptr = &(scan->currentMarkData)))
{
if (BufferIsValid(so->hashso_mrkbuf))
_hash_relbuf(scan->relation, so->hashso_mrkbuf, HASH_READ);
_hash_relbuf(scan->indexRelation, so->hashso_mrkbuf, HASH_READ);
so->hashso_mrkbuf = InvalidBuffer;
ItemPointerSetInvalid(iptr);
}
@@ -346,7 +340,7 @@ hashmarkpos(PG_FUNCTION_ARGS)
/* release lock on old marked data, if any */
if (ItemPointerIsValid(iptr = &(scan->currentMarkData)))
{
_hash_relbuf(scan->relation, so->hashso_mrkbuf, HASH_READ);
_hash_relbuf(scan->indexRelation, so->hashso_mrkbuf, HASH_READ);
so->hashso_mrkbuf = InvalidBuffer;
ItemPointerSetInvalid(iptr);
}
@@ -354,7 +348,7 @@ hashmarkpos(PG_FUNCTION_ARGS)
/* bump lock on currentItemData and copy to currentMarkData */
if (ItemPointerIsValid(&(scan->currentItemData)))
{
so->hashso_mrkbuf = _hash_getbuf(scan->relation,
so->hashso_mrkbuf = _hash_getbuf(scan->indexRelation,
BufferGetBlockNumber(so->hashso_curbuf),
HASH_READ);
scan->currentMarkData = scan->currentItemData;
@@ -378,7 +372,7 @@ hashrestrpos(PG_FUNCTION_ARGS)
/* release lock on current data, if any */
if (ItemPointerIsValid(iptr = &(scan->currentItemData)))
{
_hash_relbuf(scan->relation, so->hashso_curbuf, HASH_READ);
_hash_relbuf(scan->indexRelation, so->hashso_curbuf, HASH_READ);
so->hashso_curbuf = InvalidBuffer;
ItemPointerSetInvalid(iptr);
}
@@ -386,7 +380,7 @@ hashrestrpos(PG_FUNCTION_ARGS)
/* bump lock on currentMarkData and copy to currentItemData */
if (ItemPointerIsValid(&(scan->currentMarkData)))
{
so->hashso_curbuf = _hash_getbuf(scan->relation,
so->hashso_curbuf = _hash_getbuf(scan->indexRelation,
BufferGetBlockNumber(so->hashso_mrkbuf),
HASH_READ);
@@ -413,7 +407,6 @@ hashbulkdelete(PG_FUNCTION_ARGS)
BlockNumber num_pages;
double tuples_removed;
double num_index_tuples;
RetrieveIndexResult res;
IndexScanDesc iscan;
tuples_removed = 0;
@@ -424,30 +417,25 @@ hashbulkdelete(PG_FUNCTION_ARGS)
*/
/* walk through the entire index */
iscan = index_beginscan(rel, false, 0, (ScanKey) NULL);
iscan = index_beginscan(NULL, rel, SnapshotAny, 0, (ScanKey) NULL);
while ((res = index_getnext(iscan, ForwardScanDirection))
!= (RetrieveIndexResult) NULL)
while (index_getnext_indexitem(iscan, ForwardScanDirection))
{
ItemPointer heapptr = &res->heap_iptr;
if (callback(heapptr, callback_state))
if (callback(&iscan->xs_ctup.t_self, callback_state))
{
ItemPointer indexptr = &res->index_iptr;
ItemPointerData indextup = iscan->currentItemData;
/* adjust any active scans that will be affected by deletion */
/* (namely, my own scan) */
_hash_adjscans(rel, indexptr);
_hash_adjscans(rel, &indextup);
/* delete the data from the page */
_hash_pagedel(rel, indexptr);
_hash_pagedel(rel, &indextup);
tuples_removed += 1;
}
else
num_index_tuples += 1;
pfree(res);
}
index_endscan(iscan);

View File

@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/hash/hashscan.c,v 1.25 2001/07/15 22:48:15 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/access/hash/hashscan.c,v 1.26 2002/05/20 23:51:41 tgl Exp $
*
* NOTES
* Because we can be doing an index scan on a relation while we
@@ -119,7 +119,7 @@ _hash_adjscans(Relation rel, ItemPointer tid)
relid = RelationGetRelid(rel);
for (l = HashScans; l != (HashScanList) NULL; l = l->hashsl_next)
{
if (relid == l->hashsl_scan->relation->rd_id)
if (relid == l->hashsl_scan->indexRelation->rd_id)
_hash_scandel(l->hashsl_scan, ItemPointerGetBlockNumber(tid),
ItemPointerGetOffsetNumber(tid));
}
@@ -136,7 +136,7 @@ _hash_scandel(IndexScanDesc scan, BlockNumber blkno, OffsetNumber offno)
if (!_hash_scantouched(scan, blkno, offno))
return;
metabuf = _hash_getbuf(scan->relation, HASH_METAPAGE, HASH_READ);
metabuf = _hash_getbuf(scan->indexRelation, HASH_METAPAGE, HASH_READ);
so = (HashScanOpaque) scan->opaque;
buf = so->hashso_curbuf;

View File

@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/hash/hashsearch.c,v 1.27 2001/10/25 05:49:21 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/access/hash/hashsearch.c,v 1.28 2002/05/20 23:51:41 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -59,7 +59,7 @@ _hash_search(Relation rel,
* exit, we have the page containing the next item locked but not
* pinned.
*/
RetrieveIndexResult
bool
_hash_next(IndexScanDesc scan, ScanDirection dir)
{
Relation rel;
@@ -67,13 +67,12 @@ _hash_next(IndexScanDesc scan, ScanDirection dir)
Buffer metabuf;
Page page;
OffsetNumber offnum;
RetrieveIndexResult res;
ItemPointer current;
HashItem hitem;
IndexTuple itup;
HashScanOpaque so;
rel = scan->relation;
rel = scan->indexRelation;
so = (HashScanOpaque) scan->opaque;
current = &(scan->currentItemData);
@@ -101,7 +100,7 @@ _hash_next(IndexScanDesc scan, ScanDirection dir)
* next tuple, we come back with a lock on that buffer.
*/
if (!_hash_step(scan, &buf, dir, metabuf))
return (RetrieveIndexResult) NULL;
return false;
/* if we're here, _hash_step found a valid tuple */
current = &(scan->currentItemData);
@@ -110,9 +109,9 @@ _hash_next(IndexScanDesc scan, ScanDirection dir)
_hash_checkpage(page, LH_BUCKET_PAGE | LH_OVERFLOW_PAGE);
hitem = (HashItem) PageGetItem(page, PageGetItemId(page, offnum));
itup = &hitem->hash_itup;
res = FormRetrieveIndexResult(current, &(itup->t_tid));
scan->xs_ctup.t_self = itup->t_tid;
return res;
return true;
}
static void
@@ -161,13 +160,13 @@ _hash_readprev(Relation rel,
/*
* _hash_first() -- Find the first item in a scan.
*
* Return the RetrieveIndexResult of the first item in the tree that
* satisfies the qualificatin associated with the scan descriptor. On
* Find the first item in the tree that
* satisfies the qualification associated with the scan descriptor. On
* exit, the page containing the current index tuple is read locked
* and pinned, and the scan's opaque data entry is updated to
* include the buffer.
*/
RetrieveIndexResult
bool
_hash_first(IndexScanDesc scan, ScanDirection dir)
{
Relation rel;
@@ -180,10 +179,9 @@ _hash_first(IndexScanDesc scan, ScanDirection dir)
IndexTuple itup;
ItemPointer current;
OffsetNumber offnum;
RetrieveIndexResult res;
HashScanOpaque so;
rel = scan->relation;
rel = scan->indexRelation;
so = (HashScanOpaque) scan->opaque;
current = &(scan->currentItemData);
@@ -230,7 +228,7 @@ _hash_first(IndexScanDesc scan, ScanDirection dir)
{
_hash_relbuf(rel, buf, HASH_READ);
_hash_relbuf(rel, metabuf, HASH_READ);
return (RetrieveIndexResult) NULL;
return false;
}
}
}
@@ -241,7 +239,7 @@ _hash_first(IndexScanDesc scan, ScanDirection dir)
}
if (!_hash_step(scan, &buf, dir, metabuf))
return (RetrieveIndexResult) NULL;
return false;
/* if we're here, _hash_step found a valid tuple */
current = &(scan->currentItemData);
@@ -250,9 +248,9 @@ _hash_first(IndexScanDesc scan, ScanDirection dir)
_hash_checkpage(page, LH_BUCKET_PAGE | LH_OVERFLOW_PAGE);
hitem = (HashItem) PageGetItem(page, PageGetItemId(page, offnum));
itup = &hitem->hash_itup;
res = FormRetrieveIndexResult(current, &(itup->t_tid));
scan->xs_ctup.t_self = itup->t_tid;
return res;
return true;
}
/*
@@ -285,7 +283,7 @@ _hash_step(IndexScanDesc scan, Buffer *bufP, ScanDirection dir, Buffer metabuf)
HashItem hitem;
IndexTuple itup;
rel = scan->relation;
rel = scan->indexRelation;
current = &(scan->currentItemData);
so = (HashScanOpaque) scan->opaque;
allbuckets = (scan->numberOfKeys < 1);

View File

@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/hash/hashutil.c,v 1.28 2002/03/06 20:49:43 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/access/hash/hashutil.c,v 1.29 2002/05/20 23:51:41 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -63,7 +63,7 @@ _hash_checkqual(IndexScanDesc scan, IndexTuple itup)
{
if (scan->numberOfKeys > 0)
return (index_keytest(itup,
RelationGetDescr(scan->relation),
RelationGetDescr(scan->indexRelation),
scan->numberOfKeys, scan->keyData));
else
return true;

View File

@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.133 2002/05/01 01:23:37 inoue Exp $
* $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.134 2002/05/20 23:51:41 tgl Exp $
*
*
* INTERFACE ROUTINES
@@ -24,7 +24,7 @@
* heap_rescan - restart a relation scan
* heap_endscan - end relation scan
* heap_getnext - retrieve next tuple in scan
* heap_fetch - retrive tuple with tid
* heap_fetch - retrieve tuple with tid
* heap_insert - insert tuple into a relation
* heap_delete - delete a tuple from a relation
* heap_update - replace a tuple in a relation with another tuple
@@ -70,11 +70,7 @@ static XLogRecPtr log_heap_update(Relation reln, Buffer oldbuf,
* ----------------
*/
static void
initscan(HeapScanDesc scan,
Relation relation,
int atend,
unsigned nkeys,
ScanKey key)
initscan(HeapScanDesc scan, ScanKey key)
{
/*
* Make sure we have up-to-date idea of number of blocks in relation.
@@ -82,7 +78,7 @@ initscan(HeapScanDesc scan,
* added while the scan is in progress will be invisible to my
* transaction anyway...
*/
relation->rd_nblocks = RelationGetNumberOfBlocks(relation);
scan->rs_rd->rd_nblocks = RelationGetNumberOfBlocks(scan->rs_rd);
scan->rs_ctup.t_datamcxt = NULL;
scan->rs_ctup.t_data = NULL;
@@ -95,7 +91,7 @@ initscan(HeapScanDesc scan,
* copy the scan key, if appropriate
*/
if (key != NULL)
memmove(scan->rs_key, key, nkeys * sizeof(ScanKeyData));
memcpy(scan->rs_key, key, scan->rs_nkeys * sizeof(ScanKeyData));
}
/* ----------------
@@ -185,7 +181,7 @@ heapgettup(Relation relation,
/*
* calculate next starting lineoff, given scan direction
*/
if (!dir)
if (dir == 0)
{
/*
* ``no movement'' scan direction: refetch same tuple
@@ -216,8 +212,8 @@ heapgettup(Relation relation,
tuple->t_data = (HeapTupleHeader) PageGetItem((Page) dp, lpp);
tuple->t_len = ItemIdGetLength(lpp);
LockBuffer(*buffer, BUFFER_LOCK_UNLOCK);
return;
return;
}
else if (dir < 0)
{
@@ -255,7 +251,6 @@ heapgettup(Relation relation,
OffsetNumberPrev(ItemPointerGetOffsetNumber(tid));
}
/* page and lineoff now reference the physically previous tid */
}
else
{
@@ -287,7 +282,6 @@ heapgettup(Relation relation,
dp = (Page) BufferGetPage(*buffer);
lines = PageGetMaxOffsetNumber(dp);
/* page and lineoff now reference the physically next tid */
}
/* 'dir' is now non-zero */
@@ -675,11 +669,8 @@ heap_openr(const char *sysRelationName, LOCKMODE lockmode)
* ----------------
*/
HeapScanDesc
heap_beginscan(Relation relation,
int atend,
Snapshot snapshot,
unsigned nkeys,
ScanKey key)
heap_beginscan(Relation relation, Snapshot snapshot,
int nkeys, ScanKey key)
{
HeapScanDesc scan;
@@ -715,20 +706,20 @@ heap_beginscan(Relation relation,
scan->rs_rd = relation;
scan->rs_snapshot = snapshot;
scan->rs_nkeys = (short) nkeys;
pgstat_initstats(&scan->rs_pgstat_info, relation);
scan->rs_nkeys = nkeys;
/*
* we do this here instead of in initscan() because heap_rescan also
* calls initscan() and we don't want to allocate memory again
*/
if (nkeys)
if (nkeys > 0)
scan->rs_key = (ScanKey) palloc(sizeof(ScanKeyData) * nkeys);
else
scan->rs_key = NULL;
initscan(scan, relation, atend, nkeys, key);
pgstat_initstats(&scan->rs_pgstat_info, relation);
initscan(scan, key);
return scan;
}
@@ -739,7 +730,6 @@ heap_beginscan(Relation relation,
*/
void
heap_rescan(HeapScanDesc scan,
bool scanFromEnd,
ScanKey key)
{
/*
@@ -757,7 +747,7 @@ heap_rescan(HeapScanDesc scan,
/*
* reinitialize scan descriptor
*/
initscan(scan, scan->rs_rd, scanFromEnd, scan->rs_nkeys, key);
initscan(scan, key);
pgstat_reset_heap_scan(&scan->rs_pgstat_info);
}
@@ -808,14 +798,14 @@ heap_endscan(HeapScanDesc scan)
#ifdef HEAPDEBUGALL
#define HEAPDEBUG_1 \
elog(LOG, "heap_getnext([%s,nkeys=%d],backw=%d) called", \
RelationGetRelationName(scan->rs_rd), scan->rs_nkeys, backw)
elog(LOG, "heap_getnext([%s,nkeys=%d],dir=%d) called", \
RelationGetRelationName(scan->rs_rd), scan->rs_nkeys, (int) direction)
#define HEAPDEBUG_2 \
elog(LOG, "heap_getnext returning EOS")
#define HEAPDEBUG_3 \
elog(LOG, "heap_getnext returning tuple");
elog(LOG, "heap_getnext returning tuple")
#else
#define HEAPDEBUG_1
#define HEAPDEBUG_2
@@ -824,7 +814,7 @@ elog(LOG, "heap_getnext([%s,nkeys=%d],backw=%d) called", \
HeapTuple
heap_getnext(HeapScanDesc scan, int backw)
heap_getnext(HeapScanDesc scan, ScanDirection direction)
{
/*
* increment access statistics
@@ -842,43 +832,21 @@ heap_getnext(HeapScanDesc scan, int backw)
HEAPDEBUG_1; /* heap_getnext( info ) */
if (backw)
{
/*
* handle reverse scan
*/
heapgettup(scan->rs_rd,
-1,
&(scan->rs_ctup),
&(scan->rs_cbuf),
scan->rs_snapshot,
scan->rs_nkeys,
scan->rs_key);
/*
* Note: we depend here on the -1/0/1 encoding of ScanDirection.
*/
heapgettup(scan->rs_rd,
(int) direction,
&(scan->rs_ctup),
&(scan->rs_cbuf),
scan->rs_snapshot,
scan->rs_nkeys,
scan->rs_key);
if (scan->rs_ctup.t_data == NULL && !BufferIsValid(scan->rs_cbuf))
{
HEAPDEBUG_2; /* heap_getnext returning EOS */
return NULL;
}
}
else
if (scan->rs_ctup.t_data == NULL && !BufferIsValid(scan->rs_cbuf))
{
/*
* handle forward scan
*/
heapgettup(scan->rs_rd,
1,
&(scan->rs_ctup),
&(scan->rs_cbuf),
scan->rs_snapshot,
scan->rs_nkeys,
scan->rs_key);
if (scan->rs_ctup.t_data == NULL && !BufferIsValid(scan->rs_cbuf))
{
HEAPDEBUG_2; /* heap_getnext returning EOS */
return NULL;
}
HEAPDEBUG_2; /* heap_getnext returning EOS */
return NULL;
}
pgstat_count_heap_scan(&scan->rs_pgstat_info);
@@ -897,16 +865,17 @@ heap_getnext(HeapScanDesc scan, int backw)
}
/* ----------------
* heap_fetch - retrive tuple with tid
* heap_fetch - retrieve tuple with given tid
*
* Currently ignores LP_IVALID during processing!
* On entry, tuple->t_self is the TID to fetch.
*
* Because this is not part of a scan, there is no way to
* automatically lock/unlock the shared buffers.
* For this reason, we require that the user retrieve the buffer
* value, and they are required to BufferRelease() it when they
* are done. If they want to make a copy of it before releasing it,
* they can call heap_copytyple().
* If successful (ie, tuple found and passes snapshot time qual),
* then the rest of *tuple is filled in, and *userbuf is set to the
* buffer holding the tuple. A pin is obtained on the buffer; the
* caller must BufferRelease the buffer when done with the tuple.
*
* If not successful, tuple->t_data is set to NULL and *userbuf is set to
* InvalidBuffer.
* ----------------
*/
void
@@ -914,7 +883,7 @@ heap_fetch(Relation relation,
Snapshot snapshot,
HeapTuple tuple,
Buffer *userbuf,
IndexScanDesc iscan)
PgStat_Info *pgstat_info)
{
ItemId lp;
Buffer buffer;
@@ -936,8 +905,9 @@ heap_fetch(Relation relation,
buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(tid));
if (!BufferIsValid(buffer))
elog(ERROR, "heap_fetch: %s relation: ReadBuffer(%lx) failed",
RelationGetRelationName(relation), (long) tid);
elog(ERROR, "heap_fetch: %s relation: ReadBuffer(%ld) failed",
RelationGetRelationName(relation),
(long) ItemPointerGetBlockNumber(tid));
LockBuffer(buffer, BUFFER_LOCK_SHARE);
@@ -990,8 +960,12 @@ heap_fetch(Relation relation,
*/
*userbuf = buffer;
if (iscan != NULL)
pgstat_count_heap_fetch(&iscan->xs_pgstat_info);
/*
* Count the successful fetch in *pgstat_info if given,
* otherwise in the relation's default statistics area.
*/
if (pgstat_info != NULL)
pgstat_count_heap_fetch(pgstat_info);
else
pgstat_count_heap_fetch(&relation->pgstat_info);
}

View File

@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/heap/tuptoaster.c,v 1.28 2002/03/05 05:33:06 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/access/heap/tuptoaster.c,v 1.29 2002/05/20 23:51:41 tgl Exp $
*
*
* INTERFACE ROUTINES
@@ -37,8 +37,6 @@
#include "utils/pg_lzcompress.h"
#ifdef TUPLE_TOASTER_ACTIVE
#undef TOAST_DEBUG
static void toast_delete(Relation rel, HeapTuple oldtup);
@@ -961,14 +959,12 @@ toast_save_datum(Relation rel, Datum value)
static void
toast_delete_datum(Relation rel, Datum value)
{
register varattrib *attr = (varattrib *) value;
varattrib *attr = (varattrib *) DatumGetPointer(value);
Relation toastrel;
Relation toastidx;
ScanKeyData toastkey;
IndexScanDesc toastscan;
HeapTupleData toasttup;
RetrieveIndexResult indexRes;
Buffer buffer;
HeapTuple toasttup;
if (!VARATT_IS_EXTERNAL(attr))
return;
@@ -993,22 +989,14 @@ toast_delete_datum(Relation rel, Datum value)
/*
* Find the chunks by index
*/
toastscan = index_beginscan(toastidx, false, 1, &toastkey);
while ((indexRes = index_getnext(toastscan, ForwardScanDirection)) != NULL)
toastscan = index_beginscan(toastrel, toastidx, SnapshotToast,
1, &toastkey);
while ((toasttup = index_getnext(toastscan, ForwardScanDirection)) != NULL)
{
toasttup.t_self = indexRes->heap_iptr;
heap_fetch(toastrel, SnapshotToast, &toasttup, &buffer, toastscan);
pfree(indexRes);
if (!toasttup.t_data)
continue;
/*
* Have a chunk, delete it
*/
simple_heap_delete(toastrel, &toasttup.t_self);
ReleaseBuffer(buffer);
simple_heap_delete(toastrel, &toasttup->t_self);
}
/*
@@ -1034,11 +1022,8 @@ toast_fetch_datum(varattrib *attr)
Relation toastidx;
ScanKeyData toastkey;
IndexScanDesc toastscan;
HeapTupleData toasttup;
HeapTuple ttup;
TupleDesc toasttupDesc;
RetrieveIndexResult indexRes;
Buffer buffer;
varattrib *result;
int32 ressize;
int32 residx,
@@ -1082,17 +1067,10 @@ toast_fetch_datum(varattrib *attr)
*/
nextidx = 0;
toastscan = index_beginscan(toastidx, false, 1, &toastkey);
while ((indexRes = index_getnext(toastscan, ForwardScanDirection)) != NULL)
toastscan = index_beginscan(toastrel, toastidx, SnapshotToast,
1, &toastkey);
while ((ttup = index_getnext(toastscan, ForwardScanDirection)) != NULL)
{
toasttup.t_self = indexRes->heap_iptr;
heap_fetch(toastrel, SnapshotToast, &toasttup, &buffer, toastscan);
pfree(indexRes);
if (toasttup.t_data == NULL)
continue;
ttup = &toasttup;
/*
* Have a chunk, extract the sequence number and the data
*/
@@ -1135,7 +1113,6 @@ toast_fetch_datum(varattrib *attr)
VARATT_DATA(chunk),
chunksize);
ReleaseBuffer(buffer);
nextidx++;
}
@@ -1170,16 +1147,12 @@ toast_fetch_datum_slice(varattrib *attr, int32 sliceoffset, int32 length)
Relation toastrel;
Relation toastidx;
ScanKeyData toastkey[3];
int nscankeys;
IndexScanDesc toastscan;
HeapTupleData toasttup;
HeapTuple ttup;
TupleDesc toasttupDesc;
RetrieveIndexResult indexRes;
Buffer buffer;
varattrib *result;
int32 attrsize;
int32 nscankeys;
int32 residx;
int32 nextidx;
int numchunks;
@@ -1198,15 +1171,15 @@ toast_fetch_datum_slice(varattrib *attr, int32 sliceoffset, int32 length)
totalchunks = ((attrsize - 1) / TOAST_MAX_CHUNK_SIZE) + 1;
if (sliceoffset >= attrsize)
{
{
sliceoffset = 0;
length = 0;
}
}
if (((sliceoffset + length) > attrsize) || length < 0)
{
{
length = attrsize - sliceoffset;
}
}
result = (varattrib *) palloc(length + VARHDRSZ);
VARATT_SIZEP(result) = length + VARHDRSZ;
@@ -1274,17 +1247,10 @@ toast_fetch_datum_slice(varattrib *attr, int32 sliceoffset, int32 length)
* The index is on (valueid, chunkidx) so they will come in order
*/
nextidx = startchunk;
toastscan = index_beginscan(toastidx, false, nscankeys, &toastkey[0]);
while ((indexRes = index_getnext(toastscan, ForwardScanDirection)) != NULL)
toastscan = index_beginscan(toastrel, toastidx, SnapshotToast,
nscankeys, toastkey);
while ((ttup = index_getnext(toastscan, ForwardScanDirection)) != NULL)
{
toasttup.t_self = indexRes->heap_iptr;
heap_fetch(toastrel, SnapshotToast, &toasttup, &buffer, toastscan);
pfree(indexRes);
if (toasttup.t_data == NULL)
continue;
ttup = &toasttup;
/*
* Have a chunk, extract the sequence number and the data
*/
@@ -1329,7 +1295,6 @@ toast_fetch_datum_slice(varattrib *attr, int32 sliceoffset, int32 length)
VARATT_DATA(chunk) + chcpystrt,
(chcpyend - chcpystrt) + 1);
ReleaseBuffer(buffer);
nextidx++;
}
@@ -1350,5 +1315,3 @@ toast_fetch_datum_slice(varattrib *attr, int32 sliceoffset, int32 length)
return result;
}
#endif /* TUPLE_TOASTER_ACTIVE */

View File

@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/index/genam.c,v 1.32 2002/03/29 22:10:32 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/access/index/genam.c,v 1.33 2002/05/20 23:51:41 tgl Exp $
*
* NOTES
* many of the old access method routines have been turned into
@@ -16,34 +16,7 @@
*
*-------------------------------------------------------------------------
*/
/*
* OLD COMMENTS
* Scans are implemented as follows:
*
* `0' represents an invalid item pointer.
* `-' represents an unknown item pointer.
* `X' represents a known item pointers.
* `+' represents known or invalid item pointers.
* `*' represents any item pointers.
*
* State is represented by a triple of these symbols in the order of
* previous, current, next. Note that the case of reverse scans works
* identically.
*
* State Result
* (1) + + - + 0 0 (if the next item pointer is invalid)
* (2) + X - (otherwise)
* (3) * 0 0 * 0 0 (no change)
* (4) + X 0 X 0 0 (shift)
* (5) * + X + X - (shift, add unknown)
*
* All other states cannot occur.
*
* Note:
* It would be possible to cache the status of the previous and
* next item pointer using the flags.
* ----------------------------------------------------------------
*/
#include "postgres.h"
#include "access/genam.h"
@@ -83,50 +56,58 @@
* the passed key.
*
* Parameters:
* relation -- index relation for scan.
* scanFromEnd -- if true, begin scan at one of the index's
* endpoints.
* numberOfKeys -- count of scan keys.
* key -- the ScanKey for the starting position of the scan.
* indexRelation -- index relation for scan.
* nkeys -- count of scan keys.
* key -- array of scan keys to restrict the index scan.
*
* Returns:
* An initialized IndexScanDesc.
* ----------------
*/
IndexScanDesc
RelationGetIndexScan(Relation relation,
bool scanFromEnd,
uint16 numberOfKeys,
ScanKey key)
RelationGetIndexScan(Relation indexRelation,
int nkeys, ScanKey key)
{
IndexScanDesc scan;
if (!RelationIsValid(relation))
if (!RelationIsValid(indexRelation))
elog(ERROR, "RelationGetIndexScan: relation invalid");
scan = (IndexScanDesc) palloc(sizeof(IndexScanDescData));
scan->relation = relation;
scan->heapRelation = NULL; /* may be set later */
scan->indexRelation = indexRelation;
scan->xs_snapshot = SnapshotNow; /* may be set later */
scan->numberOfKeys = nkeys;
/*
* We allocate the key space here, but the AM is responsible for
* actually filling it from the passed key array.
*/
if (nkeys > 0)
scan->keyData = (ScanKey) palloc(sizeof(ScanKeyData) * nkeys);
else
scan->keyData = NULL;
scan->opaque = NULL;
scan->numberOfKeys = numberOfKeys;
ItemPointerSetInvalid(&scan->currentItemData);
ItemPointerSetInvalid(&scan->currentMarkData);
pgstat_initstats(&scan->xs_pgstat_info, relation);
ItemPointerSetInvalid(&scan->xs_ctup.t_self);
scan->xs_ctup.t_datamcxt = NULL;
scan->xs_ctup.t_data = NULL;
scan->xs_cbuf = InvalidBuffer;
/*
* mark cached function lookup data invalid; it will be set on first
* use
*/
/* mark cached function lookup data invalid; it will be set later */
scan->fn_getnext.fn_oid = InvalidOid;
if (numberOfKeys > 0)
scan->keyData = (ScanKey) palloc(sizeof(ScanKeyData) * numberOfKeys);
else
scan->keyData = NULL;
pgstat_initstats(&scan->xs_pgstat_info, indexRelation);
index_rescan(scan, scanFromEnd, key);
/*
* Let the AM fill in the key and any opaque data it wants.
*/
index_rescan(scan, key);
return scan;
}
@@ -155,113 +136,21 @@ IndexScanEnd(IndexScanDesc scan)
pfree(scan);
}
#ifdef NOT_USED
/* ----------------
* IndexScanRestart -- Restart an index scan.
*
* This routine isn't used by any existing access method. It's
* appropriate if relation level locks are what you want.
*
* Returns:
* None.
*
* Side Effects:
* None.
* ----------------
*/
void
IndexScanRestart(IndexScanDesc scan,
bool scanFromEnd,
ScanKey key)
{
if (!IndexScanIsValid(scan))
elog(ERROR, "IndexScanRestart: invalid scan");
ItemPointerSetInvalid(&scan->currentItemData);
if (RelationGetNumberOfBlocks(scan->relation) == 0)
scan->flags = ScanUnmarked;
else if (scanFromEnd)
scan->flags = ScanUnmarked | ScanUncheckedPrevious;
else
scan->flags = ScanUnmarked | ScanUncheckedNext;
scan->scanFromEnd = (bool) scanFromEnd;
if (scan->numberOfKeys > 0)
memmove(scan->keyData,
key,
scan->numberOfKeys * sizeof(ScanKeyData));
}
/* ----------------
* IndexScanMarkPosition -- Mark current position in a scan.
*
* This routine isn't used by any existing access method, but is the
* one that AM implementors should use, if they don't want to do any
* special locking. If relation-level locking is sufficient, this is
* the routine for you.
*
* Returns:
* None.
*
* Side Effects:
* None.
* ----------------
*/
void
IndexScanMarkPosition(IndexScanDesc scan)
{
scan->currentMarkData = scan->currentItemData;
scan->flags = 0x0; /* XXX should have a symbolic name */
}
/* ----------------
* IndexScanRestorePosition -- Restore position on a marked scan.
*
* This routine isn't used by any existing access method, but is the
* one that AM implementors should use if they don't want to do any
* special locking. If relation-level locking is sufficient, then
* this is the one you want.
*
* Returns:
* None.
*
* Side Effects:
* None.
* ----------------
*/
void
IndexScanRestorePosition(IndexScanDesc scan)
{
if (scan->flags & ScanUnmarked)
elog(ERROR, "IndexScanRestorePosition: no mark to restore");
scan->currentItemData = scan->currentMarkData;
scan->flags = 0x0; /* XXX should have a symbolic name */
}
#endif
/* ----------------------------------------------------------------
* heap-or-index-scan access to system catalogs
*
* These functions support system catalog accesses that normally use
* an index but need to be capable of being switched to heap scans
* if the system indexes are unavailable. The interface is
* as easy to use as a heap scan, and hides all the extra cruft of
* the present indexscan API.
* if the system indexes are unavailable.
*
* The specified scan keys must be compatible with the named index.
* Generally this means that they must constrain either all columns
* of the index, or the first K columns of an N-column index.
*
* These routines would work fine with non-system tables, actually,
* These routines could work with non-system tables, actually,
* but they're only useful when there is a known index to use with
* the given scan keys, so in practice they're only good for
* the given scan keys; so in practice they're only good for
* predetermined types of scans of system catalogs.
* ----------------------------------------------------------------
*/
@@ -286,27 +175,24 @@ IndexScanRestorePosition(IndexScanDesc scan)
* In standard case indexOK can simply be constant TRUE.
*/
SysScanDesc
systable_beginscan(Relation rel,
systable_beginscan(Relation heapRelation,
const char *indexRelname,
bool indexOK,
Snapshot snapshot,
unsigned nkeys, ScanKey key)
int nkeys, ScanKey key)
{
SysScanDesc sysscan;
sysscan = (SysScanDesc) palloc(sizeof(SysScanDescData));
sysscan->heap_rel = rel;
sysscan->snapshot = snapshot;
sysscan->tuple.t_datamcxt = NULL;
sysscan->tuple.t_data = NULL;
sysscan->buffer = InvalidBuffer;
sysscan->heap_rel = heapRelation;
if (indexOK &&
rel->rd_rel->relhasindex &&
heapRelation->rd_rel->relhasindex &&
!IsIgnoringSystemIndexes())
{
Relation irel;
unsigned i;
int i;
/* We assume it's a system index, so index_openr is OK */
sysscan->irel = irel = index_openr(indexRelname);
@@ -321,13 +207,14 @@ systable_beginscan(Relation rel,
Assert(key[i].sk_attno == irel->rd_index->indkey[i]);
key[i].sk_attno = i+1;
}
sysscan->iscan = index_beginscan(irel, false, nkeys, key);
sysscan->iscan = index_beginscan(heapRelation, irel, snapshot,
nkeys, key);
sysscan->scan = NULL;
}
else
{
sysscan->irel = (Relation) NULL;
sysscan->scan = heap_beginscan(rel, false, snapshot, nkeys, key);
sysscan->irel = NULL;
sysscan->scan = heap_beginscan(heapRelation, snapshot, nkeys, key);
sysscan->iscan = NULL;
}
@@ -346,34 +233,12 @@ systable_beginscan(Relation rel,
HeapTuple
systable_getnext(SysScanDesc sysscan)
{
HeapTuple htup = (HeapTuple) NULL;
HeapTuple htup;
if (sysscan->irel)
{
RetrieveIndexResult indexRes;
if (BufferIsValid(sysscan->buffer))
{
ReleaseBuffer(sysscan->buffer);
sysscan->buffer = InvalidBuffer;
}
while ((indexRes = index_getnext(sysscan->iscan, ForwardScanDirection)) != NULL)
{
sysscan->tuple.t_self = indexRes->heap_iptr;
pfree(indexRes);
heap_fetch(sysscan->heap_rel, sysscan->snapshot,
&sysscan->tuple, &sysscan->buffer,
sysscan->iscan);
if (sysscan->tuple.t_data != NULL)
{
htup = &sysscan->tuple;
break;
}
}
}
htup = index_getnext(sysscan->iscan, ForwardScanDirection);
else
htup = heap_getnext(sysscan->scan, 0);
htup = heap_getnext(sysscan->scan, ForwardScanDirection);
return htup;
}
@@ -388,8 +253,6 @@ systable_endscan(SysScanDesc sysscan)
{
if (sysscan->irel)
{
if (BufferIsValid(sysscan->buffer))
ReleaseBuffer(sysscan->buffer);
index_endscan(sysscan->iscan);
index_close(sysscan->irel);
}

View File

@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/index/indexam.c,v 1.57 2002/04/17 20:57:56 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/access/index/indexam.c,v 1.58 2002/05/20 23:51:41 tgl Exp $
*
* INTERFACE ROUTINES
* index_open - open an index relation by relation OID
@@ -73,20 +73,20 @@
*/
#define RELATION_CHECKS \
( \
AssertMacro(RelationIsValid(relation)), \
AssertMacro(PointerIsValid(relation->rd_am)) \
AssertMacro(RelationIsValid(indexRelation)), \
AssertMacro(PointerIsValid(indexRelation->rd_am)) \
)
#define SCAN_CHECKS \
( \
AssertMacro(IndexScanIsValid(scan)), \
AssertMacro(RelationIsValid(scan->relation)), \
AssertMacro(PointerIsValid(scan->relation->rd_am)) \
AssertMacro(RelationIsValid(scan->indexRelation)), \
AssertMacro(PointerIsValid(scan->indexRelation->rd_am)) \
)
#define GET_REL_PROCEDURE(x,y) \
( \
procedure = relation->rd_am->y, \
procedure = indexRelation->rd_am->y, \
(!RegProcedureIsValid(procedure)) ? \
elog(ERROR, "index_%s: invalid %s regproc", \
CppAsString(x), CppAsString(y)) \
@@ -95,7 +95,7 @@
#define GET_SCAN_PROCEDURE(x,y) \
( \
procedure = scan->relation->rd_am->y, \
procedure = scan->indexRelation->rd_am->y, \
(!RegProcedureIsValid(procedure)) ? \
elog(ERROR, "index_%s: invalid %s regproc", \
CppAsString(x), CppAsString(y)) \
@@ -200,11 +200,11 @@ index_close(Relation relation)
* ----------------
*/
InsertIndexResult
index_insert(Relation relation,
Datum *datum,
index_insert(Relation indexRelation,
Datum *datums,
char *nulls,
ItemPointer heap_t_ctid,
Relation heapRel)
Relation heapRelation)
{
RegProcedure procedure;
InsertIndexResult specificResult;
@@ -217,11 +217,11 @@ index_insert(Relation relation,
*/
specificResult = (InsertIndexResult)
DatumGetPointer(OidFunctionCall5(procedure,
PointerGetDatum(relation),
PointerGetDatum(datum),
PointerGetDatum(indexRelation),
PointerGetDatum(datums),
PointerGetDatum(nulls),
PointerGetDatum(heap_t_ctid),
PointerGetDatum(heapRel)));
PointerGetDatum(heapRelation)));
/* must be pfree'ed */
return specificResult;
@@ -229,13 +229,19 @@ index_insert(Relation relation,
/* ----------------
* index_beginscan - start a scan of an index
*
* Note: heapRelation may be NULL if there is no intention of calling
* index_getnext on this scan; index_getnext_indexitem will not use the
* heapRelation link (nor the snapshot). However, the caller had better
* be holding some kind of lock on the heap relation in any case, to ensure
* no one deletes it (or the index) out from under us.
* ----------------
*/
IndexScanDesc
index_beginscan(Relation relation,
bool scanFromEnd,
uint16 numberOfKeys,
ScanKey key)
index_beginscan(Relation heapRelation,
Relation indexRelation,
Snapshot snapshot,
int nkeys, ScanKey key)
{
IndexScanDesc scan;
RegProcedure procedure;
@@ -243,7 +249,7 @@ index_beginscan(Relation relation,
RELATION_CHECKS;
GET_REL_PROCEDURE(beginscan, ambeginscan);
RelationIncrementReferenceCount(relation);
RelationIncrementReferenceCount(indexRelation);
/*
* Acquire AccessShareLock for the duration of the scan
@@ -252,16 +258,23 @@ index_beginscan(Relation relation,
* rebuild the relcache entry. The refcount increment above ensures
* that we will rebuild it and not just flush it...
*/
LockRelation(relation, AccessShareLock);
LockRelation(indexRelation, AccessShareLock);
/*
* Tell the AM to open a scan.
*/
scan = (IndexScanDesc)
DatumGetPointer(OidFunctionCall4(procedure,
PointerGetDatum(relation),
BoolGetDatum(scanFromEnd),
UInt16GetDatum(numberOfKeys),
DatumGetPointer(OidFunctionCall3(procedure,
PointerGetDatum(indexRelation),
Int32GetDatum(nkeys),
PointerGetDatum(key)));
pgstat_initstats(&scan->xs_pgstat_info, relation);
/*
* Save additional parameters into the scandesc. Everything else
* was set up by RelationGetIndexScan.
*/
scan->heapRelation = heapRelation;
scan->xs_snapshot = snapshot;
/*
* We want to look up the amgettuple procedure just once per scan, not
@@ -275,20 +288,23 @@ index_beginscan(Relation relation,
}
/* ----------------
* index_rescan - restart a scan of an index
* index_rescan - (re)start a scan of an index
*
* The caller may specify a new set of scankeys (but the number of keys
* cannot change). Note that this is also called when first starting
* an indexscan; see RelationGetIndexScan.
* ----------------
*/
void
index_rescan(IndexScanDesc scan, bool scanFromEnd, ScanKey key)
index_rescan(IndexScanDesc scan, ScanKey key)
{
RegProcedure procedure;
SCAN_CHECKS;
GET_SCAN_PROCEDURE(rescan, amrescan);
OidFunctionCall3(procedure,
OidFunctionCall2(procedure,
PointerGetDatum(scan),
BoolGetDatum(scanFromEnd),
PointerGetDatum(key));
pgstat_reset_index_scan(&scan->xs_pgstat_info);
@@ -306,13 +322,21 @@ index_endscan(IndexScanDesc scan)
SCAN_CHECKS;
GET_SCAN_PROCEDURE(endscan, amendscan);
/* Release any held pin on a heap page */
if (BufferIsValid(scan->xs_cbuf))
{
ReleaseBuffer(scan->xs_cbuf);
scan->xs_cbuf = InvalidBuffer;
}
/* End the AM's scan */
OidFunctionCall1(procedure, PointerGetDatum(scan));
/* Release lock and refcount acquired by index_beginscan */
/* Release index lock and refcount acquired by index_beginscan */
UnlockRelation(scan->relation, AccessShareLock);
UnlockRelation(scan->indexRelation, AccessShareLock);
RelationDecrementReferenceCount(scan->relation);
RelationDecrementReferenceCount(scan->indexRelation);
/* Release the scan data structure itself */
IndexScanEnd(scan);
@@ -349,33 +373,87 @@ index_restrpos(IndexScanDesc scan)
}
/* ----------------
* index_getnext - get the next tuple from a scan
* index_getnext - get the next heap tuple from a scan
*
* A RetrieveIndexResult is a index tuple/heap tuple pair
* The result is the next heap tuple satisfying the scan keys and the
* snapshot, or NULL if no more matching tuples exist. On success,
* the buffer containing the heap tuple is pinned (the pin will be dropped
* at the next index_getnext or index_endscan). The index TID corresponding
* to the heap tuple can be obtained if needed from scan->currentItemData.
* ----------------
*/
RetrieveIndexResult
index_getnext(IndexScanDesc scan,
ScanDirection direction)
HeapTuple
index_getnext(IndexScanDesc scan, ScanDirection direction)
{
RetrieveIndexResult result;
bool found;
SCAN_CHECKS;
pgstat_count_index_scan(&scan->xs_pgstat_info);
/* Release any previously held pin */
if (BufferIsValid(scan->xs_cbuf))
{
ReleaseBuffer(scan->xs_cbuf);
scan->xs_cbuf = InvalidBuffer;
}
for (;;)
{
pgstat_count_index_scan(&scan->xs_pgstat_info);
/*
* The AM's gettuple proc finds the next tuple matching the scan
* keys. index_beginscan already set up fn_getnext.
*/
found = DatumGetBool(FunctionCall2(&scan->fn_getnext,
PointerGetDatum(scan),
Int32GetDatum(direction)));
if (!found)
return NULL; /* failure exit */
/*
* Fetch the heap tuple and see if it matches the snapshot.
*/
heap_fetch(scan->heapRelation, scan->xs_snapshot,
&scan->xs_ctup, &scan->xs_cbuf,
&scan->xs_pgstat_info);
if (scan->xs_ctup.t_data != NULL)
break;
/*
* XXX here, consider whether we can kill the index tuple.
*/
}
/* Success exit */
pgstat_count_index_getnext(&scan->xs_pgstat_info);
return &scan->xs_ctup;
}
/* ----------------
* index_getnext_indexitem - get the next index tuple from a scan
*
* Finds the next index tuple satisfying the scan keys. Note that no
* time qual (snapshot) check is done; indeed the heap tuple is not accessed.
* On success (TRUE return), the found index TID is in scan->currentItemData,
* and its heap TID is in scan->xs_ctup.t_self. scan->xs_cbuf is untouched.
* ----------------
*/
bool
index_getnext_indexitem(IndexScanDesc scan,
ScanDirection direction)
{
bool found;
SCAN_CHECKS;
/*
* have the am's gettuple proc do all the work. index_beginscan
* already set up fn_getnext.
*/
result = (RetrieveIndexResult)
DatumGetPointer(FunctionCall2(&scan->fn_getnext,
PointerGetDatum(scan),
Int32GetDatum(direction)));
found = DatumGetBool(FunctionCall2(&scan->fn_getnext,
PointerGetDatum(scan),
Int32GetDatum(direction)));
if (result != NULL)
pgstat_count_index_getnext(&scan->xs_pgstat_info);
return result;
return found;
}
/* ----------------
@@ -388,7 +466,7 @@ index_getnext(IndexScanDesc scan,
* ----------------
*/
IndexBulkDeleteResult *
index_bulk_delete(Relation relation,
index_bulk_delete(Relation indexRelation,
IndexBulkDeleteCallback callback,
void *callback_state)
{
@@ -400,7 +478,7 @@ index_bulk_delete(Relation relation,
result = (IndexBulkDeleteResult *)
DatumGetPointer(OidFunctionCall3(procedure,
PointerGetDatum(relation),
PointerGetDatum(indexRelation),
PointerGetDatum((Pointer) callback),
PointerGetDatum(callback_state)));
@@ -418,7 +496,7 @@ index_bulk_delete(Relation relation,
* ----------------
*/
RegProcedure
index_cost_estimator(Relation relation)
index_cost_estimator(Relation indexRelation)
{
RegProcedure procedure;

View File

@@ -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.88 2002/03/02 21:39:18 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtree.c,v 1.89 2002/05/20 23:51:41 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -296,7 +296,7 @@ btgettuple(PG_FUNCTION_ARGS)
{
IndexScanDesc scan = (IndexScanDesc) PG_GETARG_POINTER(0);
ScanDirection dir = (ScanDirection) PG_GETARG_INT32(1);
RetrieveIndexResult res;
bool res;
/*
* If we've already initialized this scan, we can just advance it in
@@ -326,12 +326,12 @@ btgettuple(PG_FUNCTION_ARGS)
*/
if (res)
{
((BTScanOpaque) scan->opaque)->curHeapIptr = res->heap_iptr;
((BTScanOpaque) scan->opaque)->curHeapIptr = scan->xs_ctup.t_self;
LockBuffer(((BTScanOpaque) scan->opaque)->btso_curbuf,
BUFFER_LOCK_UNLOCK);
}
PG_RETURN_POINTER(res);
PG_RETURN_BOOL(res);
}
/*
@@ -341,13 +341,12 @@ Datum
btbeginscan(PG_FUNCTION_ARGS)
{
Relation rel = (Relation) PG_GETARG_POINTER(0);
bool fromEnd = PG_GETARG_BOOL(1);
uint16 keysz = PG_GETARG_UINT16(2);
ScanKey scankey = (ScanKey) PG_GETARG_POINTER(3);
int keysz = PG_GETARG_INT32(1);
ScanKey scankey = (ScanKey) PG_GETARG_POINTER(2);
IndexScanDesc scan;
/* get the scan */
scan = RelationGetIndexScan(rel, fromEnd, keysz, scankey);
scan = RelationGetIndexScan(rel, keysz, scankey);
PG_RETURN_POINTER(scan);
}
@@ -359,11 +358,7 @@ Datum
btrescan(PG_FUNCTION_ARGS)
{
IndexScanDesc scan = (IndexScanDesc) PG_GETARG_POINTER(0);
#ifdef NOT_USED /* XXX surely it's wrong to ignore this? */
bool fromEnd = PG_GETARG_BOOL(1);
#endif
ScanKey scankey = (ScanKey) PG_GETARG_POINTER(2);
ScanKey scankey = (ScanKey) PG_GETARG_POINTER(1);
ItemPointer iptr;
BTScanOpaque so;
@@ -373,11 +368,13 @@ btrescan(PG_FUNCTION_ARGS)
{
so = (BTScanOpaque) palloc(sizeof(BTScanOpaqueData));
so->btso_curbuf = so->btso_mrkbuf = InvalidBuffer;
so->keyData = (ScanKey) NULL;
ItemPointerSetInvalid(&(so->curHeapIptr));
ItemPointerSetInvalid(&(so->mrkHeapIptr));
if (scan->numberOfKeys > 0)
so->keyData = (ScanKey) palloc(scan->numberOfKeys * sizeof(ScanKeyData));
else
so->keyData = (ScanKey) NULL;
scan->opaque = so;
scan->flags = 0x0;
}
/* we aren't holding any read locks, but gotta drop the pins */
@@ -385,6 +382,7 @@ btrescan(PG_FUNCTION_ARGS)
{
ReleaseBuffer(so->btso_curbuf);
so->btso_curbuf = InvalidBuffer;
ItemPointerSetInvalid(&(so->curHeapIptr));
ItemPointerSetInvalid(iptr);
}
@@ -392,6 +390,7 @@ btrescan(PG_FUNCTION_ARGS)
{
ReleaseBuffer(so->btso_mrkbuf);
so->btso_mrkbuf = InvalidBuffer;
ItemPointerSetInvalid(&(so->mrkHeapIptr));
ItemPointerSetInvalid(iptr);
}
@@ -491,7 +490,7 @@ btmarkpos(PG_FUNCTION_ARGS)
/* bump pin on current buffer for assignment to mark buffer */
if (ItemPointerIsValid(&(scan->currentItemData)))
{
so->btso_mrkbuf = ReadBuffer(scan->relation,
so->btso_mrkbuf = ReadBuffer(scan->indexRelation,
BufferGetBlockNumber(so->btso_curbuf));
scan->currentMarkData = scan->currentItemData;
so->mrkHeapIptr = so->curHeapIptr;
@@ -523,7 +522,7 @@ btrestrpos(PG_FUNCTION_ARGS)
/* bump pin on marked buffer */
if (ItemPointerIsValid(&(scan->currentMarkData)))
{
so->btso_curbuf = ReadBuffer(scan->relation,
so->btso_curbuf = ReadBuffer(scan->indexRelation,
BufferGetBlockNumber(so->btso_mrkbuf));
scan->currentItemData = scan->currentMarkData;
so->curHeapIptr = so->mrkHeapIptr;
@@ -549,7 +548,6 @@ btbulkdelete(PG_FUNCTION_ARGS)
BlockNumber num_pages;
double tuples_removed;
double num_index_tuples;
RetrieveIndexResult res;
IndexScanDesc scan;
BTScanOpaque so;
ItemPointer current;
@@ -569,19 +567,16 @@ btbulkdelete(PG_FUNCTION_ARGS)
* doesn't care which kind of lock it's releasing). This should
* minimize the amount of work needed per page.
*/
scan = index_beginscan(rel, false, 0, (ScanKey) NULL);
scan = index_beginscan(NULL, rel, SnapshotAny, 0, (ScanKey) NULL);
so = (BTScanOpaque) scan->opaque;
current = &(scan->currentItemData);
/* Use _bt_first to get started, then _bt_step to remaining tuples */
res = _bt_first(scan, ForwardScanDirection);
if (res != NULL)
if (_bt_first(scan, ForwardScanDirection))
{
Buffer buf;
BlockNumber lockedBlock = InvalidBlockNumber;
pfree(res);
/* we have the buffer pinned and locked */
buf = so->btso_curbuf;
Assert(BufferIsValid(buf));
@@ -683,7 +678,7 @@ btbulkdelete(PG_FUNCTION_ARGS)
static void
_bt_restscan(IndexScanDesc scan)
{
Relation rel = scan->relation;
Relation rel = scan->indexRelation;
BTScanOpaque so = (BTScanOpaque) scan->opaque;
Buffer buf = so->btso_curbuf;
Page page;

View File

@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtsearch.c,v 1.69 2001/10/25 05:49:21 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtsearch.c,v 1.70 2002/05/20 23:51:41 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -19,7 +19,7 @@
#include "access/nbtree.h"
static RetrieveIndexResult _bt_endpoint(IndexScanDesc scan, ScanDirection dir);
static bool _bt_endpoint(IndexScanDesc scan, ScanDirection dir);
/*
@@ -357,11 +357,11 @@ _bt_compare(Relation rel,
*
* On entry, we have a valid currentItemData in the scan, and a
* read lock and pin count on the page that contains that item.
* We return the next item in the scan, or NULL if no more.
* We return the next item in the scan, or false if no more.
* On successful exit, the page containing the new item is locked
* and pinned; on NULL exit, no lock or pin is held.
* and pinned; on failure exit, no lock or pin is held.
*/
RetrieveIndexResult
bool
_bt_next(IndexScanDesc scan, ScanDirection dir)
{
Relation rel;
@@ -374,7 +374,7 @@ _bt_next(IndexScanDesc scan, ScanDirection dir)
BTScanOpaque so;
bool continuescan;
rel = scan->relation;
rel = scan->indexRelation;
so = (BTScanOpaque) scan->opaque;
current = &(scan->currentItemData);
@@ -386,7 +386,7 @@ _bt_next(IndexScanDesc scan, ScanDirection dir)
{
/* step one tuple in the appropriate direction */
if (!_bt_step(scan, &buf, dir))
return (RetrieveIndexResult) NULL;
return false;
/* current is the next candidate tuple to return */
offnum = ItemPointerGetOffsetNumber(current);
@@ -397,7 +397,8 @@ _bt_next(IndexScanDesc scan, ScanDirection dir)
if (_bt_checkkeys(scan, itup, dir, &continuescan))
{
/* tuple passes all scan key conditions, so return it */
return FormRetrieveIndexResult(current, &(itup->t_tid));
scan->xs_ctup.t_self = itup->t_tid;
return true;
}
/* This tuple doesn't pass, but there might be more that do */
@@ -408,20 +409,20 @@ _bt_next(IndexScanDesc scan, ScanDirection dir)
so->btso_curbuf = InvalidBuffer;
_bt_relbuf(rel, buf);
return (RetrieveIndexResult) NULL;
return false;
}
/*
* _bt_first() -- Find the first item in a scan.
*
* We need to be clever about the type of scan, the operation it's
* performing, and the tree ordering. We return the RetrieveIndexResult
* of the first item in the tree that satisfies the qualification
* performing, and the tree ordering. We find the
* first item in the tree that satisfies the qualification
* associated with the scan descriptor. On exit, the page containing
* the current index tuple is read locked and pinned, and the scan's
* opaque data entry is updated to include the buffer.
*/
RetrieveIndexResult
bool
_bt_first(IndexScanDesc scan, ScanDirection dir)
{
Relation rel;
@@ -434,9 +435,10 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
ItemPointer current;
BlockNumber blkno;
StrategyNumber strat;
RetrieveIndexResult res;
bool res;
int32 result;
BTScanOpaque so;
bool scanFromEnd;
bool continuescan;
ScanKey scankeys = NULL;
int keysCount = 0;
@@ -445,7 +447,7 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
j;
StrategyNumber strat_total;
rel = scan->relation;
rel = scan->indexRelation;
so = (BTScanOpaque) scan->opaque;
/*
@@ -459,12 +461,12 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
* be satisfied (eg, x == 1 AND x > 2).
*/
if (!so->qual_ok)
return (RetrieveIndexResult) NULL;
return false;
/*
* Examine the scan keys to discover where we need to start the scan.
*/
scan->scanFromEnd = false;
scanFromEnd = false;
strat_total = BTEqualStrategyNumber;
if (so->numberOfKeys > 0)
{
@@ -511,13 +513,13 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
}
}
if (keysCount == 0)
scan->scanFromEnd = true;
scanFromEnd = true;
}
else
scan->scanFromEnd = true;
scanFromEnd = true;
/* if we just need to walk down one edge of the tree, do that */
if (scan->scanFromEnd)
if (scanFromEnd)
{
if (nKeyIs)
pfree(nKeyIs);
@@ -544,7 +546,7 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
pfree(nKeyIs);
pfree(scankeys);
elog(ERROR, "_bt_first: btree doesn't support is(not)null, yet");
return ((RetrieveIndexResult) NULL);
return false;
}
procinfo = index_getprocinfo(rel, i + 1, BTORDER_PROC);
ScanKeyEntryInitializeWithInfo(scankeys + i,
@@ -574,7 +576,7 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
ItemPointerSetInvalid(current);
so->btso_curbuf = InvalidBuffer;
pfree(scankeys);
return (RetrieveIndexResult) NULL;
return false;
}
/* remember which buffer we have pinned */
@@ -598,7 +600,7 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
* the scan strategy to find the exact place to start the scan.
*
* Note: if _bt_step fails (meaning we fell off the end of the index in
* one direction or the other), we either return NULL (no matches) or
* one direction or the other), we either return false (no matches) or
* call _bt_endpoint() to set up a scan starting at that index
* endpoint, as appropriate for the desired scan type.
*
@@ -615,7 +617,7 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
if (!_bt_step(scan, &buf, BackwardScanDirection))
{
pfree(scankeys);
return (RetrieveIndexResult) NULL;
return false;
}
break;
@@ -649,7 +651,7 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
if (!_bt_step(scan, &buf, BackwardScanDirection))
{
pfree(scankeys);
return (RetrieveIndexResult) NULL;
return false;
}
break;
@@ -664,7 +666,7 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
if (!_bt_step(scan, &buf, ForwardScanDirection))
{
pfree(scankeys);
return (RetrieveIndexResult) NULL;
return false;
}
offnum = ItemPointerGetOffsetNumber(current);
page = BufferGetPage(buf);
@@ -706,7 +708,7 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
if (!_bt_step(scan, &buf, ForwardScanDirection))
{
pfree(scankeys);
return (RetrieveIndexResult) NULL;
return false;
}
}
break;
@@ -722,7 +724,7 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
if (!_bt_step(scan, &buf, ForwardScanDirection))
{
pfree(scankeys);
return (RetrieveIndexResult) NULL;
return false;
}
offnum = ItemPointerGetOffsetNumber(current);
page = BufferGetPage(buf);
@@ -733,7 +735,7 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
if (!_bt_step(scan, &buf, ForwardScanDirection))
{
pfree(scankeys);
return (RetrieveIndexResult) NULL;
return false;
}
offnum = ItemPointerGetOffsetNumber(current);
page = BufferGetPage(buf);
@@ -752,7 +754,8 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
if (_bt_checkkeys(scan, itup, dir, &continuescan))
{
/* yes, return it */
res = FormRetrieveIndexResult(current, &(itup->t_tid));
scan->xs_ctup.t_self = itup->t_tid;
res = true;
}
else if (continuescan)
{
@@ -766,7 +769,7 @@ nomatches:
ItemPointerSetInvalid(current);
so->btso_curbuf = InvalidBuffer;
_bt_relbuf(rel, buf);
res = (RetrieveIndexResult) NULL;
res = false;
}
pfree(scankeys);
@@ -788,7 +791,7 @@ nomatches:
bool
_bt_step(IndexScanDesc scan, Buffer *bufP, ScanDirection dir)
{
Relation rel = scan->relation;
Relation rel = scan->indexRelation;
ItemPointer current = &(scan->currentItemData);
BTScanOpaque so = (BTScanOpaque) scan->opaque;
Page page;
@@ -902,7 +905,7 @@ _bt_step(IndexScanDesc scan, Buffer *bufP, ScanDirection dir)
* that the scan must start at the beginning or end of the index (for
* a forward or backward scan respectively).
*/
static RetrieveIndexResult
static bool
_bt_endpoint(IndexScanDesc scan, ScanDirection dir)
{
Relation rel;
@@ -917,10 +920,10 @@ _bt_endpoint(IndexScanDesc scan, ScanDirection dir)
BTItem btitem;
IndexTuple itup;
BTScanOpaque so;
RetrieveIndexResult res;
bool res;
bool continuescan;
rel = scan->relation;
rel = scan->indexRelation;
current = &(scan->currentItemData);
so = (BTScanOpaque) scan->opaque;
@@ -936,7 +939,7 @@ _bt_endpoint(IndexScanDesc scan, ScanDirection dir)
/* empty index... */
ItemPointerSetInvalid(current);
so->btso_curbuf = InvalidBuffer;
return (RetrieveIndexResult) NULL;
return false;
}
blkno = BufferGetBlockNumber(buf);
@@ -1016,7 +1019,7 @@ _bt_endpoint(IndexScanDesc scan, ScanDirection dir)
if (start > maxoff)
{
if (!_bt_step(scan, &buf, dir))
return (RetrieveIndexResult) NULL;
return false;
start = ItemPointerGetOffsetNumber(current);
page = BufferGetPage(buf);
}
@@ -1028,7 +1031,8 @@ _bt_endpoint(IndexScanDesc scan, ScanDirection dir)
if (_bt_checkkeys(scan, itup, dir, &continuescan))
{
/* yes, return it */
res = FormRetrieveIndexResult(current, &(itup->t_tid));
scan->xs_ctup.t_self = itup->t_tid;
res = true;
}
else if (continuescan)
{
@@ -1041,7 +1045,7 @@ _bt_endpoint(IndexScanDesc scan, ScanDirection dir)
ItemPointerSetInvalid(current);
so->btso_curbuf = InvalidBuffer;
_bt_relbuf(rel, buf);
res = (RetrieveIndexResult) NULL;
res = false;
}
return res;

View File

@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtutils.c,v 1.47 2001/10/25 05:49:21 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtutils.c,v 1.48 2002/05/20 23:51:41 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -195,7 +195,7 @@ _bt_orderkeys(Relation relation, BTScanOpaque so)
{
ScanKeyData xform[BTMaxStrategyNumber];
bool init[BTMaxStrategyNumber];
uint16 numberOfKeys = so->numberOfKeys;
int numberOfKeys = so->numberOfKeys;
ScanKey key;
ScanKey cur;
StrategyMap map;
@@ -203,7 +203,7 @@ _bt_orderkeys(Relation relation, BTScanOpaque so)
int i,
j;
AttrNumber attno;
uint16 new_numberOfKeys;
int new_numberOfKeys;
bool allEqualSoFar;
so->qual_ok = true;
@@ -439,10 +439,10 @@ _bt_checkkeys(IndexScanDesc scan, IndexTuple tuple,
ScanDirection dir, bool *continuescan)
{
BTScanOpaque so = (BTScanOpaque) scan->opaque;
Size keysz = so->numberOfKeys;
int keysz = so->numberOfKeys;
int keysok;
TupleDesc tupdesc;
ScanKey key;
Size keysok;
*continuescan = true;
@@ -450,7 +450,7 @@ _bt_checkkeys(IndexScanDesc scan, IndexTuple tuple,
if (keysz == 0)
return true;
tupdesc = RelationGetDescr(scan->relation);
tupdesc = RelationGetDescr(scan->indexRelation);
key = so->keyData;
keysok = 0;

View File

@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtget.c,v 1.25 2001/03/22 03:59:16 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtget.c,v 1.26 2002/05/20 23:51:41 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -21,10 +21,9 @@
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);
static ItemPointer rtheapptr(Relation r, ItemPointer itemp);
static bool rtscancache(IndexScanDesc s, ScanDirection dir);
static bool rtfirst(IndexScanDesc s, ScanDirection dir);
static bool rtnext(IndexScanDesc s, ScanDirection dir);
Datum
@@ -32,35 +31,34 @@ rtgettuple(PG_FUNCTION_ARGS)
{
IndexScanDesc s = (IndexScanDesc) PG_GETARG_POINTER(0);
ScanDirection dir = (ScanDirection) PG_GETARG_INT32(1);
RetrieveIndexResult res;
bool res;
/* if we have it cached in the scan desc, just return the value */
if ((res = rtscancache(s, dir)) != (RetrieveIndexResult) NULL)
PG_RETURN_POINTER(res);
if (rtscancache(s, dir))
PG_RETURN_BOOL(true);
/* not cached, so we'll have to do some work */
if (ItemPointerIsValid(&(s->currentItemData)))
res = rtnext(s, dir);
else
res = rtfirst(s, dir);
PG_RETURN_POINTER(res);
PG_RETURN_BOOL(res);
}
static RetrieveIndexResult
static bool
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);
b = ReadBuffer(s->indexRelation, P_ROOT);
p = BufferGetPage(b);
po = (RTreePageOpaque) PageGetSpecialPointer(p);
so = (RTreeScanOpaque) s->opaque;
@@ -75,13 +73,12 @@ rtfirst(IndexScanDesc s, ScanDirection dir)
while (n < FirstOffsetNumber || n > maxoff)
{
ReleaseBuffer(b);
if (so->s_stack == (RTSTACK *) NULL)
return (RetrieveIndexResult) NULL;
return false;
stk = so->s_stack;
b = ReadBuffer(s->relation, stk->rts_blk);
b = ReadBuffer(s->indexRelation, stk->rts_blk);
p = BufferGetPage(b);
po = (RTreePageOpaque) PageGetSpecialPointer(p);
maxoff = PageGetMaxOffsetNumber(p);
@@ -101,10 +98,10 @@ rtfirst(IndexScanDesc s, ScanDirection dir)
it = (IndexTuple) PageGetItem(p, PageGetItemId(p, n));
res = FormRetrieveIndexResult(&(s->currentItemData), &(it->t_tid));
s->xs_ctup.t_self = it->t_tid;
ReleaseBuffer(b);
return res;
return true;
}
else
{
@@ -118,21 +115,20 @@ rtfirst(IndexScanDesc s, ScanDirection dir)
blk = ItemPointerGetBlockNumber(&(it->t_tid));
ReleaseBuffer(b);
b = ReadBuffer(s->relation, blk);
b = ReadBuffer(s->indexRelation, blk);
p = BufferGetPage(b);
po = (RTreePageOpaque) PageGetSpecialPointer(p);
}
}
}
static RetrieveIndexResult
static bool
rtnext(IndexScanDesc s, ScanDirection dir)
{
Buffer b;
Page p;
OffsetNumber n;
OffsetNumber maxoff;
RetrieveIndexResult res;
RTreePageOpaque po;
RTreeScanOpaque so;
RTSTACK *stk;
@@ -147,7 +143,7 @@ rtnext(IndexScanDesc s, ScanDirection dir)
else
n = OffsetNumberPrev(n);
b = ReadBuffer(s->relation, blk);
b = ReadBuffer(s->indexRelation, blk);
p = BufferGetPage(b);
po = (RTreePageOpaque) PageGetSpecialPointer(p);
so = (RTreeScanOpaque) s->opaque;
@@ -159,13 +155,12 @@ rtnext(IndexScanDesc s, ScanDirection dir)
while (n < FirstOffsetNumber || n > maxoff)
{
ReleaseBuffer(b);
if (so->s_stack == (RTSTACK *) NULL)
return (RetrieveIndexResult) NULL;
return false;
stk = so->s_stack;
b = ReadBuffer(s->relation, stk->rts_blk);
b = ReadBuffer(s->indexRelation, stk->rts_blk);
p = BufferGetPage(b);
maxoff = PageGetMaxOffsetNumber(p);
po = (RTreePageOpaque) PageGetSpecialPointer(p);
@@ -185,10 +180,10 @@ rtnext(IndexScanDesc s, ScanDirection dir)
it = (IndexTuple) PageGetItem(p, PageGetItemId(p, n));
res = FormRetrieveIndexResult(&(s->currentItemData), &(it->t_tid));
s->xs_ctup.t_self = it->t_tid;
ReleaseBuffer(b);
return res;
return true;
}
else
{
@@ -202,7 +197,7 @@ rtnext(IndexScanDesc s, ScanDirection dir)
blk = ItemPointerGetBlockNumber(&(it->t_tid));
ReleaseBuffer(b);
b = ReadBuffer(s->relation, blk);
b = ReadBuffer(s->indexRelation, blk);
p = BufferGetPage(b);
po = (RTreePageOpaque) PageGetSpecialPointer(p);
@@ -243,14 +238,14 @@ findnext(IndexScanDesc s, Page p, OffsetNumber n, ScanDirection dir)
if (po->flags & F_LEAF)
{
if (index_keytest(it,
RelationGetDescr(s->relation),
RelationGetDescr(s->indexRelation),
s->numberOfKeys, s->keyData))
break;
}
else
{
if (index_keytest(it,
RelationGetDescr(s->relation),
RelationGetDescr(s->indexRelation),
so->s_internalNKey, so->s_internalKey))
break;
}
@@ -264,57 +259,25 @@ findnext(IndexScanDesc s, Page p, OffsetNumber n, ScanDirection dir)
return n;
}
static RetrieveIndexResult
static bool
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;
}
/*
* rtheapptr returns the item pointer to the tuple in the heap relation
* for which itemp is the index relation item pointer.
*/
static ItemPointer
rtheapptr(Relation r, ItemPointer itemp)
{
Buffer b;
Page p;
IndexTuple it;
ItemPointer ip;
OffsetNumber n;
IndexTuple it;
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);
if (!(ScanDirectionIsNoMovement(dir)
&& ItemPointerIsValid(&(s->currentItemData))))
return false;
return ip;
b = ReadBuffer(s->indexRelation,
ItemPointerGetBlockNumber(&(s->currentItemData)));
p = BufferGetPage(b);
n = ItemPointerGetOffsetNumber(&(s->currentItemData));
it = (IndexTuple) PageGetItem(p, PageGetItemId(p, n));
s->xs_ctup.t_self = it->t_tid;
ReleaseBuffer(b);
return true;
}

View File

@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtree.c,v 1.70 2002/03/02 21:39:19 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtree.c,v 1.71 2002/05/20 23:51:41 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1189,7 +1189,6 @@ rtbulkdelete(PG_FUNCTION_ARGS)
BlockNumber num_pages;
double tuples_removed;
double num_index_tuples;
RetrieveIndexResult res;
IndexScanDesc iscan;
tuples_removed = 0;
@@ -1206,23 +1205,20 @@ rtbulkdelete(PG_FUNCTION_ARGS)
*/
/* walk through the entire index */
iscan = index_beginscan(rel, false, 0, (ScanKey) NULL);
iscan = index_beginscan(NULL, rel, SnapshotAny, 0, (ScanKey) NULL);
while ((res = index_getnext(iscan, ForwardScanDirection))
!= (RetrieveIndexResult) NULL)
while (index_getnext_indexitem(iscan, ForwardScanDirection))
{
ItemPointer heapptr = &res->heap_iptr;
if (callback(heapptr, callback_state))
if (callback(&iscan->xs_ctup.t_self, callback_state))
{
ItemPointer indexptr = &res->index_iptr;
ItemPointerData indextup = iscan->currentItemData;
BlockNumber blkno;
OffsetNumber offnum;
Buffer buf;
Page page;
blkno = ItemPointerGetBlockNumber(indexptr);
offnum = ItemPointerGetOffsetNumber(indexptr);
blkno = ItemPointerGetBlockNumber(&indextup);
offnum = ItemPointerGetOffsetNumber(&indextup);
/* adjust any scans that will be affected by this deletion */
/* (namely, my own scan) */
@@ -1240,8 +1236,6 @@ rtbulkdelete(PG_FUNCTION_ARGS)
}
else
num_index_tuples += 1;
pfree(res);
}
index_endscan(iscan);

View File

@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtscan.c,v 1.40 2002/03/05 05:30:40 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtscan.c,v 1.41 2002/05/20 23:51:41 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -54,12 +54,11 @@ Datum
rtbeginscan(PG_FUNCTION_ARGS)
{
Relation r = (Relation) PG_GETARG_POINTER(0);
bool fromEnd = PG_GETARG_BOOL(1);
uint16 nkeys = PG_GETARG_UINT16(2);
ScanKey key = (ScanKey) PG_GETARG_POINTER(3);
int nkeys = PG_GETARG_INT32(1);
ScanKey key = (ScanKey) PG_GETARG_POINTER(2);
IndexScanDesc s;
s = RelationGetIndexScan(r, fromEnd, nkeys, key);
s = RelationGetIndexScan(r, nkeys, key);
rtregscan(s);
@@ -70,8 +69,7 @@ Datum
rtrescan(PG_FUNCTION_ARGS)
{
IndexScanDesc s = (IndexScanDesc) PG_GETARG_POINTER(0);
bool fromEnd = PG_GETARG_BOOL(1);
ScanKey key = (ScanKey) PG_GETARG_POINTER(2);
ScanKey key = (ScanKey) PG_GETARG_POINTER(1);
RTreeScanOpaque p;
RegProcedure internal_proc;
int i;
@@ -82,18 +80,6 @@ rtrescan(PG_FUNCTION_ARGS)
ItemPointerSetInvalid(&s->currentItemData);
ItemPointerSetInvalid(&s->currentMarkData);
/*
* Set flags.
*/
if (RelationGetNumberOfBlocks(s->relation) == 0)
s->flags = ScanUnmarked;
else if (fromEnd)
s->flags = ScanUnmarked | ScanUncheckedPrevious;
else
s->flags = ScanUnmarked | ScanUncheckedNext;
s->scanFromEnd = fromEnd;
if (s->numberOfKeys > 0)
{
memmove(s->keyData,
@@ -133,7 +119,7 @@ rtrescan(PG_FUNCTION_ARGS)
for (i = 0; i < s->numberOfKeys; i++)
{
p->s_internalKey[i].sk_argument = s->keyData[i].sk_argument;
internal_proc = RTMapOperator(s->relation,
internal_proc = RTMapOperator(s->indexRelation,
s->keyData[i].sk_attno,
s->keyData[i].sk_procedure);
ScanKeyEntryInitialize(&(p->s_internalKey[i]),
@@ -306,7 +292,7 @@ rtadjscans(Relation r, int op, BlockNumber blkno, OffsetNumber offnum)
relid = RelationGetRelid(r);
for (l = RTScans; l != (RTScanList) NULL; l = l->rtsl_next)
{
if (RelationGetRelid(l->rtsl_scan->relation) == relid)
if (RelationGetRelid(l->rtsl_scan->indexRelation) == relid)
rtadjone(l->rtsl_scan, op, blkno, offnum);
}
}