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:
parent
c961474c96
commit
44fbe20d62
|
@ -922,10 +922,9 @@ get_pkey_attnames(Oid relid, int16 *numatts)
|
|||
indexRelation = heap_openr(IndexRelationName, AccessShareLock);
|
||||
ScanKeyEntryInitialize(&entry, 0, Anum_pg_index_indrelid,
|
||||
F_OIDEQ, ObjectIdGetDatum(relid));
|
||||
scan = heap_beginscan(indexRelation, false, SnapshotNow,
|
||||
1, &entry);
|
||||
scan = heap_beginscan(indexRelation, SnapshotNow, 1, &entry);
|
||||
|
||||
while (HeapTupleIsValid(indexTuple = heap_getnext(scan, 0)))
|
||||
while ((indexTuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
|
||||
{
|
||||
Form_pg_index index = (Form_pg_index) GETSTRUCT(indexTuple);
|
||||
|
||||
|
|
|
@ -59,8 +59,8 @@ database_size(PG_FUNCTION_ARGS)
|
|||
relation = heap_openr(DatabaseRelationName, AccessShareLock);
|
||||
ScanKeyEntryInitialize(&scanKey, 0, Anum_pg_database_datname,
|
||||
F_NAMEEQ, NameGetDatum(dbname));
|
||||
scan = heap_beginscan(relation, 0, SnapshotNow, 1, &scanKey);
|
||||
tuple = heap_getnext(scan, 0);
|
||||
scan = heap_beginscan(relation, SnapshotNow, 1, &scanKey);
|
||||
tuple = heap_getnext(scan, ForwardScanDirection);
|
||||
|
||||
if (!HeapTupleIsValid(tuple))
|
||||
elog(ERROR, "database %s does not exist", NameStr(*dbname));
|
||||
|
|
|
@ -93,12 +93,12 @@ active_listeners(text *relname)
|
|||
Anum_pg_listener_relname,
|
||||
F_NAMEEQ,
|
||||
PointerGetDatum(listen_name));
|
||||
sRel = heap_beginscan(lRel, 0, SnapshotNow, 1, &key);
|
||||
sRel = heap_beginscan(lRel, SnapshotNow, 1, &key);
|
||||
}
|
||||
else
|
||||
sRel = heap_beginscan(lRel, 0, SnapshotNow, 0, (ScanKey) NULL);
|
||||
sRel = heap_beginscan(lRel, SnapshotNow, 0, (ScanKey) NULL);
|
||||
|
||||
while (HeapTupleIsValid(lTuple = heap_getnext(sRel, 0)))
|
||||
while ((lTuple = heap_getnext(sRel, ForwardScanDirection)) != NULL)
|
||||
{
|
||||
d = heap_getattr(lTuple, Anum_pg_listener_pid, tdesc, &isnull);
|
||||
pid = DatumGetInt32(d);
|
||||
|
@ -111,14 +111,3 @@ active_listeners(text *relname)
|
|||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
/* end of file */
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* tab-width: 4
|
||||
* c-indent-level: 4
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
*/
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* $Header: /cvsroot/pgsql/contrib/pgstattuple/pgstattuple.c,v 1.5 2002/03/30 01:02:41 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/contrib/pgstattuple/pgstattuple.c,v 1.6 2002/05/20 23:51:40 tgl Exp $
|
||||
*
|
||||
* Copyright (c) 2001 Tatsuo Ishii
|
||||
*
|
||||
|
@ -70,9 +70,9 @@ pgstattuple(PG_FUNCTION_ARGS)
|
|||
rel = heap_openrv(relrv, AccessShareLock);
|
||||
|
||||
nblocks = RelationGetNumberOfBlocks(rel);
|
||||
scan = heap_beginscan(rel, false, SnapshotAny, 0, NULL);
|
||||
scan = heap_beginscan(rel, SnapshotAny, 0, NULL);
|
||||
|
||||
while ((tuple = heap_getnext(scan, 0)))
|
||||
while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
|
||||
{
|
||||
if (HeapTupleSatisfiesNow(tuple->t_data))
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/bootstrap/bootstrap.c,v 1.129 2002/05/17 01:19:16 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/bootstrap/bootstrap.c,v 1.130 2002/05/20 23:51:41 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -482,18 +482,18 @@ boot_openrel(char *relname)
|
|||
if (Typ == (struct typmap **) NULL)
|
||||
{
|
||||
rel = heap_openr(TypeRelationName, NoLock);
|
||||
scan = heap_beginscan(rel, 0, SnapshotNow, 0, (ScanKey) NULL);
|
||||
scan = heap_beginscan(rel, SnapshotNow, 0, (ScanKey) NULL);
|
||||
i = 0;
|
||||
while (HeapTupleIsValid(tup = heap_getnext(scan, 0)))
|
||||
while ((tup = heap_getnext(scan, ForwardScanDirection)) != NULL)
|
||||
++i;
|
||||
heap_endscan(scan);
|
||||
app = Typ = ALLOC(struct typmap *, i + 1);
|
||||
while (i-- > 0)
|
||||
*app++ = ALLOC(struct typmap, 1);
|
||||
*app = (struct typmap *) NULL;
|
||||
scan = heap_beginscan(rel, 0, SnapshotNow, 0, (ScanKey) NULL);
|
||||
scan = heap_beginscan(rel, SnapshotNow, 0, (ScanKey) NULL);
|
||||
app = Typ;
|
||||
while (HeapTupleIsValid(tup = heap_getnext(scan, 0)))
|
||||
while ((tup = heap_getnext(scan, ForwardScanDirection)) != NULL)
|
||||
{
|
||||
(*app)->am_oid = tup->t_data->t_oid;
|
||||
memcpy((char *) &(*app)->am_typ,
|
||||
|
@ -858,18 +858,18 @@ gettype(char *type)
|
|||
}
|
||||
elog(DEBUG3, "external type: %s", type);
|
||||
rel = heap_openr(TypeRelationName, NoLock);
|
||||
scan = heap_beginscan(rel, 0, SnapshotNow, 0, (ScanKey) NULL);
|
||||
scan = heap_beginscan(rel, SnapshotNow, 0, (ScanKey) NULL);
|
||||
i = 0;
|
||||
while (HeapTupleIsValid(tup = heap_getnext(scan, 0)))
|
||||
while ((tup = heap_getnext(scan, ForwardScanDirection)) != NULL)
|
||||
++i;
|
||||
heap_endscan(scan);
|
||||
app = Typ = ALLOC(struct typmap *, i + 1);
|
||||
while (i-- > 0)
|
||||
*app++ = ALLOC(struct typmap, 1);
|
||||
*app = (struct typmap *) NULL;
|
||||
scan = heap_beginscan(rel, 0, SnapshotNow, 0, (ScanKey) NULL);
|
||||
scan = heap_beginscan(rel, SnapshotNow, 0, (ScanKey) NULL);
|
||||
app = Typ;
|
||||
while (HeapTupleIsValid(tup = heap_getnext(scan, 0)))
|
||||
while ((tup = heap_getnext(scan, ForwardScanDirection)) != NULL)
|
||||
{
|
||||
(*app)->am_oid = tup->t_data->t_oid;
|
||||
memmove((char *) &(*app++)->am_typ,
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/catalog/aclchk.c,v 1.67 2002/04/27 03:45:00 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/catalog/aclchk.c,v 1.68 2002/05/20 23:51:41 tgl Exp $
|
||||
*
|
||||
* NOTES
|
||||
* See acl.h.
|
||||
|
@ -295,8 +295,8 @@ ExecuteGrantStmt_Database(GrantStmt *stmt)
|
|||
ScanKeyEntryInitialize(&entry[0], 0,
|
||||
Anum_pg_database_datname, F_NAMEEQ,
|
||||
CStringGetDatum(dbname));
|
||||
scan = heap_beginscan(relation, 0, SnapshotNow, 1, entry);
|
||||
tuple = heap_getnext(scan, 0);
|
||||
scan = heap_beginscan(relation, SnapshotNow, 1, entry);
|
||||
tuple = heap_getnext(scan, ForwardScanDirection);
|
||||
if (!HeapTupleIsValid(tuple))
|
||||
elog(ERROR, "database \"%s\" not found", dbname);
|
||||
pg_database_tuple = (Form_pg_database) GETSTRUCT(tuple);
|
||||
|
@ -1045,8 +1045,8 @@ pg_database_aclcheck(Oid db_oid, Oid userid, AclMode mode)
|
|||
ScanKeyEntryInitialize(&entry[0], 0x0,
|
||||
ObjectIdAttributeNumber, F_OIDEQ,
|
||||
ObjectIdGetDatum(db_oid));
|
||||
scan = heap_beginscan(pg_database, 0, SnapshotNow, 1, entry);
|
||||
tuple = heap_getnext(scan, 0);
|
||||
scan = heap_beginscan(pg_database, SnapshotNow, 1, entry);
|
||||
tuple = heap_getnext(scan, ForwardScanDirection);
|
||||
if (!HeapTupleIsValid(tuple))
|
||||
elog(ERROR, "pg_database_aclcheck: database %u not found", db_oid);
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.199 2002/05/12 23:43:02 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.200 2002/05/20 23:51:41 tgl Exp $
|
||||
*
|
||||
*
|
||||
* INTERFACE ROUTINES
|
||||
|
@ -776,7 +776,6 @@ RelationRemoveInheritance(Relation relation)
|
|||
ObjectIdGetDatum(RelationGetRelid(relation)));
|
||||
|
||||
scan = heap_beginscan(catalogRelation,
|
||||
false,
|
||||
SnapshotNow,
|
||||
1,
|
||||
&entry);
|
||||
|
@ -784,8 +783,7 @@ RelationRemoveInheritance(Relation relation)
|
|||
/*
|
||||
* if any subclasses exist, then we disallow the deletion.
|
||||
*/
|
||||
tuple = heap_getnext(scan, 0);
|
||||
if (HeapTupleIsValid(tuple))
|
||||
if ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
|
||||
{
|
||||
Oid subclass = ((Form_pg_inherits) GETSTRUCT(tuple))->inhrelid;
|
||||
char *subclassname;
|
||||
|
@ -808,12 +806,11 @@ RelationRemoveInheritance(Relation relation)
|
|||
entry.sk_attno = Anum_pg_inherits_inhrelid;
|
||||
|
||||
scan = heap_beginscan(catalogRelation,
|
||||
false,
|
||||
SnapshotNow,
|
||||
1,
|
||||
&entry);
|
||||
|
||||
while (HeapTupleIsValid(tuple = heap_getnext(scan, 0)))
|
||||
while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
|
||||
{
|
||||
simple_heap_delete(catalogRelation, &tuple->t_self);
|
||||
found = true;
|
||||
|
@ -1074,7 +1071,6 @@ DeleteTypeTuple(Relation rel)
|
|||
ObjectIdGetDatum(RelationGetRelid(rel)));
|
||||
|
||||
pg_type_scan = heap_beginscan(pg_type_desc,
|
||||
0,
|
||||
SnapshotNow,
|
||||
1,
|
||||
&key);
|
||||
|
@ -1083,7 +1079,7 @@ DeleteTypeTuple(Relation rel)
|
|||
* use heap_getnext() to fetch the pg_type tuple. If this tuple is
|
||||
* not valid then something's wrong.
|
||||
*/
|
||||
tup = heap_getnext(pg_type_scan, 0);
|
||||
tup = heap_getnext(pg_type_scan, ForwardScanDirection);
|
||||
|
||||
if (!HeapTupleIsValid(tup))
|
||||
{
|
||||
|
@ -1109,7 +1105,6 @@ DeleteTypeTuple(Relation rel)
|
|||
ObjectIdGetDatum(typoid));
|
||||
|
||||
pg_attribute_scan = heap_beginscan(pg_attribute_desc,
|
||||
0,
|
||||
SnapshotNow,
|
||||
1,
|
||||
&attkey);
|
||||
|
@ -1118,7 +1113,7 @@ DeleteTypeTuple(Relation rel)
|
|||
* try and get a pg_attribute tuple. if we succeed it means we can't
|
||||
* delete the relation because something depends on the schema.
|
||||
*/
|
||||
atttup = heap_getnext(pg_attribute_scan, 0);
|
||||
atttup = heap_getnext(pg_attribute_scan, ForwardScanDirection);
|
||||
|
||||
if (HeapTupleIsValid(atttup))
|
||||
{
|
||||
|
@ -1833,9 +1828,9 @@ RemoveAttrDefaults(Relation rel)
|
|||
F_OIDEQ,
|
||||
ObjectIdGetDatum(RelationGetRelid(rel)));
|
||||
|
||||
adscan = heap_beginscan(adrel, 0, SnapshotNow, 1, &key);
|
||||
adscan = heap_beginscan(adrel, SnapshotNow, 1, &key);
|
||||
|
||||
while (HeapTupleIsValid(tup = heap_getnext(adscan, 0)))
|
||||
while ((tup = heap_getnext(adscan, ForwardScanDirection)) != NULL)
|
||||
simple_heap_delete(adrel, &tup->t_self);
|
||||
|
||||
heap_endscan(adscan);
|
||||
|
@ -1856,9 +1851,9 @@ RemoveRelChecks(Relation rel)
|
|||
F_OIDEQ,
|
||||
ObjectIdGetDatum(RelationGetRelid(rel)));
|
||||
|
||||
rcscan = heap_beginscan(rcrel, 0, SnapshotNow, 1, &key);
|
||||
rcscan = heap_beginscan(rcrel, SnapshotNow, 1, &key);
|
||||
|
||||
while (HeapTupleIsValid(tup = heap_getnext(rcscan, 0)))
|
||||
while ((tup = heap_getnext(rcscan, ForwardScanDirection)) != NULL)
|
||||
simple_heap_delete(rcrel, &tup->t_self);
|
||||
|
||||
heap_endscan(rcscan);
|
||||
|
@ -1946,14 +1941,14 @@ RemoveCheckConstraint(Relation rel, const char *constrName, bool inh)
|
|||
PointerGetDatum(constrName));
|
||||
|
||||
/* Begin scanning the heap */
|
||||
rcscan = heap_beginscan(rcrel, 0, SnapshotNow, 2, key);
|
||||
rcscan = heap_beginscan(rcrel, SnapshotNow, 2, key);
|
||||
|
||||
/*
|
||||
* Scan over the result set, removing any matching entries. Note that
|
||||
* this has the side-effect of removing ALL CHECK constraints that
|
||||
* share the specified constraint name.
|
||||
*/
|
||||
while (HeapTupleIsValid(rctup = heap_getnext(rcscan, 0)))
|
||||
while ((rctup = heap_getnext(rcscan, ForwardScanDirection)) != NULL)
|
||||
{
|
||||
simple_heap_delete(rcrel, &rctup->t_self);
|
||||
++rel_deleted;
|
||||
|
@ -2008,9 +2003,9 @@ RemoveStatistics(Relation rel)
|
|||
ScanKeyEntryInitialize(&key, 0x0, Anum_pg_statistic_starelid,
|
||||
F_OIDEQ,
|
||||
ObjectIdGetDatum(RelationGetRelid(rel)));
|
||||
scan = heap_beginscan(pgstatistic, false, SnapshotNow, 1, &key);
|
||||
scan = heap_beginscan(pgstatistic, SnapshotNow, 1, &key);
|
||||
|
||||
while (HeapTupleIsValid(tuple = heap_getnext(scan, 0)))
|
||||
while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
|
||||
simple_heap_delete(pgstatistic, &tuple->t_self);
|
||||
|
||||
heap_endscan(scan);
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.177 2002/04/27 21:24:34 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.178 2002/05/20 23:51:41 tgl Exp $
|
||||
*
|
||||
*
|
||||
* INTERFACE ROUTINES
|
||||
|
@ -1067,10 +1067,9 @@ IndexesAreActive(Oid relid, bool confirmCommitted)
|
|||
indexRelation = heap_openr(IndexRelationName, AccessShareLock);
|
||||
ScanKeyEntryInitialize(&entry, 0, Anum_pg_index_indrelid,
|
||||
F_OIDEQ, ObjectIdGetDatum(relid));
|
||||
scan = heap_beginscan(indexRelation, false, SnapshotNow,
|
||||
1, &entry);
|
||||
if (!heap_getnext(scan, 0))
|
||||
isactive = true;
|
||||
scan = heap_beginscan(indexRelation, SnapshotNow, 1, &entry);
|
||||
if (heap_getnext(scan, ForwardScanDirection) == NULL)
|
||||
isactive = true; /* no indexes, so report "active" */
|
||||
heap_endscan(scan);
|
||||
heap_close(indexRelation, AccessShareLock);
|
||||
return isactive;
|
||||
|
@ -1121,8 +1120,8 @@ setRelhasindex(Oid relid, bool hasindex, bool isprimary, Oid reltoastidxid)
|
|||
F_OIDEQ,
|
||||
ObjectIdGetDatum(relid));
|
||||
|
||||
pg_class_scan = heap_beginscan(pg_class, 0, SnapshotNow, 1, key);
|
||||
tuple = heap_getnext(pg_class_scan, 0);
|
||||
pg_class_scan = heap_beginscan(pg_class, SnapshotNow, 1, key);
|
||||
tuple = heap_getnext(pg_class_scan, ForwardScanDirection);
|
||||
}
|
||||
|
||||
if (!HeapTupleIsValid(tuple))
|
||||
|
@ -1341,8 +1340,8 @@ UpdateStats(Oid relid, double reltuples)
|
|||
F_OIDEQ,
|
||||
ObjectIdGetDatum(relid));
|
||||
|
||||
pg_class_scan = heap_beginscan(pg_class, 0, SnapshotNow, 1, key);
|
||||
tuple = heap_getnext(pg_class_scan, 0);
|
||||
pg_class_scan = heap_beginscan(pg_class, SnapshotNow, 1, key);
|
||||
tuple = heap_getnext(pg_class_scan, ForwardScanDirection);
|
||||
}
|
||||
|
||||
if (!HeapTupleIsValid(tuple))
|
||||
|
@ -1563,7 +1562,6 @@ IndexBuildHeapScan(Relation heapRelation,
|
|||
}
|
||||
|
||||
scan = heap_beginscan(heapRelation, /* relation */
|
||||
0, /* start at end */
|
||||
snapshot, /* seeself */
|
||||
0, /* number of keys */
|
||||
(ScanKey) NULL); /* scan key */
|
||||
|
@ -1573,7 +1571,7 @@ IndexBuildHeapScan(Relation heapRelation,
|
|||
/*
|
||||
* Scan all tuples in the base relation.
|
||||
*/
|
||||
while (HeapTupleIsValid(heapTuple = heap_getnext(scan, 0)))
|
||||
while ((heapTuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
|
||||
{
|
||||
bool tupleIsAlive;
|
||||
|
||||
|
@ -1967,10 +1965,9 @@ reindex_relation(Oid relid, bool force)
|
|||
indexRelation = heap_openr(IndexRelationName, AccessShareLock);
|
||||
ScanKeyEntryInitialize(&entry, 0, Anum_pg_index_indrelid,
|
||||
F_OIDEQ, ObjectIdGetDatum(relid));
|
||||
scan = heap_beginscan(indexRelation, false, SnapshotNow,
|
||||
1, &entry);
|
||||
scan = heap_beginscan(indexRelation, SnapshotNow, 1, &entry);
|
||||
reindexed = false;
|
||||
while (HeapTupleIsValid(indexTuple = heap_getnext(scan, 0)))
|
||||
while ((indexTuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
|
||||
{
|
||||
Form_pg_index index = (Form_pg_index) GETSTRUCT(indexTuple);
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/catalog/namespace.c,v 1.21 2002/05/17 20:53:33 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/catalog/namespace.c,v 1.22 2002/05/20 23:51:41 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -1588,9 +1588,9 @@ FindTempRelations(Oid tempNamespaceId)
|
|||
ObjectIdGetDatum(tempNamespaceId));
|
||||
|
||||
pgclass = heap_openr(RelationRelationName, AccessShareLock);
|
||||
scan = heap_beginscan(pgclass, false, SnapshotNow, 1, &key);
|
||||
scan = heap_beginscan(pgclass, SnapshotNow, 1, &key);
|
||||
|
||||
while (HeapTupleIsValid(tuple = heap_getnext(scan, 0)))
|
||||
while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
|
||||
{
|
||||
switch (((Form_pg_class) GETSTRUCT(tuple))->relkind)
|
||||
{
|
||||
|
@ -1627,9 +1627,9 @@ FindDeletionConstraints(List *relOids)
|
|||
* Scan pg_inherits to find parents and children that are in the list.
|
||||
*/
|
||||
inheritsrel = heap_openr(InheritsRelationName, AccessShareLock);
|
||||
scan = heap_beginscan(inheritsrel, 0, SnapshotNow, 0, NULL);
|
||||
scan = heap_beginscan(inheritsrel, SnapshotNow, 0, NULL);
|
||||
|
||||
while (HeapTupleIsValid(tuple = heap_getnext(scan, 0)))
|
||||
while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
|
||||
{
|
||||
Oid inhrelid = ((Form_pg_inherits) GETSTRUCT(tuple))->inhrelid;
|
||||
Oid inhparent = ((Form_pg_inherits) GETSTRUCT(tuple))->inhparent;
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_largeobject.c,v 1.10 2001/08/10 20:52:24 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_largeobject.c,v 1.11 2002/05/20 23:51:42 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -88,9 +88,7 @@ LargeObjectDrop(Oid loid)
|
|||
Relation pg_lo_idx;
|
||||
ScanKeyData skey[1];
|
||||
IndexScanDesc sd;
|
||||
RetrieveIndexResult indexRes;
|
||||
HeapTupleData tuple;
|
||||
Buffer buffer;
|
||||
HeapTuple tuple;
|
||||
|
||||
ScanKeyEntryInitialize(&skey[0],
|
||||
(bits16) 0x0,
|
||||
|
@ -101,22 +99,12 @@ LargeObjectDrop(Oid loid)
|
|||
pg_largeobject = heap_openr(LargeObjectRelationName, RowShareLock);
|
||||
pg_lo_idx = index_openr(LargeObjectLOidPNIndex);
|
||||
|
||||
sd = index_beginscan(pg_lo_idx, false, 1, skey);
|
||||
sd = index_beginscan(pg_largeobject, pg_lo_idx, SnapshotNow, 1, skey);
|
||||
|
||||
tuple.t_datamcxt = CurrentMemoryContext;
|
||||
tuple.t_data = NULL;
|
||||
|
||||
while ((indexRes = index_getnext(sd, ForwardScanDirection)))
|
||||
while ((tuple = index_getnext(sd, ForwardScanDirection)) != NULL)
|
||||
{
|
||||
tuple.t_self = indexRes->heap_iptr;
|
||||
heap_fetch(pg_largeobject, SnapshotNow, &tuple, &buffer, sd);
|
||||
pfree(indexRes);
|
||||
if (tuple.t_data != NULL)
|
||||
{
|
||||
simple_heap_delete(pg_largeobject, &tuple.t_self);
|
||||
ReleaseBuffer(buffer);
|
||||
found = true;
|
||||
}
|
||||
simple_heap_delete(pg_largeobject, &tuple->t_self);
|
||||
found = true;
|
||||
}
|
||||
|
||||
index_endscan(sd);
|
||||
|
@ -136,9 +124,7 @@ LargeObjectExists(Oid loid)
|
|||
Relation pg_lo_idx;
|
||||
ScanKeyData skey[1];
|
||||
IndexScanDesc sd;
|
||||
RetrieveIndexResult indexRes;
|
||||
HeapTupleData tuple;
|
||||
Buffer buffer;
|
||||
HeapTuple tuple;
|
||||
|
||||
/*
|
||||
* See if we can find any tuples belonging to the specified LO
|
||||
|
@ -152,23 +138,10 @@ LargeObjectExists(Oid loid)
|
|||
pg_largeobject = heap_openr(LargeObjectRelationName, RowShareLock);
|
||||
pg_lo_idx = index_openr(LargeObjectLOidPNIndex);
|
||||
|
||||
sd = index_beginscan(pg_lo_idx, false, 1, skey);
|
||||
sd = index_beginscan(pg_largeobject, pg_lo_idx, SnapshotNow, 1, skey);
|
||||
|
||||
tuple.t_datamcxt = CurrentMemoryContext;
|
||||
tuple.t_data = NULL;
|
||||
|
||||
while ((indexRes = index_getnext(sd, ForwardScanDirection)))
|
||||
{
|
||||
tuple.t_self = indexRes->heap_iptr;
|
||||
heap_fetch(pg_largeobject, SnapshotNow, &tuple, &buffer, sd);
|
||||
pfree(indexRes);
|
||||
if (tuple.t_data != NULL)
|
||||
{
|
||||
retval = true;
|
||||
ReleaseBuffer(buffer);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ((tuple = index_getnext(sd, ForwardScanDirection)) != NULL)
|
||||
retval = true;
|
||||
|
||||
index_endscan(sd);
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/analyze.c,v 1.32 2002/04/16 23:08:10 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/analyze.c,v 1.33 2002/05/20 23:51:42 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -524,8 +524,8 @@ acquire_sample_rows(Relation onerel, HeapTuple *rows, int targrows,
|
|||
/*
|
||||
* Do a simple linear scan until we reach the target number of rows.
|
||||
*/
|
||||
scan = heap_beginscan(onerel, false, SnapshotNow, 0, NULL);
|
||||
while (HeapTupleIsValid(tuple = heap_getnext(scan, 0)))
|
||||
scan = heap_beginscan(onerel, SnapshotNow, 0, NULL);
|
||||
while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
|
||||
{
|
||||
rows[numrows++] = heap_copytuple(tuple);
|
||||
if (numrows >= targrows)
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/async.c,v 1.84 2002/05/05 00:03:28 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/async.c,v 1.85 2002/05/20 23:51:42 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -204,8 +204,8 @@ Async_Listen(char *relname, int pid)
|
|||
lRel = heap_openr(ListenerRelationName, AccessExclusiveLock);
|
||||
|
||||
/* Detect whether we are already listening on this relname */
|
||||
scan = heap_beginscan(lRel, 0, SnapshotNow, 0, (ScanKey) NULL);
|
||||
while (HeapTupleIsValid(tuple = heap_getnext(scan, 0)))
|
||||
scan = heap_beginscan(lRel, SnapshotNow, 0, (ScanKey) NULL);
|
||||
while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
|
||||
{
|
||||
Form_pg_listener listener = (Form_pg_listener) GETSTRUCT(tuple);
|
||||
|
||||
|
@ -305,8 +305,8 @@ Async_Unlisten(char *relname, int pid)
|
|||
|
||||
lRel = heap_openr(ListenerRelationName, AccessExclusiveLock);
|
||||
|
||||
scan = heap_beginscan(lRel, 0, SnapshotNow, 0, (ScanKey) NULL);
|
||||
while (HeapTupleIsValid(tuple = heap_getnext(scan, 0)))
|
||||
scan = heap_beginscan(lRel, SnapshotNow, 0, (ScanKey) NULL);
|
||||
while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
|
||||
{
|
||||
Form_pg_listener listener = (Form_pg_listener) GETSTRUCT(tuple);
|
||||
|
||||
|
@ -369,9 +369,9 @@ Async_UnlistenAll(void)
|
|||
Anum_pg_listener_pid,
|
||||
F_INT4EQ,
|
||||
Int32GetDatum(MyProcPid));
|
||||
scan = heap_beginscan(lRel, 0, SnapshotNow, 1, key);
|
||||
scan = heap_beginscan(lRel, SnapshotNow, 1, key);
|
||||
|
||||
while (HeapTupleIsValid(lTuple = heap_getnext(scan, 0)))
|
||||
while ((lTuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
|
||||
simple_heap_delete(lRel, &lTuple->t_self);
|
||||
|
||||
heap_endscan(scan);
|
||||
|
@ -472,9 +472,9 @@ AtCommit_Notify(void)
|
|||
|
||||
lRel = heap_openr(ListenerRelationName, AccessExclusiveLock);
|
||||
tdesc = RelationGetDescr(lRel);
|
||||
scan = heap_beginscan(lRel, 0, SnapshotNow, 0, (ScanKey) NULL);
|
||||
scan = heap_beginscan(lRel, SnapshotNow, 0, (ScanKey) NULL);
|
||||
|
||||
while (HeapTupleIsValid(lTuple = heap_getnext(scan, 0)))
|
||||
while ((lTuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
|
||||
{
|
||||
Form_pg_listener listener = (Form_pg_listener) GETSTRUCT(lTuple);
|
||||
char *relname = NameStr(listener->relname);
|
||||
|
@ -773,7 +773,7 @@ ProcessIncomingNotify(void)
|
|||
Anum_pg_listener_pid,
|
||||
F_INT4EQ,
|
||||
Int32GetDatum(MyProcPid));
|
||||
scan = heap_beginscan(lRel, 0, SnapshotNow, 1, key);
|
||||
scan = heap_beginscan(lRel, SnapshotNow, 1, key);
|
||||
|
||||
/* Prepare data for rewriting 0 into notification field */
|
||||
nulls[0] = nulls[1] = nulls[2] = ' ';
|
||||
|
@ -782,7 +782,7 @@ ProcessIncomingNotify(void)
|
|||
value[0] = value[1] = value[2] = (Datum) 0;
|
||||
value[Anum_pg_listener_notify - 1] = Int32GetDatum(0);
|
||||
|
||||
while (HeapTupleIsValid(lTuple = heap_getnext(scan, 0)))
|
||||
while ((lTuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
|
||||
{
|
||||
Form_pg_listener listener = (Form_pg_listener) GETSTRUCT(lTuple);
|
||||
char *relname = NameStr(listener->relname);
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/cluster.c,v 1.79 2002/04/27 21:24:34 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/cluster.c,v 1.80 2002/05/20 23:51:42 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -217,7 +217,7 @@ rebuildheap(Oid OIDNewHeap, Oid OIDOldHeap, Oid OIDOldIndex)
|
|||
LocalOldHeap,
|
||||
LocalOldIndex;
|
||||
IndexScanDesc ScanDesc;
|
||||
RetrieveIndexResult ScanResult;
|
||||
HeapTuple LocalHeapTuple;
|
||||
|
||||
/*
|
||||
* Open the relations I need. Scan through the OldHeap on the OldIndex
|
||||
|
@ -227,36 +227,24 @@ rebuildheap(Oid OIDNewHeap, Oid OIDOldHeap, Oid OIDOldIndex)
|
|||
LocalOldHeap = heap_open(OIDOldHeap, AccessExclusiveLock);
|
||||
LocalOldIndex = index_open(OIDOldIndex);
|
||||
|
||||
ScanDesc = index_beginscan(LocalOldIndex, false, 0, (ScanKey) NULL);
|
||||
ScanDesc = index_beginscan(LocalOldHeap, LocalOldIndex,
|
||||
SnapshotNow, 0, (ScanKey) NULL);
|
||||
|
||||
while ((ScanResult = index_getnext(ScanDesc, ForwardScanDirection)) != NULL)
|
||||
while ((LocalHeapTuple = index_getnext(ScanDesc, ForwardScanDirection)) != NULL)
|
||||
{
|
||||
HeapTupleData LocalHeapTuple;
|
||||
Buffer LocalBuffer;
|
||||
/*
|
||||
* We must copy the tuple because heap_insert() will overwrite
|
||||
* the commit-status fields of the tuple it's handed, and the
|
||||
* retrieved tuple will actually be in a disk buffer! Thus,
|
||||
* the source relation would get trashed, which is bad news if
|
||||
* we abort later on. (This was a bug in releases thru 7.0)
|
||||
*/
|
||||
HeapTuple copiedTuple = heap_copytuple(LocalHeapTuple);
|
||||
|
||||
heap_insert(LocalNewHeap, copiedTuple);
|
||||
heap_freetuple(copiedTuple);
|
||||
|
||||
CHECK_FOR_INTERRUPTS();
|
||||
|
||||
LocalHeapTuple.t_self = ScanResult->heap_iptr;
|
||||
LocalHeapTuple.t_datamcxt = NULL;
|
||||
LocalHeapTuple.t_data = NULL;
|
||||
heap_fetch(LocalOldHeap, SnapshotNow, &LocalHeapTuple, &LocalBuffer,
|
||||
ScanDesc);
|
||||
if (LocalHeapTuple.t_data != NULL)
|
||||
{
|
||||
/*
|
||||
* We must copy the tuple because heap_insert() will overwrite
|
||||
* the commit-status fields of the tuple it's handed, and the
|
||||
* retrieved tuple will actually be in a disk buffer! Thus,
|
||||
* the source relation would get trashed, which is bad news if
|
||||
* we abort later on. (This was a bug in releases thru 7.0)
|
||||
*/
|
||||
HeapTuple copiedTuple = heap_copytuple(&LocalHeapTuple);
|
||||
|
||||
ReleaseBuffer(LocalBuffer);
|
||||
heap_insert(LocalNewHeap, copiedTuple);
|
||||
heap_freetuple(copiedTuple);
|
||||
}
|
||||
pfree(ScanResult);
|
||||
}
|
||||
|
||||
index_endscan(ScanDesc);
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
* Copyright (c) 1999-2001, PostgreSQL Global Development Group
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/comment.c,v 1.46 2002/05/13 17:45:30 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/comment.c,v 1.47 2002/05/20 23:51:42 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -122,12 +122,9 @@ void
|
|||
CreateComments(Oid oid, Oid classoid, int32 subid, char *comment)
|
||||
{
|
||||
Relation description;
|
||||
Relation descriptionindex;
|
||||
ScanKeyData skey[3];
|
||||
IndexScanDesc sd;
|
||||
RetrieveIndexResult indexRes;
|
||||
HeapTupleData oldtuple;
|
||||
Buffer buffer;
|
||||
SysScanDesc sd;
|
||||
HeapTuple oldtuple;
|
||||
HeapTuple newtuple = NULL;
|
||||
Datum values[Natts_pg_description];
|
||||
char nulls[Natts_pg_description];
|
||||
|
@ -153,11 +150,6 @@ CreateComments(Oid oid, Oid classoid, int32 subid, char *comment)
|
|||
values[i++] = DirectFunctionCall1(textin, CStringGetDatum(comment));
|
||||
}
|
||||
|
||||
/* Open pg_description and its index */
|
||||
|
||||
description = heap_openr(DescriptionRelationName, RowExclusiveLock);
|
||||
descriptionindex = index_openr(DescriptionObjIndex);
|
||||
|
||||
/* Use the index to search for a matching old tuple */
|
||||
|
||||
ScanKeyEntryInitialize(&skey[0],
|
||||
|
@ -178,40 +170,32 @@ CreateComments(Oid oid, Oid classoid, int32 subid, char *comment)
|
|||
(RegProcedure) F_INT4EQ,
|
||||
Int32GetDatum(subid));
|
||||
|
||||
sd = index_beginscan(descriptionindex, false, 3, skey);
|
||||
description = heap_openr(DescriptionRelationName, RowExclusiveLock);
|
||||
|
||||
oldtuple.t_datamcxt = CurrentMemoryContext;
|
||||
oldtuple.t_data = NULL;
|
||||
sd = systable_beginscan(description, DescriptionObjIndex, true,
|
||||
SnapshotNow, 3, skey);
|
||||
|
||||
while ((indexRes = index_getnext(sd, ForwardScanDirection)))
|
||||
while ((oldtuple = systable_getnext(sd)) != NULL)
|
||||
{
|
||||
oldtuple.t_self = indexRes->heap_iptr;
|
||||
heap_fetch(description, SnapshotNow, &oldtuple, &buffer, sd);
|
||||
pfree(indexRes);
|
||||
|
||||
if (oldtuple.t_data == NULL)
|
||||
continue; /* time qual failed */
|
||||
|
||||
/* Found the old tuple, so delete or update it */
|
||||
|
||||
if (comment == NULL)
|
||||
simple_heap_delete(description, &oldtuple.t_self);
|
||||
simple_heap_delete(description, &oldtuple->t_self);
|
||||
else
|
||||
{
|
||||
newtuple = heap_modifytuple(&oldtuple, description, values,
|
||||
newtuple = heap_modifytuple(oldtuple, description, values,
|
||||
nulls, replaces);
|
||||
simple_heap_update(description, &oldtuple.t_self, newtuple);
|
||||
simple_heap_update(description, &oldtuple->t_self, newtuple);
|
||||
}
|
||||
|
||||
ReleaseBuffer(buffer);
|
||||
break; /* Assume there can be only one match */
|
||||
}
|
||||
|
||||
index_endscan(sd);
|
||||
systable_endscan(sd);
|
||||
|
||||
/* If we didn't find an old tuple, insert a new one */
|
||||
|
||||
if (oldtuple.t_data == NULL && comment != NULL)
|
||||
if (newtuple == NULL && comment != NULL)
|
||||
{
|
||||
newtuple = heap_formtuple(RelationGetDescr(description),
|
||||
values, nulls);
|
||||
|
@ -237,7 +221,6 @@ CreateComments(Oid oid, Oid classoid, int32 subid, char *comment)
|
|||
|
||||
/* Done */
|
||||
|
||||
index_close(descriptionindex);
|
||||
heap_close(description, NoLock);
|
||||
}
|
||||
|
||||
|
@ -252,17 +235,9 @@ void
|
|||
DeleteComments(Oid oid, Oid classoid)
|
||||
{
|
||||
Relation description;
|
||||
Relation descriptionindex;
|
||||
ScanKeyData skey[2];
|
||||
IndexScanDesc sd;
|
||||
RetrieveIndexResult indexRes;
|
||||
HeapTupleData oldtuple;
|
||||
Buffer buffer;
|
||||
|
||||
/* Open pg_description and its index */
|
||||
|
||||
description = heap_openr(DescriptionRelationName, RowExclusiveLock);
|
||||
descriptionindex = index_openr(DescriptionObjIndex);
|
||||
SysScanDesc sd;
|
||||
HeapTuple oldtuple;
|
||||
|
||||
/* Use the index to search for all matching old tuples */
|
||||
|
||||
|
@ -278,26 +253,19 @@ DeleteComments(Oid oid, Oid classoid)
|
|||
(RegProcedure) F_OIDEQ,
|
||||
ObjectIdGetDatum(classoid));
|
||||
|
||||
sd = index_beginscan(descriptionindex, false, 2, skey);
|
||||
description = heap_openr(DescriptionRelationName, RowExclusiveLock);
|
||||
|
||||
while ((indexRes = index_getnext(sd, ForwardScanDirection)))
|
||||
sd = systable_beginscan(description, DescriptionObjIndex, true,
|
||||
SnapshotNow, 2, skey);
|
||||
|
||||
while ((oldtuple = systable_getnext(sd)) != NULL)
|
||||
{
|
||||
oldtuple.t_self = indexRes->heap_iptr;
|
||||
heap_fetch(description, SnapshotNow, &oldtuple, &buffer, sd);
|
||||
pfree(indexRes);
|
||||
|
||||
if (oldtuple.t_data == NULL)
|
||||
continue; /* time qual failed */
|
||||
|
||||
simple_heap_delete(description, &oldtuple.t_self);
|
||||
|
||||
ReleaseBuffer(buffer);
|
||||
simple_heap_delete(description, &oldtuple->t_self);
|
||||
}
|
||||
|
||||
/* Done */
|
||||
|
||||
index_endscan(sd);
|
||||
index_close(descriptionindex);
|
||||
systable_endscan(sd);
|
||||
heap_close(description, NoLock);
|
||||
}
|
||||
|
||||
|
@ -449,8 +417,8 @@ CommentDatabase(List *qualname, char *comment)
|
|||
pg_database = heap_openr(DatabaseRelationName, AccessShareLock);
|
||||
ScanKeyEntryInitialize(&entry, 0, Anum_pg_database_datname,
|
||||
F_NAMEEQ, CStringGetDatum(database));
|
||||
scan = heap_beginscan(pg_database, 0, SnapshotNow, 1, &entry);
|
||||
dbtuple = heap_getnext(scan, 0);
|
||||
scan = heap_beginscan(pg_database, SnapshotNow, 1, &entry);
|
||||
dbtuple = heap_getnext(scan, ForwardScanDirection);
|
||||
|
||||
/* Validate database exists, and fetch the db oid */
|
||||
|
||||
|
@ -566,10 +534,10 @@ CommentRule(List *qualname, char *comment)
|
|||
PointerGetDatum(rulename));
|
||||
|
||||
RewriteRelation = heap_openr(RewriteRelationName, AccessShareLock);
|
||||
scanDesc = heap_beginscan(RewriteRelation,
|
||||
0, SnapshotNow, 1, &scanKeyData);
|
||||
scanDesc = heap_beginscan(RewriteRelation, SnapshotNow,
|
||||
1, &scanKeyData);
|
||||
|
||||
tuple = heap_getnext(scanDesc, 0);
|
||||
tuple = heap_getnext(scanDesc, ForwardScanDirection);
|
||||
if (HeapTupleIsValid(tuple))
|
||||
{
|
||||
reloid = ((Form_pg_rewrite) GETSTRUCT(tuple))->ev_class;
|
||||
|
@ -581,7 +549,8 @@ CommentRule(List *qualname, char *comment)
|
|||
reloid = ruleoid = 0; /* keep compiler quiet */
|
||||
}
|
||||
|
||||
if (HeapTupleIsValid(tuple = heap_getnext(scanDesc, 0)))
|
||||
if (HeapTupleIsValid(tuple = heap_getnext(scanDesc,
|
||||
ForwardScanDirection)))
|
||||
elog(ERROR, "There are multiple rules \"%s\""
|
||||
"\n\tPlease specify a relation name as well as a rule name",
|
||||
rulename);
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.153 2002/04/27 03:45:00 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.154 2002/05/20 23:51:42 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -494,9 +494,9 @@ CopyTo(Relation rel, bool binary, bool oids, FILE *fp,
|
|||
CopySendData(&tmp, sizeof(int32), fp);
|
||||
}
|
||||
|
||||
scandesc = heap_beginscan(rel, 0, QuerySnapshot, 0, NULL);
|
||||
scandesc = heap_beginscan(rel, QuerySnapshot, 0, NULL);
|
||||
|
||||
while (HeapTupleIsValid(tuple = heap_getnext(scandesc, 0)))
|
||||
while ((tuple = heap_getnext(scandesc, ForwardScanDirection)) != NULL)
|
||||
{
|
||||
bool need_delim = false;
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/dbcommands.c,v 1.89 2002/05/17 01:19:17 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/dbcommands.c,v 1.90 2002/05/20 23:51:42 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -387,9 +387,9 @@ dropdb(const char *dbname)
|
|||
ScanKeyEntryInitialize(&key, 0, ObjectIdAttributeNumber,
|
||||
F_OIDEQ, ObjectIdGetDatum(db_id));
|
||||
|
||||
pgdbscan = heap_beginscan(pgdbrel, 0, SnapshotNow, 1, &key);
|
||||
pgdbscan = heap_beginscan(pgdbrel, SnapshotNow, 1, &key);
|
||||
|
||||
tup = heap_getnext(pgdbscan, 0);
|
||||
tup = heap_getnext(pgdbscan, ForwardScanDirection);
|
||||
if (!HeapTupleIsValid(tup))
|
||||
{
|
||||
/*
|
||||
|
@ -463,8 +463,8 @@ AlterDatabaseSet(AlterDatabaseSetStmt *stmt)
|
|||
rel = heap_openr(DatabaseRelationName, RowExclusiveLock);
|
||||
ScanKeyEntryInitialize(&scankey, 0, Anum_pg_database_datname,
|
||||
F_NAMEEQ, NameGetDatum(stmt->dbname));
|
||||
scan = heap_beginscan(rel, 0, SnapshotNow, 1, &scankey);
|
||||
tuple = heap_getnext(scan, 0);
|
||||
scan = heap_beginscan(rel, SnapshotNow, 1, &scankey);
|
||||
tuple = heap_getnext(scan, ForwardScanDirection);
|
||||
if (!HeapTupleIsValid(tuple))
|
||||
elog(ERROR, "database \"%s\" does not exist", stmt->dbname);
|
||||
|
||||
|
@ -535,9 +535,9 @@ get_db_info(const char *name, Oid *dbIdP, int4 *ownerIdP,
|
|||
ScanKeyEntryInitialize(&scanKey, 0, Anum_pg_database_datname,
|
||||
F_NAMEEQ, NameGetDatum(name));
|
||||
|
||||
scan = heap_beginscan(relation, 0, SnapshotNow, 1, &scanKey);
|
||||
scan = heap_beginscan(relation, SnapshotNow, 1, &scanKey);
|
||||
|
||||
tuple = heap_getnext(scan, 0);
|
||||
tuple = heap_getnext(scan, ForwardScanDirection);
|
||||
|
||||
gottuple = HeapTupleIsValid(tuple);
|
||||
if (gottuple)
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.73 2002/05/12 20:10:02 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.74 2002/05/20 23:51:42 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -736,9 +736,9 @@ ReindexDatabase(const char *dbname, bool force, bool all)
|
|||
* Scan pg_class to build a list of the relations we need to reindex.
|
||||
*/
|
||||
relationRelation = heap_openr(RelationRelationName, AccessShareLock);
|
||||
scan = heap_beginscan(relationRelation, false, SnapshotNow, 0, NULL);
|
||||
scan = heap_beginscan(relationRelation, SnapshotNow, 0, NULL);
|
||||
relcnt = relalc = 0;
|
||||
while (HeapTupleIsValid(tuple = heap_getnext(scan, 0)))
|
||||
while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
|
||||
{
|
||||
if (!all)
|
||||
{
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/tablecmds.c,v 1.14 2002/05/17 22:35:12 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/tablecmds.c,v 1.15 2002/05/20 23:51:42 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -1314,32 +1314,38 @@ update_ri_trigger_args(Oid relid,
|
|||
bool update_relname)
|
||||
{
|
||||
Relation tgrel;
|
||||
Relation irel;
|
||||
ScanKeyData skey[1];
|
||||
IndexScanDesc idxtgscan;
|
||||
RetrieveIndexResult idxres;
|
||||
SysScanDesc trigscan;
|
||||
HeapTuple tuple;
|
||||
Datum values[Natts_pg_trigger];
|
||||
char nulls[Natts_pg_trigger];
|
||||
char replaces[Natts_pg_trigger];
|
||||
|
||||
tgrel = heap_openr(TriggerRelationName, RowExclusiveLock);
|
||||
if (fk_scan)
|
||||
irel = index_openr(TriggerConstrRelidIndex);
|
||||
else
|
||||
irel = index_openr(TriggerRelidNameIndex);
|
||||
|
||||
ScanKeyEntryInitialize(&skey[0], 0x0,
|
||||
1, /* column 1 of index in either case */
|
||||
F_OIDEQ,
|
||||
ObjectIdGetDatum(relid));
|
||||
idxtgscan = index_beginscan(irel, false, 1, skey);
|
||||
|
||||
while ((idxres = index_getnext(idxtgscan, ForwardScanDirection)) != NULL)
|
||||
{
|
||||
HeapTupleData tupledata;
|
||||
Buffer buffer;
|
||||
HeapTuple tuple;
|
||||
Form_pg_trigger pg_trigger;
|
||||
ScanKeyEntryInitialize(&skey[0], 0x0,
|
||||
Anum_pg_trigger_tgconstrrelid,
|
||||
F_OIDEQ,
|
||||
ObjectIdGetDatum(relid));
|
||||
trigscan = systable_beginscan(tgrel, TriggerConstrRelidIndex,
|
||||
true, SnapshotNow,
|
||||
1, skey);
|
||||
}
|
||||
else
|
||||
{
|
||||
ScanKeyEntryInitialize(&skey[0], 0x0,
|
||||
Anum_pg_trigger_tgrelid,
|
||||
F_OIDEQ,
|
||||
ObjectIdGetDatum(relid));
|
||||
trigscan = systable_beginscan(tgrel, TriggerRelidNameIndex,
|
||||
true, SnapshotNow,
|
||||
1, skey);
|
||||
}
|
||||
|
||||
while ((tuple = systable_getnext(trigscan)) != NULL)
|
||||
{
|
||||
Form_pg_trigger pg_trigger = (Form_pg_trigger) GETSTRUCT(tuple);
|
||||
bytea *val;
|
||||
bytea *newtgargs;
|
||||
bool isnull;
|
||||
|
@ -1352,18 +1358,10 @@ update_ri_trigger_args(Oid relid,
|
|||
const char *arga[RI_MAX_ARGUMENTS];
|
||||
const char *argp;
|
||||
|
||||
tupledata.t_self = idxres->heap_iptr;
|
||||
heap_fetch(tgrel, SnapshotNow, &tupledata, &buffer, idxtgscan);
|
||||
pfree(idxres);
|
||||
if (!tupledata.t_data)
|
||||
continue;
|
||||
tuple = &tupledata;
|
||||
pg_trigger = (Form_pg_trigger) GETSTRUCT(tuple);
|
||||
tg_type = ri_trigger_type(pg_trigger->tgfoid);
|
||||
if (tg_type == RI_TRIGGER_NONE)
|
||||
{
|
||||
/* Not an RI trigger, forget it */
|
||||
ReleaseBuffer(buffer);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -1381,7 +1379,6 @@ update_ri_trigger_args(Oid relid,
|
|||
tgnargs > RI_MAX_ARGUMENTS)
|
||||
{
|
||||
/* This probably shouldn't happen, but ignore busted triggers */
|
||||
ReleaseBuffer(buffer);
|
||||
continue;
|
||||
}
|
||||
argp = (const char *) VARDATA(val);
|
||||
|
@ -1429,7 +1426,6 @@ update_ri_trigger_args(Oid relid,
|
|||
if (!changed)
|
||||
{
|
||||
/* Don't need to update this tuple */
|
||||
ReleaseBuffer(buffer);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -1462,11 +1458,6 @@ update_ri_trigger_args(Oid relid,
|
|||
|
||||
tuple = heap_modifytuple(tuple, tgrel, values, nulls, replaces);
|
||||
|
||||
/*
|
||||
* Now we can release hold on original tuple.
|
||||
*/
|
||||
ReleaseBuffer(buffer);
|
||||
|
||||
/*
|
||||
* Update pg_trigger and its indexes
|
||||
*/
|
||||
|
@ -1485,8 +1476,7 @@ update_ri_trigger_args(Oid relid,
|
|||
heap_freetuple(tuple);
|
||||
}
|
||||
|
||||
index_endscan(idxtgscan);
|
||||
index_close(irel);
|
||||
systable_endscan(trigscan);
|
||||
|
||||
heap_close(tgrel, RowExclusiveLock);
|
||||
|
||||
|
@ -1979,9 +1969,9 @@ AlterTableAlterColumnSetNotNull(Oid myrelid,
|
|||
*/
|
||||
tupdesc = RelationGetDescr(rel);
|
||||
|
||||
scan = heap_beginscan(rel, false, SnapshotNow, 0, NULL);
|
||||
scan = heap_beginscan(rel, SnapshotNow, 0, NULL);
|
||||
|
||||
while (HeapTupleIsValid(tuple = heap_getnext(scan, 0)))
|
||||
while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
|
||||
{
|
||||
Datum d;
|
||||
bool isnull;
|
||||
|
@ -2177,9 +2167,9 @@ drop_default(Oid relid, int16 attnum)
|
|||
Anum_pg_attrdef_adnum, F_INT2EQ,
|
||||
Int16GetDatum(attnum));
|
||||
|
||||
scan = heap_beginscan(attrdef_rel, false, SnapshotNow, 2, scankeys);
|
||||
scan = heap_beginscan(attrdef_rel, SnapshotNow, 2, scankeys);
|
||||
|
||||
if (HeapTupleIsValid(tuple = heap_getnext(scan, 0)))
|
||||
if ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
|
||||
simple_heap_delete(attrdef_rel, &tuple->t_self);
|
||||
|
||||
heap_endscan(scan);
|
||||
|
@ -2501,9 +2491,9 @@ AlterTableAddConstraint(Oid myrelid,
|
|||
* Scan through the rows now, checking the
|
||||
* expression at each row.
|
||||
*/
|
||||
scan = heap_beginscan(rel, false, SnapshotNow, 0, NULL);
|
||||
scan = heap_beginscan(rel, SnapshotNow, 0, NULL);
|
||||
|
||||
while (HeapTupleIsValid(tuple = heap_getnext(scan, 0)))
|
||||
while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
|
||||
{
|
||||
ExecStoreTuple(tuple, slot, InvalidBuffer, false);
|
||||
if (!ExecQual(qual, econtext, true))
|
||||
|
@ -2621,9 +2611,9 @@ AlterTableAddConstraint(Oid myrelid,
|
|||
}
|
||||
trig.tgnargs = count - 1;
|
||||
|
||||
scan = heap_beginscan(rel, false, SnapshotNow, 0, NULL);
|
||||
scan = heap_beginscan(rel, SnapshotNow, 0, NULL);
|
||||
|
||||
while (HeapTupleIsValid(tuple = heap_getnext(scan, 0)))
|
||||
while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
|
||||
{
|
||||
/* Make a call to the check function */
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/user.c,v 1.101 2002/05/17 01:19:17 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/user.c,v 1.102 2002/05/20 23:51:42 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -140,8 +140,8 @@ write_group_file(Relation urel, Relation grel)
|
|||
elog(ERROR, "write_group_file: unable to write %s: %m", tempname);
|
||||
|
||||
/* read table */
|
||||
scan = heap_beginscan(grel, false, SnapshotSelf, 0, NULL);
|
||||
while (HeapTupleIsValid(tuple = heap_getnext(scan, 0)))
|
||||
scan = heap_beginscan(grel, SnapshotSelf, 0, NULL);
|
||||
while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
|
||||
{
|
||||
Datum datum, grolist_datum;
|
||||
bool isnull;
|
||||
|
@ -284,8 +284,8 @@ write_user_file(Relation urel)
|
|||
elog(ERROR, "write_password_file: unable to write %s: %m", tempname);
|
||||
|
||||
/* read table */
|
||||
scan = heap_beginscan(urel, false, SnapshotSelf, 0, NULL);
|
||||
while (HeapTupleIsValid(tuple = heap_getnext(scan, 0)))
|
||||
scan = heap_beginscan(urel, SnapshotSelf, 0, NULL);
|
||||
while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
|
||||
{
|
||||
Datum datum;
|
||||
bool isnull;
|
||||
|
@ -517,10 +517,10 @@ CreateUser(CreateUserStmt *stmt)
|
|||
pg_shadow_rel = heap_openr(ShadowRelationName, ExclusiveLock);
|
||||
pg_shadow_dsc = RelationGetDescr(pg_shadow_rel);
|
||||
|
||||
scan = heap_beginscan(pg_shadow_rel, false, SnapshotNow, 0, NULL);
|
||||
scan = heap_beginscan(pg_shadow_rel, SnapshotNow, 0, NULL);
|
||||
max_id = 99; /* start auto-assigned ids at 100 */
|
||||
while (!user_exists && !sysid_exists &&
|
||||
HeapTupleIsValid(tuple = heap_getnext(scan, 0)))
|
||||
(tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
|
||||
{
|
||||
Form_pg_shadow shadow_form = (Form_pg_shadow) GETSTRUCT(tuple);
|
||||
int32 this_sysid;
|
||||
|
@ -977,9 +977,9 @@ DropUser(DropUserStmt *stmt)
|
|||
Anum_pg_database_datdba, F_INT4EQ,
|
||||
Int32GetDatum(usesysid));
|
||||
|
||||
scan = heap_beginscan(pg_rel, false, SnapshotNow, 1, &scankey);
|
||||
scan = heap_beginscan(pg_rel, SnapshotNow, 1, &scankey);
|
||||
|
||||
if (HeapTupleIsValid(tmp_tuple = heap_getnext(scan, 0)))
|
||||
if ((tmp_tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
|
||||
{
|
||||
char *dbname;
|
||||
|
||||
|
@ -1012,8 +1012,8 @@ DropUser(DropUserStmt *stmt)
|
|||
*/
|
||||
pg_rel = heap_openr(GroupRelationName, ExclusiveLock);
|
||||
pg_dsc = RelationGetDescr(pg_rel);
|
||||
scan = heap_beginscan(pg_rel, false, SnapshotNow, 0, NULL);
|
||||
while (HeapTupleIsValid(tmp_tuple = heap_getnext(scan, 0)))
|
||||
scan = heap_beginscan(pg_rel, SnapshotNow, 0, NULL);
|
||||
while ((tmp_tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
|
||||
{
|
||||
AlterGroupStmt ags;
|
||||
|
||||
|
@ -1148,10 +1148,10 @@ CreateGroup(CreateGroupStmt *stmt)
|
|||
pg_group_rel = heap_openr(GroupRelationName, ExclusiveLock);
|
||||
pg_group_dsc = RelationGetDescr(pg_group_rel);
|
||||
|
||||
scan = heap_beginscan(pg_group_rel, false, SnapshotNow, 0, NULL);
|
||||
scan = heap_beginscan(pg_group_rel, SnapshotNow, 0, NULL);
|
||||
max_id = 99; /* start auto-assigned ids at 100 */
|
||||
while (!group_exists && !sysid_exists &&
|
||||
HeapTupleIsValid(tuple = heap_getnext(scan, false)))
|
||||
(tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
|
||||
{
|
||||
Form_pg_group group_form = (Form_pg_group) GETSTRUCT(tuple);
|
||||
int32 this_sysid;
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.224 2002/04/15 23:39:42 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.225 2002/05/20 23:51:42 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -350,9 +350,9 @@ getrels(const RangeVar *vacrel, const char *stmttype)
|
|||
|
||||
pgclass = heap_openr(RelationRelationName, AccessShareLock);
|
||||
|
||||
scan = heap_beginscan(pgclass, false, SnapshotNow, 1, &key);
|
||||
scan = heap_beginscan(pgclass, SnapshotNow, 1, &key);
|
||||
|
||||
while (HeapTupleIsValid(tuple = heap_getnext(scan, 0)))
|
||||
while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
|
||||
{
|
||||
/* Make a relation list entry for this guy */
|
||||
oldcontext = MemoryContextSwitchTo(vac_context);
|
||||
|
@ -521,9 +521,9 @@ vac_update_dbstats(Oid dbid,
|
|||
ObjectIdAttributeNumber, F_OIDEQ,
|
||||
ObjectIdGetDatum(dbid));
|
||||
|
||||
scan = heap_beginscan(relation, 0, SnapshotNow, 1, entry);
|
||||
scan = heap_beginscan(relation, SnapshotNow, 1, entry);
|
||||
|
||||
tuple = heap_getnext(scan, 0);
|
||||
tuple = heap_getnext(scan, ForwardScanDirection);
|
||||
|
||||
if (!HeapTupleIsValid(tuple))
|
||||
elog(ERROR, "database %u does not exist", dbid);
|
||||
|
@ -573,9 +573,9 @@ vac_truncate_clog(TransactionId vacuumXID, TransactionId frozenXID)
|
|||
|
||||
relation = heap_openr(DatabaseRelationName, AccessShareLock);
|
||||
|
||||
scan = heap_beginscan(relation, 0, SnapshotNow, 0, NULL);
|
||||
scan = heap_beginscan(relation, SnapshotNow, 0, NULL);
|
||||
|
||||
while (HeapTupleIsValid(tuple = heap_getnext(scan, 0)))
|
||||
while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
|
||||
{
|
||||
Form_pg_database dbform = (Form_pg_database) GETSTRUCT(tuple);
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/nodeIndexscan.c,v 1.67 2002/02/19 20:11:13 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/nodeIndexscan.c,v 1.68 2002/05/20 23:51:42 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -72,14 +72,10 @@ IndexNext(IndexScan *node)
|
|||
IndexScanState *indexstate;
|
||||
ExprContext *econtext;
|
||||
ScanDirection direction;
|
||||
Snapshot snapshot;
|
||||
IndexScanDescPtr scanDescs;
|
||||
IndexScanDesc scandesc;
|
||||
Relation heapRelation;
|
||||
RetrieveIndexResult result;
|
||||
HeapTuple tuple;
|
||||
TupleTableSlot *slot;
|
||||
Buffer buffer = InvalidBuffer;
|
||||
int numIndices;
|
||||
bool bBackward;
|
||||
int indexNumber;
|
||||
|
@ -96,11 +92,9 @@ IndexNext(IndexScan *node)
|
|||
else if (ScanDirectionIsBackward(direction))
|
||||
direction = ForwardScanDirection;
|
||||
}
|
||||
snapshot = estate->es_snapshot;
|
||||
scanstate = node->scan.scanstate;
|
||||
indexstate = node->indxstate;
|
||||
scanDescs = indexstate->iss_ScanDescs;
|
||||
heapRelation = scanstate->css_currentRelation;
|
||||
numIndices = indexstate->iss_NumIndices;
|
||||
econtext = scanstate->cstate.cs_ExprContext;
|
||||
slot = scanstate->css_ScanTupleSlot;
|
||||
|
@ -142,8 +136,6 @@ IndexNext(IndexScan *node)
|
|||
return slot;
|
||||
}
|
||||
|
||||
tuple = &(indexstate->iss_htup);
|
||||
|
||||
/*
|
||||
* ok, now that we have what we need, fetch an index tuple. if
|
||||
* scanning this index succeeded then return the appropriate heap
|
||||
|
@ -170,48 +162,37 @@ IndexNext(IndexScan *node)
|
|||
while (indexNumber < numIndices)
|
||||
{
|
||||
scandesc = scanDescs[indexstate->iss_IndexPtr];
|
||||
while ((result = index_getnext(scandesc, direction)) != NULL)
|
||||
while ((tuple = index_getnext(scandesc, direction)) != NULL)
|
||||
{
|
||||
tuple->t_self = result->heap_iptr;
|
||||
heap_fetch(heapRelation, snapshot, tuple, &buffer, scandesc);
|
||||
pfree(result);
|
||||
/*
|
||||
* store the scanned tuple in the scan tuple slot of the
|
||||
* scan state. Note: we pass 'false' because tuples
|
||||
* returned by amgetnext are pointers onto disk pages and
|
||||
* must not be pfree()'d.
|
||||
*/
|
||||
ExecStoreTuple(tuple, /* tuple to store */
|
||||
slot, /* slot to store in */
|
||||
scandesc->xs_cbuf, /* buffer containing tuple */
|
||||
false); /* don't pfree */
|
||||
|
||||
if (tuple->t_data != NULL)
|
||||
/*
|
||||
* We must check to see if the current tuple was already
|
||||
* matched by an earlier index, so we don't double-report
|
||||
* it. We do this by passing the tuple through ExecQual
|
||||
* and checking for failure with all previous
|
||||
* qualifications.
|
||||
*/
|
||||
if (indexstate->iss_IndexPtr > 0)
|
||||
{
|
||||
bool prev_matches = false;
|
||||
int prev_index;
|
||||
List *qual;
|
||||
|
||||
/*
|
||||
* store the scanned tuple in the scan tuple slot of the
|
||||
* scan state. Eventually we will only do this and not
|
||||
* return a tuple. Note: we pass 'false' because tuples
|
||||
* returned by amgetnext are pointers onto disk pages and
|
||||
* must not be pfree()'d.
|
||||
*/
|
||||
ExecStoreTuple(tuple, /* tuple to store */
|
||||
slot, /* slot to store in */
|
||||
buffer, /* buffer associated with tuple */
|
||||
false); /* don't pfree */
|
||||
|
||||
/*
|
||||
* At this point we have an extra pin on the buffer,
|
||||
* because ExecStoreTuple incremented the pin count. Drop
|
||||
* our local pin.
|
||||
*/
|
||||
ReleaseBuffer(buffer);
|
||||
|
||||
/*
|
||||
* We must check to see if the current tuple was already
|
||||
* matched by an earlier index, so we don't double-report
|
||||
* it. We do this by passing the tuple through ExecQual
|
||||
* and checking for failure with all previous
|
||||
* qualifications.
|
||||
*/
|
||||
econtext->ecxt_scantuple = slot;
|
||||
ResetExprContext(econtext);
|
||||
qual = node->indxqualorig;
|
||||
for (prev_index = 0; prev_index < indexstate->iss_IndexPtr;
|
||||
for (prev_index = 0;
|
||||
prev_index < indexstate->iss_IndexPtr;
|
||||
prev_index++)
|
||||
{
|
||||
if (ExecQual((List *) lfirst(qual), econtext, false))
|
||||
|
@ -221,12 +202,17 @@ IndexNext(IndexScan *node)
|
|||
}
|
||||
qual = lnext(qual);
|
||||
}
|
||||
if (!prev_matches)
|
||||
return slot; /* OK to return tuple */
|
||||
/* Duplicate tuple, so drop it and loop back for another */
|
||||
ExecClearTuple(slot);
|
||||
if (prev_matches)
|
||||
{
|
||||
/* Duplicate, so drop it and loop back for another */
|
||||
ExecClearTuple(slot);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return slot; /* OK to return tuple */
|
||||
}
|
||||
|
||||
if (indexNumber < numIndices)
|
||||
{
|
||||
indexNumber++;
|
||||
|
@ -300,7 +286,6 @@ ExecIndexReScan(IndexScan *node, ExprContext *exprCtxt, Plan *parent)
|
|||
EState *estate;
|
||||
IndexScanState *indexstate;
|
||||
ExprContext *econtext;
|
||||
ScanDirection direction;
|
||||
int numIndices;
|
||||
IndexScanDescPtr scanDescs;
|
||||
ScanKey *scanKeys;
|
||||
|
@ -313,7 +298,6 @@ ExecIndexReScan(IndexScan *node, ExprContext *exprCtxt, Plan *parent)
|
|||
indexstate = node->indxstate;
|
||||
econtext = indexstate->iss_RuntimeContext; /* context for runtime
|
||||
* keys */
|
||||
direction = estate->es_direction;
|
||||
numIndices = indexstate->iss_NumIndices;
|
||||
scanDescs = indexstate->iss_ScanDescs;
|
||||
scanKeys = indexstate->iss_ScanKeys;
|
||||
|
@ -431,7 +415,7 @@ ExecIndexReScan(IndexScan *node, ExprContext *exprCtxt, Plan *parent)
|
|||
IndexScanDesc scan = scanDescs[i];
|
||||
ScanKey skey = scanKeys[i];
|
||||
|
||||
index_rescan(scan, direction, skey);
|
||||
index_rescan(scan, skey);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -622,16 +606,14 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent)
|
|||
int indexPtr;
|
||||
ScanKey *scanKeys;
|
||||
int *numScanKeys;
|
||||
RelationPtr relationDescs;
|
||||
RelationPtr indexDescs;
|
||||
IndexScanDescPtr scanDescs;
|
||||
int **runtimeKeyInfo;
|
||||
bool have_runtime_keys;
|
||||
List *rangeTable;
|
||||
RangeTblEntry *rtentry;
|
||||
Index relid;
|
||||
Oid reloid;
|
||||
Relation currentRelation;
|
||||
ScanDirection direction;
|
||||
|
||||
/*
|
||||
* assign execution state to node
|
||||
|
@ -701,7 +683,7 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent)
|
|||
*/
|
||||
numScanKeys = (int *) palloc(numIndices * sizeof(int));
|
||||
scanKeys = (ScanKey *) palloc(numIndices * sizeof(ScanKey));
|
||||
relationDescs = (RelationPtr) palloc(numIndices * sizeof(Relation));
|
||||
indexDescs = (RelationPtr) palloc(numIndices * sizeof(Relation));
|
||||
scanDescs = (IndexScanDescPtr) palloc(numIndices * sizeof(IndexScanDesc));
|
||||
|
||||
/*
|
||||
|
@ -1010,18 +992,11 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent)
|
|||
pfree(runtimeKeyInfo);
|
||||
}
|
||||
|
||||
/*
|
||||
* get the range table and direction information from the execution
|
||||
* state (these are needed to open the relations).
|
||||
*/
|
||||
rangeTable = estate->es_range_table;
|
||||
direction = estate->es_direction;
|
||||
|
||||
/*
|
||||
* open the base relation and acquire AccessShareLock on it.
|
||||
*/
|
||||
relid = node->scan.scanrelid;
|
||||
rtentry = rt_fetch(relid, rangeTable);
|
||||
rtentry = rt_fetch(relid, estate->es_range_table);
|
||||
reloid = rtentry->relid;
|
||||
|
||||
currentRelation = heap_open(reloid, AccessShareLock);
|
||||
|
@ -1049,24 +1024,16 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent)
|
|||
{
|
||||
Oid indexOid = (Oid) lfirsti(listscan);
|
||||
|
||||
if (indexOid != 0)
|
||||
{
|
||||
relationDescs[i] = index_open(indexOid);
|
||||
|
||||
/*
|
||||
* Note: index_beginscan()'s second arg is a boolean indicating
|
||||
* that the scan should be done in reverse. That is, if you pass
|
||||
* it true, then the scan is backward.
|
||||
*/
|
||||
scanDescs[i] = index_beginscan(relationDescs[i],
|
||||
false, /* see above comment */
|
||||
numScanKeys[i],
|
||||
scanKeys[i]);
|
||||
}
|
||||
indexDescs[i] = index_open(indexOid);
|
||||
scanDescs[i] = index_beginscan(currentRelation,
|
||||
indexDescs[i],
|
||||
estate->es_snapshot,
|
||||
numScanKeys[i],
|
||||
scanKeys[i]);
|
||||
listscan = lnext(listscan);
|
||||
}
|
||||
|
||||
indexstate->iss_RelationDescs = relationDescs;
|
||||
indexstate->iss_RelationDescs = indexDescs;
|
||||
indexstate->iss_ScanDescs = scanDescs;
|
||||
|
||||
/*
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/nodeSeqscan.c,v 1.34 2002/02/19 20:11:14 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/nodeSeqscan.c,v 1.35 2002/05/20 23:51:42 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -93,7 +93,7 @@ SeqNext(SeqScan *node)
|
|||
/*
|
||||
* get the next tuple from the access methods
|
||||
*/
|
||||
tuple = heap_getnext(scandesc, ScanDirectionIsBackward(direction));
|
||||
tuple = heap_getnext(scandesc, direction);
|
||||
|
||||
/*
|
||||
* save the tuple and the buffer returned to us by the access methods
|
||||
|
@ -148,7 +148,6 @@ InitScanRelation(SeqScan *node, EState *estate,
|
|||
List *rangeTable;
|
||||
RangeTblEntry *rtentry;
|
||||
Oid reloid;
|
||||
ScanDirection direction;
|
||||
Relation currentRelation;
|
||||
HeapScanDesc currentScanDesc;
|
||||
|
||||
|
@ -162,12 +161,10 @@ InitScanRelation(SeqScan *node, EState *estate,
|
|||
rangeTable = estate->es_range_table;
|
||||
rtentry = rt_fetch(relid, rangeTable);
|
||||
reloid = rtentry->relid;
|
||||
direction = estate->es_direction;
|
||||
|
||||
currentRelation = heap_open(reloid, AccessShareLock);
|
||||
|
||||
currentScanDesc = heap_beginscan(currentRelation,
|
||||
ScanDirectionIsBackward(direction),
|
||||
estate->es_snapshot,
|
||||
0,
|
||||
NULL);
|
||||
|
@ -316,7 +313,6 @@ ExecSeqReScan(SeqScan *node, ExprContext *exprCtxt, Plan *parent)
|
|||
CommonScanState *scanstate;
|
||||
EState *estate;
|
||||
HeapScanDesc scan;
|
||||
ScanDirection direction;
|
||||
|
||||
scanstate = node->scanstate;
|
||||
estate = node->plan.state;
|
||||
|
@ -330,10 +326,8 @@ ExecSeqReScan(SeqScan *node, ExprContext *exprCtxt, Plan *parent)
|
|||
}
|
||||
|
||||
scan = scanstate->css_currentScanDesc;
|
||||
direction = estate->es_direction;
|
||||
|
||||
heap_rescan(scan, /* scan desc */
|
||||
ScanDirectionIsBackward(direction), /* backward flag */
|
||||
NULL); /* new scan keys */
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/indxpath.c,v 1.117 2002/05/12 23:43:02 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/indxpath.c,v 1.118 2002/05/20 23:51:42 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -1233,9 +1233,9 @@ pred_test_simple_clause(Expr *predicate, Node *clause)
|
|||
ObjectIdGetDatum(pred_op));
|
||||
|
||||
relation = heap_openr(AccessMethodOperatorRelationName, AccessShareLock);
|
||||
scan = heap_beginscan(relation, false, SnapshotNow, 1, entry);
|
||||
scan = heap_beginscan(relation, SnapshotNow, 1, entry);
|
||||
|
||||
while (HeapTupleIsValid(tuple = heap_getnext(scan, 0)))
|
||||
while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
|
||||
{
|
||||
aform = (Form_pg_amop) GETSTRUCT(tuple);
|
||||
if (opclass_is_btree(aform->amopclaid))
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/plancat.c,v 1.71 2002/04/12 20:38:26 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/plancat.c,v 1.72 2002/05/20 23:51:42 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -290,8 +290,8 @@ find_inheritance_children(Oid inhparent)
|
|||
(RegProcedure) F_OIDEQ,
|
||||
ObjectIdGetDatum(inhparent));
|
||||
relation = heap_openr(InheritsRelationName, AccessShareLock);
|
||||
scan = heap_beginscan(relation, 0, SnapshotNow, 1, key);
|
||||
while (HeapTupleIsValid(inheritsTuple = heap_getnext(scan, 0)))
|
||||
scan = heap_beginscan(relation, SnapshotNow, 1, key);
|
||||
while ((inheritsTuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
|
||||
{
|
||||
inhrelid = ((Form_pg_inherits) GETSTRUCT(inheritsTuple))->inhrelid;
|
||||
list = lappendi(list, inhrelid);
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.130 2002/05/17 22:35:13 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.131 2002/05/20 23:51:42 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -959,9 +959,9 @@ find_inheritors(Oid relid, Oid **supervec)
|
|||
F_OIDEQ,
|
||||
ObjectIdGetDatum(relid));
|
||||
|
||||
inhscan = heap_beginscan(inhrel, 0, SnapshotNow, 1, &skey);
|
||||
inhscan = heap_beginscan(inhrel, SnapshotNow, 1, &skey);
|
||||
|
||||
while (HeapTupleIsValid(inhtup = heap_getnext(inhscan, 0)))
|
||||
while ((inhtup = heap_getnext(inhscan, ForwardScanDirection)) != NULL)
|
||||
{
|
||||
Form_pg_inherits inh = (Form_pg_inherits) GETSTRUCT(inhtup);
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
*
|
||||
* Copyright (c) 2001, PostgreSQL Global Development Group
|
||||
*
|
||||
* $Header: /cvsroot/pgsql/src/backend/postmaster/pgstat.c,v 1.20 2002/05/05 00:03:28 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/postmaster/pgstat.c,v 1.21 2002/05/20 23:51:43 tgl Exp $
|
||||
* ----------
|
||||
*/
|
||||
#include "postgres.h"
|
||||
|
@ -619,8 +619,8 @@ pgstat_vacuum_tabstat(void)
|
|||
dbidlist = (Oid *) palloc(sizeof(Oid) * dbidalloc);
|
||||
|
||||
dbrel = heap_openr(DatabaseRelationName, AccessShareLock);
|
||||
dbscan = heap_beginscan(dbrel, 0, SnapshotNow, 0, NULL);
|
||||
while (HeapTupleIsValid(dbtup = heap_getnext(dbscan, FALSE)))
|
||||
dbscan = heap_beginscan(dbrel, SnapshotNow, 0, NULL);
|
||||
while ((dbtup = heap_getnext(dbscan, ForwardScanDirection)) != NULL)
|
||||
{
|
||||
if (dbidused >= dbidalloc)
|
||||
{
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteDefine.c,v 1.70 2002/05/12 20:10:04 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteDefine.c,v 1.71 2002/05/20 23:51:43 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -292,18 +292,11 @@ DefineQueryRewrite(RuleStmt *stmt)
|
|||
if (event_relation->rd_rel->relkind != RELKIND_VIEW)
|
||||
{
|
||||
HeapScanDesc scanDesc;
|
||||
HeapTuple tuple;
|
||||
|
||||
scanDesc = heap_beginscan(event_relation, 0, SnapshotNow, 0, NULL);
|
||||
tuple = heap_getnext(scanDesc, 0);
|
||||
if (HeapTupleIsValid(tuple))
|
||||
scanDesc = heap_beginscan(event_relation, SnapshotNow, 0, NULL);
|
||||
if (heap_getnext(scanDesc, ForwardScanDirection) != NULL)
|
||||
elog(ERROR, "Relation \"%s\" is not empty. Cannot convert it to view",
|
||||
event_obj->relname);
|
||||
|
||||
/*
|
||||
* don't need heap_freetuple because we never got a valid
|
||||
* tuple
|
||||
*/
|
||||
heap_endscan(scanDesc);
|
||||
|
||||
RelisBecomingView = true;
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/storage/large_object/inv_api.c,v 1.90 2001/10/25 05:49:42 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/storage/large_object/inv_api.c,v 1.91 2002/05/20 23:51:43 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -198,12 +198,7 @@ inv_getsize(LargeObjectDesc *obj_desc)
|
|||
uint32 lastbyte = 0;
|
||||
ScanKeyData skey[1];
|
||||
IndexScanDesc sd;
|
||||
RetrieveIndexResult indexRes;
|
||||
HeapTupleData tuple;
|
||||
Buffer buffer;
|
||||
Form_pg_largeobject data;
|
||||
bytea *datafield;
|
||||
bool pfreeit;
|
||||
HeapTuple tuple;
|
||||
|
||||
Assert(PointerIsValid(obj_desc));
|
||||
|
||||
|
@ -213,10 +208,8 @@ inv_getsize(LargeObjectDesc *obj_desc)
|
|||
(RegProcedure) F_OIDEQ,
|
||||
ObjectIdGetDatum(obj_desc->id));
|
||||
|
||||
sd = index_beginscan(obj_desc->index_r, true, 1, skey);
|
||||
|
||||
tuple.t_datamcxt = CurrentMemoryContext;
|
||||
tuple.t_data = NULL;
|
||||
sd = index_beginscan(obj_desc->heap_r, obj_desc->index_r,
|
||||
SnapshotNow, 1, skey);
|
||||
|
||||
/*
|
||||
* Because the pg_largeobject index is on both loid and pageno, but we
|
||||
|
@ -224,15 +217,14 @@ inv_getsize(LargeObjectDesc *obj_desc)
|
|||
* large object in reverse pageno order. So, it's sufficient to
|
||||
* examine the first valid tuple (== last valid page).
|
||||
*/
|
||||
while ((indexRes = index_getnext(sd, BackwardScanDirection)))
|
||||
while ((tuple = index_getnext(sd, BackwardScanDirection)) != NULL)
|
||||
{
|
||||
tuple.t_self = indexRes->heap_iptr;
|
||||
heap_fetch(obj_desc->heap_r, SnapshotNow, &tuple, &buffer, sd);
|
||||
pfree(indexRes);
|
||||
if (tuple.t_data == NULL)
|
||||
continue;
|
||||
Form_pg_largeobject data;
|
||||
bytea *datafield;
|
||||
bool pfreeit;
|
||||
|
||||
found = true;
|
||||
data = (Form_pg_largeobject) GETSTRUCT(&tuple);
|
||||
data = (Form_pg_largeobject) GETSTRUCT(tuple);
|
||||
datafield = &(data->data);
|
||||
pfreeit = false;
|
||||
if (VARATT_IS_EXTENDED(datafield))
|
||||
|
@ -244,7 +236,6 @@ inv_getsize(LargeObjectDesc *obj_desc)
|
|||
lastbyte = data->pageno * LOBLKSIZE + getbytealen(datafield);
|
||||
if (pfreeit)
|
||||
pfree(datafield);
|
||||
ReleaseBuffer(buffer);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -306,12 +297,7 @@ inv_read(LargeObjectDesc *obj_desc, char *buf, int nbytes)
|
|||
uint32 pageoff;
|
||||
ScanKeyData skey[2];
|
||||
IndexScanDesc sd;
|
||||
RetrieveIndexResult indexRes;
|
||||
HeapTupleData tuple;
|
||||
Buffer buffer;
|
||||
Form_pg_largeobject data;
|
||||
bytea *datafield;
|
||||
bool pfreeit;
|
||||
HeapTuple tuple;
|
||||
|
||||
Assert(PointerIsValid(obj_desc));
|
||||
Assert(buf != NULL);
|
||||
|
@ -331,21 +317,16 @@ inv_read(LargeObjectDesc *obj_desc, char *buf, int nbytes)
|
|||
(RegProcedure) F_INT4GE,
|
||||
Int32GetDatum(pageno));
|
||||
|
||||
sd = index_beginscan(obj_desc->index_r, false, 2, skey);
|
||||
sd = index_beginscan(obj_desc->heap_r, obj_desc->index_r,
|
||||
SnapshotNow, 2, skey);
|
||||
|
||||
tuple.t_datamcxt = CurrentMemoryContext;
|
||||
tuple.t_data = NULL;
|
||||
|
||||
while ((indexRes = index_getnext(sd, ForwardScanDirection)))
|
||||
while ((tuple = index_getnext(sd, ForwardScanDirection)) != NULL)
|
||||
{
|
||||
tuple.t_self = indexRes->heap_iptr;
|
||||
heap_fetch(obj_desc->heap_r, SnapshotNow, &tuple, &buffer, sd);
|
||||
pfree(indexRes);
|
||||
Form_pg_largeobject data;
|
||||
bytea *datafield;
|
||||
bool pfreeit;
|
||||
|
||||
if (tuple.t_data == NULL)
|
||||
continue;
|
||||
|
||||
data = (Form_pg_largeobject) GETSTRUCT(&tuple);
|
||||
data = (Form_pg_largeobject) GETSTRUCT(tuple);
|
||||
|
||||
/*
|
||||
* We assume the indexscan will deliver pages in order. However,
|
||||
|
@ -389,7 +370,6 @@ inv_read(LargeObjectDesc *obj_desc, char *buf, int nbytes)
|
|||
pfree(datafield);
|
||||
}
|
||||
|
||||
ReleaseBuffer(buffer);
|
||||
if (nread >= nbytes)
|
||||
break;
|
||||
}
|
||||
|
@ -409,9 +389,7 @@ inv_write(LargeObjectDesc *obj_desc, char *buf, int nbytes)
|
|||
int32 pageno = (int32) (obj_desc->offset / LOBLKSIZE);
|
||||
ScanKeyData skey[2];
|
||||
IndexScanDesc sd;
|
||||
RetrieveIndexResult indexRes;
|
||||
HeapTupleData oldtuple;
|
||||
Buffer buffer;
|
||||
HeapTuple oldtuple;
|
||||
Form_pg_largeobject olddata;
|
||||
bool neednextpage;
|
||||
bytea *datafield;
|
||||
|
@ -453,12 +431,11 @@ inv_write(LargeObjectDesc *obj_desc, char *buf, int nbytes)
|
|||
(RegProcedure) F_INT4GE,
|
||||
Int32GetDatum(pageno));
|
||||
|
||||
sd = index_beginscan(obj_desc->index_r, false, 2, skey);
|
||||
sd = index_beginscan(obj_desc->heap_r, obj_desc->index_r,
|
||||
SnapshotNow, 2, skey);
|
||||
|
||||
oldtuple.t_datamcxt = CurrentMemoryContext;
|
||||
oldtuple.t_data = NULL;
|
||||
oldtuple = NULL;
|
||||
olddata = NULL;
|
||||
buffer = InvalidBuffer;
|
||||
neednextpage = true;
|
||||
|
||||
while (nwritten < nbytes)
|
||||
|
@ -470,17 +447,10 @@ inv_write(LargeObjectDesc *obj_desc, char *buf, int nbytes)
|
|||
*/
|
||||
if (neednextpage)
|
||||
{
|
||||
while ((indexRes = index_getnext(sd, ForwardScanDirection)))
|
||||
if ((oldtuple = index_getnext(sd, ForwardScanDirection)) != NULL)
|
||||
{
|
||||
oldtuple.t_self = indexRes->heap_iptr;
|
||||
heap_fetch(obj_desc->heap_r, SnapshotNow, &oldtuple, &buffer, sd);
|
||||
pfree(indexRes);
|
||||
if (oldtuple.t_data != NULL)
|
||||
{
|
||||
olddata = (Form_pg_largeobject) GETSTRUCT(&oldtuple);
|
||||
Assert(olddata->pageno >= pageno);
|
||||
break;
|
||||
}
|
||||
olddata = (Form_pg_largeobject) GETSTRUCT(oldtuple);
|
||||
Assert(olddata->pageno >= pageno);
|
||||
}
|
||||
neednextpage = false;
|
||||
}
|
||||
|
@ -538,7 +508,7 @@ inv_write(LargeObjectDesc *obj_desc, char *buf, int nbytes)
|
|||
memset(replace, ' ', sizeof(replace));
|
||||
values[Anum_pg_largeobject_data - 1] = PointerGetDatum(&workbuf);
|
||||
replace[Anum_pg_largeobject_data - 1] = 'r';
|
||||
newtup = heap_modifytuple(&oldtuple, obj_desc->heap_r,
|
||||
newtup = heap_modifytuple(oldtuple, obj_desc->heap_r,
|
||||
values, nulls, replace);
|
||||
simple_heap_update(obj_desc->heap_r, &newtup->t_self, newtup);
|
||||
if (write_indices)
|
||||
|
@ -549,9 +519,7 @@ inv_write(LargeObjectDesc *obj_desc, char *buf, int nbytes)
|
|||
/*
|
||||
* We're done with this old page.
|
||||
*/
|
||||
ReleaseBuffer(buffer);
|
||||
oldtuple.t_datamcxt = CurrentMemoryContext;
|
||||
oldtuple.t_data = NULL;
|
||||
oldtuple = NULL;
|
||||
olddata = NULL;
|
||||
neednextpage = true;
|
||||
}
|
||||
|
@ -596,9 +564,6 @@ inv_write(LargeObjectDesc *obj_desc, char *buf, int nbytes)
|
|||
pageno++;
|
||||
}
|
||||
|
||||
if (olddata != NULL)
|
||||
ReleaseBuffer(buffer);
|
||||
|
||||
index_endscan(sd);
|
||||
|
||||
if (write_indices)
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/not_in.c,v 1.28 2002/03/30 01:02:41 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/not_in.c,v 1.29 2002/05/20 23:51:43 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -75,13 +75,13 @@ int4notin(PG_FUNCTION_ARGS)
|
|||
elog(ERROR, "int4notin: unknown attribute %s for relation %s",
|
||||
attribute, RelationGetRelationName(relation_to_scan));
|
||||
|
||||
scan_descriptor = heap_beginscan(relation_to_scan, false, SnapshotNow,
|
||||
scan_descriptor = heap_beginscan(relation_to_scan, SnapshotNow,
|
||||
0, (ScanKey) NULL);
|
||||
|
||||
retval = true;
|
||||
|
||||
/* do a scan of the relation, and do the check */
|
||||
while (HeapTupleIsValid(current_tuple = heap_getnext(scan_descriptor, 0)))
|
||||
while ((current_tuple = heap_getnext(scan_descriptor, ForwardScanDirection)) != NULL)
|
||||
{
|
||||
value = heap_getattr(current_tuple,
|
||||
(AttrNumber) attrid,
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/init/postinit.c,v 1.105 2002/05/17 01:19:18 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/init/postinit.c,v 1.106 2002/05/20 23:51:43 tgl Exp $
|
||||
*
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
|
@ -95,9 +95,9 @@ ReverifyMyDatabase(const char *name)
|
|||
ScanKeyEntryInitialize(&key, 0, Anum_pg_database_datname,
|
||||
F_NAMEEQ, NameGetDatum(name));
|
||||
|
||||
pgdbscan = heap_beginscan(pgdbrel, 0, SnapshotNow, 1, &key);
|
||||
pgdbscan = heap_beginscan(pgdbrel, SnapshotNow, 1, &key);
|
||||
|
||||
tup = heap_getnext(pgdbscan, 0);
|
||||
tup = heap_getnext(pgdbscan, ForwardScanDirection);
|
||||
if (!HeapTupleIsValid(tup) ||
|
||||
tup->t_data->t_oid != MyDatabaseId)
|
||||
{
|
||||
|
@ -456,8 +456,8 @@ ThereIsAtLeastOneUser(void)
|
|||
pg_shadow_rel = heap_openr(ShadowRelationName, AccessExclusiveLock);
|
||||
pg_shadow_dsc = RelationGetDescr(pg_shadow_rel);
|
||||
|
||||
scan = heap_beginscan(pg_shadow_rel, false, SnapshotNow, 0, 0);
|
||||
result = HeapTupleIsValid(heap_getnext(scan, 0));
|
||||
scan = heap_beginscan(pg_shadow_rel, SnapshotNow, 0, NULL);
|
||||
result = (heap_getnext(scan, ForwardScanDirection) != NULL);
|
||||
|
||||
heap_endscan(scan);
|
||||
heap_close(pg_shadow_rel, AccessExclusiveLock);
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/misc/superuser.c,v 1.21 2002/04/11 05:32:03 petere Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/misc/superuser.c,v 1.22 2002/05/20 23:51:43 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -80,8 +80,8 @@ is_dbadmin(Oid dbid)
|
|||
ScanKeyEntryInitialize(&entry[0], 0x0,
|
||||
ObjectIdAttributeNumber, F_OIDEQ,
|
||||
ObjectIdGetDatum(dbid));
|
||||
scan = heap_beginscan(pg_database, 0, SnapshotNow, 1, entry);
|
||||
dbtuple = heap_getnext(scan, 0);
|
||||
scan = heap_beginscan(pg_database, SnapshotNow, 1, entry);
|
||||
dbtuple = heap_getnext(scan, ForwardScanDirection);
|
||||
if (!HeapTupleIsValid(dbtuple))
|
||||
elog(ERROR, "database %u does not exist", dbid);
|
||||
dba = ((Form_pg_database) GETSTRUCT(dbtuple))->datdba;
|
||||
|
|
|
@ -78,7 +78,7 @@
|
|||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/sort/tuplesort.c,v 1.22 2002/01/06 00:37:44 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/sort/tuplesort.c,v 1.23 2002/05/20 23:51:43 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -2076,9 +2076,9 @@ SelectSortFunction(Oid sortOperator,
|
|||
ObjectIdGetDatum(sortOperator));
|
||||
|
||||
relation = heap_openr(AccessMethodOperatorRelationName, AccessShareLock);
|
||||
scan = heap_beginscan(relation, false, SnapshotNow, 1, skey);
|
||||
scan = heap_beginscan(relation, SnapshotNow, 1, skey);
|
||||
|
||||
while (HeapTupleIsValid(tuple = heap_getnext(scan, 0)))
|
||||
while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
|
||||
{
|
||||
Form_pg_amop aform = (Form_pg_amop) GETSTRUCT(tuple);
|
||||
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* genam.h
|
||||
* POSTGRES general access method definitions.
|
||||
* POSTGRES generalized index access method definitions.
|
||||
*
|
||||
*
|
||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: genam.h,v 1.33 2002/03/26 19:16:17 tgl Exp $
|
||||
* $Id: genam.h,v 1.34 2002/05/20 23:51:43 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -36,12 +36,9 @@ typedef bool (*IndexBulkDeleteCallback) (ItemPointer itemptr, void *state);
|
|||
typedef struct SysScanDescData
|
||||
{
|
||||
Relation heap_rel; /* catalog being scanned */
|
||||
Snapshot snapshot; /* time qual (normally SnapshotNow) */
|
||||
Relation irel; /* NULL if doing heap scan */
|
||||
HeapScanDesc scan; /* only valid in heap-scan case */
|
||||
IndexScanDesc iscan; /* only valid in index-scan case */
|
||||
HeapTupleData tuple; /* workspace for indexscan */
|
||||
Buffer buffer; /* working state for indexscan */
|
||||
} SysScanDescData;
|
||||
|
||||
typedef SysScanDescData *SysScanDesc;
|
||||
|
@ -54,22 +51,27 @@ extern Relation index_open(Oid relationId);
|
|||
extern Relation index_openrv(const RangeVar *relation);
|
||||
extern Relation index_openr(const char *sysRelationName);
|
||||
extern void index_close(Relation relation);
|
||||
extern InsertIndexResult index_insert(Relation relation,
|
||||
Datum *datum, char *nulls,
|
||||
extern InsertIndexResult index_insert(Relation indexRelation,
|
||||
Datum *datums, char *nulls,
|
||||
ItemPointer heap_t_ctid,
|
||||
Relation heapRel);
|
||||
extern IndexScanDesc index_beginscan(Relation relation, bool scanFromEnd,
|
||||
uint16 numberOfKeys, ScanKey key);
|
||||
extern void index_rescan(IndexScanDesc scan, bool scanFromEnd, ScanKey key);
|
||||
Relation heapRelation);
|
||||
|
||||
extern IndexScanDesc index_beginscan(Relation heapRelation,
|
||||
Relation indexRelation,
|
||||
Snapshot snapshot,
|
||||
int nkeys, ScanKey key);
|
||||
extern void index_rescan(IndexScanDesc scan, ScanKey key);
|
||||
extern void index_endscan(IndexScanDesc scan);
|
||||
extern void index_markpos(IndexScanDesc scan);
|
||||
extern void index_restrpos(IndexScanDesc scan);
|
||||
extern RetrieveIndexResult index_getnext(IndexScanDesc scan,
|
||||
ScanDirection direction);
|
||||
extern IndexBulkDeleteResult *index_bulk_delete(Relation relation,
|
||||
extern HeapTuple index_getnext(IndexScanDesc scan, ScanDirection direction);
|
||||
extern bool index_getnext_indexitem(IndexScanDesc scan,
|
||||
ScanDirection direction);
|
||||
|
||||
extern IndexBulkDeleteResult *index_bulk_delete(Relation indexRelation,
|
||||
IndexBulkDeleteCallback callback,
|
||||
void *callback_state);
|
||||
extern RegProcedure index_cost_estimator(Relation relation);
|
||||
extern RegProcedure index_cost_estimator(Relation indexRelation);
|
||||
extern RegProcedure index_getprocid(Relation irel, AttrNumber attnum,
|
||||
uint16 procnum);
|
||||
extern struct FmgrInfo *index_getprocinfo(Relation irel, AttrNumber attnum,
|
||||
|
@ -78,18 +80,18 @@ extern struct FmgrInfo *index_getprocinfo(Relation irel, AttrNumber attnum,
|
|||
/*
|
||||
* index access method support routines (in genam.c)
|
||||
*/
|
||||
extern IndexScanDesc RelationGetIndexScan(Relation relation, bool scanFromEnd,
|
||||
uint16 numberOfKeys, ScanKey key);
|
||||
extern IndexScanDesc RelationGetIndexScan(Relation indexRelation,
|
||||
int nkeys, ScanKey key);
|
||||
extern void IndexScanEnd(IndexScanDesc scan);
|
||||
|
||||
/*
|
||||
* heap-or-index access to system catalogs (in genam.c)
|
||||
*/
|
||||
extern SysScanDesc systable_beginscan(Relation rel,
|
||||
extern SysScanDesc systable_beginscan(Relation heapRelation,
|
||||
const char *indexRelname,
|
||||
bool indexOK,
|
||||
Snapshot snapshot,
|
||||
unsigned nkeys, ScanKey key);
|
||||
int nkeys, ScanKey key);
|
||||
extern HeapTuple systable_getnext(SysScanDesc sysscan);
|
||||
extern void systable_endscan(SysScanDesc sysscan);
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: hash.h,v 1.45 2002/03/09 17:35:37 tgl Exp $
|
||||
* $Id: hash.h,v 1.46 2002/05/20 23:51:43 tgl Exp $
|
||||
*
|
||||
* NOTES
|
||||
* modeled after Margo Seltzer's hash implementation for unix.
|
||||
|
@ -306,8 +306,8 @@ extern void AtEOXact_hash(void);
|
|||
/* hashsearch.c */
|
||||
extern void _hash_search(Relation rel, int keysz, ScanKey scankey,
|
||||
Buffer *bufP, HashMetaPage metap);
|
||||
extern RetrieveIndexResult _hash_next(IndexScanDesc scan, ScanDirection dir);
|
||||
extern RetrieveIndexResult _hash_first(IndexScanDesc scan, ScanDirection dir);
|
||||
extern bool _hash_next(IndexScanDesc scan, ScanDirection dir);
|
||||
extern bool _hash_first(IndexScanDesc scan, ScanDirection dir);
|
||||
extern bool _hash_step(IndexScanDesc scan, Buffer *bufP, ScanDirection dir,
|
||||
Buffer metabuf);
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: heapam.h,v 1.73 2002/03/26 19:16:17 tgl Exp $
|
||||
* $Id: heapam.h,v 1.74 2002/05/20 23:51:43 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -16,6 +16,7 @@
|
|||
|
||||
#include "access/htup.h"
|
||||
#include "access/relscan.h"
|
||||
#include "access/sdir.h"
|
||||
#include "access/tupmacs.h"
|
||||
#include "access/xlogutils.h"
|
||||
#include "nodes/primnodes.h"
|
||||
|
@ -145,12 +146,16 @@ extern Relation heap_openr(const char *sysRelationName, LOCKMODE lockmode);
|
|||
|
||||
#define heap_close(r,l) relation_close(r,l)
|
||||
|
||||
extern HeapScanDesc heap_beginscan(Relation relation, int atend,
|
||||
Snapshot snapshot, unsigned nkeys, ScanKey key);
|
||||
extern void heap_rescan(HeapScanDesc scan, bool scanFromEnd, ScanKey key);
|
||||
extern HeapScanDesc heap_beginscan(Relation relation, Snapshot snapshot,
|
||||
int nkeys, ScanKey key);
|
||||
extern void heap_rescan(HeapScanDesc scan, ScanKey key);
|
||||
extern void heap_endscan(HeapScanDesc scan);
|
||||
extern HeapTuple heap_getnext(HeapScanDesc scandesc, int backw);
|
||||
extern void heap_fetch(Relation relation, Snapshot snapshot, HeapTuple tup, Buffer *userbuf, IndexScanDesc iscan);
|
||||
extern HeapTuple heap_getnext(HeapScanDesc scan, ScanDirection direction);
|
||||
|
||||
extern void heap_fetch(Relation relation, Snapshot snapshot,
|
||||
HeapTuple tuple, Buffer *userbuf,
|
||||
PgStat_Info *pgstat_info);
|
||||
|
||||
extern ItemPointer heap_get_latest_tid(Relation relation, Snapshot snapshot, ItemPointer tid);
|
||||
extern void setLastTid(const ItemPointer tid);
|
||||
extern Oid heap_insert(Relation relation, HeapTuple tup);
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: itup.h,v 1.33 2001/11/05 17:46:31 momjian Exp $
|
||||
* $Id: itup.h,v 1.34 2002/05/20 23:51:43 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -54,15 +54,6 @@ typedef struct InsertIndexResultData
|
|||
typedef InsertIndexResultData *InsertIndexResult;
|
||||
|
||||
|
||||
typedef struct RetrieveIndexResultData
|
||||
{
|
||||
ItemPointerData index_iptr;
|
||||
ItemPointerData heap_iptr;
|
||||
} RetrieveIndexResultData;
|
||||
|
||||
typedef RetrieveIndexResultData *RetrieveIndexResult;
|
||||
|
||||
|
||||
/* ----------------
|
||||
* externs
|
||||
* ----------------
|
||||
|
@ -147,8 +138,6 @@ extern IndexTuple index_formtuple(TupleDesc tupleDescriptor,
|
|||
Datum *value, char *null);
|
||||
extern Datum nocache_index_getattr(IndexTuple tup, int attnum,
|
||||
TupleDesc tupleDesc, bool *isnull);
|
||||
extern RetrieveIndexResult FormRetrieveIndexResult(ItemPointer indexItemPointer,
|
||||
ItemPointer heapItemPointer);
|
||||
extern void CopyIndexTuple(IndexTuple source, IndexTuple *target);
|
||||
|
||||
#endif /* ITUP_H */
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: nbtree.h,v 1.59 2001/11/05 17:46:31 momjian Exp $
|
||||
* $Id: nbtree.h,v 1.60 2002/05/20 23:51:43 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -100,8 +100,8 @@ typedef struct BTScanOpaqueData
|
|||
ItemPointerData mrkHeapIptr;
|
||||
/* these fields are set by _bt_orderkeys(), which see for more info: */
|
||||
bool qual_ok; /* false if qual can never be satisfied */
|
||||
uint16 numberOfKeys; /* number of scan keys */
|
||||
uint16 numberOfRequiredKeys; /* number of keys that must be
|
||||
int numberOfKeys; /* number of scan keys */
|
||||
int numberOfRequiredKeys; /* number of keys that must be
|
||||
* matched to continue the scan */
|
||||
ScanKey keyData; /* array of scan keys */
|
||||
} BTScanOpaqueData;
|
||||
|
@ -366,8 +366,8 @@ extern OffsetNumber _bt_binsrch(Relation rel, Buffer buf, int keysz,
|
|||
ScanKey scankey);
|
||||
extern int32 _bt_compare(Relation rel, int keysz, ScanKey scankey,
|
||||
Page page, OffsetNumber offnum);
|
||||
extern RetrieveIndexResult _bt_next(IndexScanDesc scan, ScanDirection dir);
|
||||
extern RetrieveIndexResult _bt_first(IndexScanDesc scan, ScanDirection dir);
|
||||
extern bool _bt_next(IndexScanDesc scan, ScanDirection dir);
|
||||
extern bool _bt_first(IndexScanDesc scan, ScanDirection dir);
|
||||
extern bool _bt_step(IndexScanDesc scan, Buffer *bufP, ScanDirection dir);
|
||||
|
||||
/*
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* relscan.h
|
||||
* POSTGRES internal relation scan descriptor definitions.
|
||||
* POSTGRES relation scan descriptor definitions.
|
||||
*
|
||||
*
|
||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: relscan.h,v 1.25 2001/11/05 17:46:31 momjian Exp $
|
||||
* $Id: relscan.h,v 1.26 2002/05/20 23:51:43 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -19,42 +19,54 @@
|
|||
|
||||
typedef struct HeapScanDescData
|
||||
{
|
||||
Relation rs_rd; /* pointer to relation descriptor */
|
||||
/* scan parameters */
|
||||
Relation rs_rd; /* heap relation descriptor */
|
||||
Snapshot rs_snapshot; /* snapshot to see */
|
||||
int rs_nkeys; /* number of scan keys */
|
||||
ScanKey rs_key; /* array of scan key descriptors */
|
||||
|
||||
/* scan current state */
|
||||
HeapTupleData rs_ctup; /* current tuple in scan, if any */
|
||||
Buffer rs_cbuf; /* current buffer in scan, if any */
|
||||
/* NB: if rs_cbuf is not InvalidBuffer, we hold a pin on that buffer */
|
||||
ItemPointerData rs_mctid; /* marked tid, if any */
|
||||
Snapshot rs_snapshot; /* snapshot to see */
|
||||
uint16 rs_nkeys; /* number of scan keys to select tuples */
|
||||
ScanKey rs_key; /* key descriptors */
|
||||
ItemPointerData rs_mctid; /* marked scan position, if any */
|
||||
|
||||
PgStat_Info rs_pgstat_info; /* statistics collector hook */
|
||||
} HeapScanDescData;
|
||||
|
||||
typedef HeapScanDescData *HeapScanDesc;
|
||||
|
||||
|
||||
typedef struct IndexScanDescData
|
||||
{
|
||||
Relation relation; /* relation descriptor */
|
||||
/* scan parameters */
|
||||
Relation heapRelation; /* heap relation descriptor, or NULL */
|
||||
Relation indexRelation; /* index relation descriptor */
|
||||
Snapshot xs_snapshot; /* snapshot to see */
|
||||
int numberOfKeys; /* number of scan keys */
|
||||
ScanKey keyData; /* array of scan key descriptors */
|
||||
|
||||
/* scan current state */
|
||||
void *opaque; /* access-method-specific info */
|
||||
ItemPointerData currentItemData; /* current index pointer */
|
||||
ItemPointerData currentMarkData; /* marked current pointer */
|
||||
uint8 flags; /* scan position flags */
|
||||
bool scanFromEnd; /* restart scan at end? */
|
||||
uint16 numberOfKeys; /* number of scan keys to select tuples */
|
||||
ScanKey keyData; /* key descriptors */
|
||||
FmgrInfo fn_getnext; /* cached lookup info for am's getnext fn */
|
||||
ItemPointerData currentMarkData; /* marked position, if any */
|
||||
/*
|
||||
* xs_ctup/xs_cbuf are valid after a successful index_getnext.
|
||||
* After index_getnext_indexitem, xs_ctup.t_self contains the
|
||||
* heap tuple TID from the index entry, but its other fields are
|
||||
* not valid.
|
||||
*/
|
||||
HeapTupleData xs_ctup; /* current heap tuple, if any */
|
||||
Buffer xs_cbuf; /* current heap buffer in scan, if any */
|
||||
/* NB: if xs_cbuf is not InvalidBuffer, we hold a pin on that buffer */
|
||||
|
||||
FmgrInfo fn_getnext; /* cached lookup info for AM's getnext fn */
|
||||
|
||||
PgStat_Info xs_pgstat_info; /* statistics collector hook */
|
||||
} IndexScanDescData;
|
||||
|
||||
typedef IndexScanDescData *IndexScanDesc;
|
||||
|
||||
/* IndexScanDesc flag bits (none of these are actually used currently) */
|
||||
#define ScanUnmarked 0x01
|
||||
#define ScanUncheckedPrevious 0x02
|
||||
#define ScanUncheckedNext 0x04
|
||||
|
||||
|
||||
/* ----------------
|
||||
* IndexScanDescPtr is used in the executor where we have to
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: rtree.h,v 1.27 2001/11/05 17:46:31 momjian Exp $
|
||||
* $Id: rtree.h,v 1.28 2002/05/20 23:51:43 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -71,7 +71,7 @@ typedef struct RTreeScanOpaqueData
|
|||
struct RTSTACK *s_stack;
|
||||
struct RTSTACK *s_markstk;
|
||||
uint16 s_flags;
|
||||
uint16 s_internalNKey;
|
||||
int s_internalNKey;
|
||||
ScanKey s_internalKey;
|
||||
} RTreeScanOpaqueData;
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: pg_proc.h,v 1.237 2002/05/18 13:48:00 petere Exp $
|
||||
* $Id: pg_proc.h,v 1.238 2002/05/20 23:51:43 tgl Exp $
|
||||
*
|
||||
* NOTES
|
||||
* The script catalog/genbki.sh reads this file and generates .bki
|
||||
|
@ -681,7 +681,7 @@ DATA(insert OID = 322 ( rtgettuple PGNSP PGUID 12 f f f t f v 2 23 "0 0" 10
|
|||
DESCR("r-tree(internal)");
|
||||
DATA(insert OID = 323 ( rtbuild PGNSP PGUID 12 f f f t f v 3 23 "0 0 0" 100 0 0 100 rtbuild - _null_ ));
|
||||
DESCR("r-tree(internal)");
|
||||
DATA(insert OID = 324 ( rtbeginscan PGNSP PGUID 12 f f f t f v 4 23 "0 0 0 0" 100 0 0 100 rtbeginscan - _null_ ));
|
||||
DATA(insert OID = 324 ( rtbeginscan PGNSP PGUID 12 f f f t f v 3 23 "0 0 0" 100 0 0 100 rtbeginscan - _null_ ));
|
||||
DESCR("r-tree(internal)");
|
||||
DATA(insert OID = 325 ( rtendscan PGNSP PGUID 12 f f f t f v 1 23 "0" 100 0 0 100 rtendscan - _null_ ));
|
||||
DESCR("r-tree(internal)");
|
||||
|
@ -689,7 +689,7 @@ DATA(insert OID = 326 ( rtmarkpos PGNSP PGUID 12 f f f t f v 1 23 "0" 100 0
|
|||
DESCR("r-tree(internal)");
|
||||
DATA(insert OID = 327 ( rtrestrpos PGNSP PGUID 12 f f f t f v 1 23 "0" 100 0 0 100 rtrestrpos - _null_ ));
|
||||
DESCR("r-tree(internal)");
|
||||
DATA(insert OID = 328 ( rtrescan PGNSP PGUID 12 f f f t f v 3 23 "0 0 0" 100 0 0 100 rtrescan - _null_ ));
|
||||
DATA(insert OID = 328 ( rtrescan PGNSP PGUID 12 f f f t f v 2 23 "0 0" 100 0 0 100 rtrescan - _null_ ));
|
||||
DESCR("r-tree(internal)");
|
||||
DATA(insert OID = 321 ( rtbulkdelete PGNSP PGUID 12 f f f t f v 3 23 "0 0 0" 100 0 0 100 rtbulkdelete - _null_ ));
|
||||
DESCR("r-tree(internal)");
|
||||
|
@ -700,9 +700,9 @@ DATA(insert OID = 330 ( btgettuple PGNSP PGUID 12 f f f t f v 2 23 "0 0" 10
|
|||
DESCR("btree(internal)");
|
||||
DATA(insert OID = 331 ( btinsert PGNSP PGUID 12 f f f t f v 5 23 "0 0 0 0 0" 100 0 0 100 btinsert - _null_ ));
|
||||
DESCR("btree(internal)");
|
||||
DATA(insert OID = 333 ( btbeginscan PGNSP PGUID 12 f f f t f v 4 23 "0 0 0 0" 100 0 0 100 btbeginscan - _null_ ));
|
||||
DATA(insert OID = 333 ( btbeginscan PGNSP PGUID 12 f f f t f v 3 23 "0 0 0" 100 0 0 100 btbeginscan - _null_ ));
|
||||
DESCR("btree(internal)");
|
||||
DATA(insert OID = 334 ( btrescan PGNSP PGUID 12 f f f t f v 3 23 "0 0 0" 100 0 0 100 btrescan - _null_ ));
|
||||
DATA(insert OID = 334 ( btrescan PGNSP PGUID 12 f f f t f v 2 23 "0 0" 100 0 0 100 btrescan - _null_ ));
|
||||
DESCR("btree(internal)");
|
||||
DATA(insert OID = 335 ( btendscan PGNSP PGUID 12 f f f t f v 1 23 "0" 100 0 0 100 btendscan - _null_ ));
|
||||
DESCR("btree(internal)");
|
||||
|
@ -803,9 +803,9 @@ DATA(insert OID = 440 ( hashgettuple PGNSP PGUID 12 f f f t f v 2 23 "0 0" 1
|
|||
DESCR("hash(internal)");
|
||||
DATA(insert OID = 441 ( hashinsert PGNSP PGUID 12 f f f t f v 5 23 "0 0 0 0 0" 100 0 0 100 hashinsert - _null_ ));
|
||||
DESCR("hash(internal)");
|
||||
DATA(insert OID = 443 ( hashbeginscan PGNSP PGUID 12 f f f t f v 4 23 "0 0 0 0" 100 0 0 100 hashbeginscan - _null_ ));
|
||||
DATA(insert OID = 443 ( hashbeginscan PGNSP PGUID 12 f f f t f v 3 23 "0 0 0" 100 0 0 100 hashbeginscan - _null_ ));
|
||||
DESCR("hash(internal)");
|
||||
DATA(insert OID = 444 ( hashrescan PGNSP PGUID 12 f f f t f v 3 23 "0 0 0" 100 0 0 100 hashrescan - _null_ ));
|
||||
DATA(insert OID = 444 ( hashrescan PGNSP PGUID 12 f f f t f v 2 23 "0 0" 100 0 0 100 hashrescan - _null_ ));
|
||||
DESCR("hash(internal)");
|
||||
DATA(insert OID = 445 ( hashendscan PGNSP PGUID 12 f f f t f v 1 23 "0" 100 0 0 100 hashendscan - _null_ ));
|
||||
DESCR("hash(internal)");
|
||||
|
@ -1033,9 +1033,9 @@ DATA(insert OID = 774 ( gistgettuple PGNSP PGUID 12 f f f t f v 2 23 "0 0" 1
|
|||
DESCR("gist(internal)");
|
||||
DATA(insert OID = 775 ( gistinsert PGNSP PGUID 12 f f f t f v 5 23 "0 0 0 0 0" 100 0 0 100 gistinsert - _null_ ));
|
||||
DESCR("gist(internal)");
|
||||
DATA(insert OID = 777 ( gistbeginscan PGNSP PGUID 12 f f f t f v 4 23 "0 0 0 0" 100 0 0 100 gistbeginscan - _null_ ));
|
||||
DATA(insert OID = 777 ( gistbeginscan PGNSP PGUID 12 f f f t f v 3 23 "0 0 0" 100 0 0 100 gistbeginscan - _null_ ));
|
||||
DESCR("gist(internal)");
|
||||
DATA(insert OID = 778 ( gistrescan PGNSP PGUID 12 f f f t f v 3 23 "0 0 0" 100 0 0 100 gistrescan - _null_ ));
|
||||
DATA(insert OID = 778 ( gistrescan PGNSP PGUID 12 f f f t f v 2 23 "0 0" 100 0 0 100 gistrescan - _null_ ));
|
||||
DESCR("gist(internal)");
|
||||
DATA(insert OID = 779 ( gistendscan PGNSP PGUID 12 f f f t f v 1 23 "0" 100 0 0 100 gistendscan - _null_ ));
|
||||
DESCR("gist(internal)");
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: execnodes.h,v 1.68 2002/05/12 20:10:04 tgl Exp $
|
||||
* $Id: execnodes.h,v 1.69 2002/05/20 23:51:44 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -463,7 +463,6 @@ typedef struct IndexScanState
|
|||
bool iss_RuntimeKeysReady;
|
||||
RelationPtr iss_RelationDescs;
|
||||
IndexScanDescPtr iss_ScanDescs;
|
||||
HeapTupleData iss_htup;
|
||||
} IndexScanState;
|
||||
|
||||
/* ----------------
|
||||
|
|
Loading…
Reference in New Issue