diff options
author | Tom Lane | 2002-05-20 23:51:44 +0000 |
---|---|---|
committer | Tom Lane | 2002-05-20 23:51:44 +0000 |
commit | c13d808d60f7d937563fc452a645c98955b79174 (patch) | |
tree | 08bd624e401d80c46486d1fd54b1c15fcac329b1 | |
parent | b16634a2bc9c0f8cd3be722d7d4f4a043030ea6d (diff) |
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.
59 files changed, 777 insertions, 1226 deletions
diff --git a/contrib/dblink/dblink.c b/contrib/dblink/dblink.c index 68fd2a797e..8201f8815a 100644 --- a/contrib/dblink/dblink.c +++ b/contrib/dblink/dblink.c @@ -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); diff --git a/contrib/dbsize/dbsize.c b/contrib/dbsize/dbsize.c index d85822914d..b072a86912 100644 --- a/contrib/dbsize/dbsize.c +++ b/contrib/dbsize/dbsize.c @@ -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)); diff --git a/contrib/miscutil/misc_utils.c b/contrib/miscutil/misc_utils.c index d313392965..26bbabe46f 100644 --- a/contrib/miscutil/misc_utils.c +++ b/contrib/miscutil/misc_utils.c @@ -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: - */ diff --git a/contrib/pgstattuple/pgstattuple.c b/contrib/pgstattuple/pgstattuple.c index 1806271e4e..8ab7d2d1db 100644 --- a/contrib/pgstattuple/pgstattuple.c +++ b/contrib/pgstattuple/pgstattuple.c @@ -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)) { diff --git a/src/backend/access/common/indextuple.c b/src/backend/access/common/indextuple.c index f2e1fee04e..d7881fa869 100644 --- a/src/backend/access/common/indextuple.c +++ b/src/backend/access/common/indextuple.c @@ -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); } diff --git a/src/backend/access/gist/gist.c b/src/backend/access/gist/gist.c index 4a1987aa8e..7e764f9e1c 100644 --- a/src/backend/access/gist/gist.c +++ b/src/backend/access/gist/gist.c @@ -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); diff --git a/src/backend/access/gist/gistget.c b/src/backend/access/gist/gistget.c index fb2f449643..4407840c15 100644 --- a/src/backend/access/gist/gistget.c +++ b/src/backend/access/gist/gistget.c @@ -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; } diff --git a/src/backend/access/gist/gistscan.c b/src/backend/access/gist/gistscan.c index eafa23e309..effae2c10d 100644 --- a/src/backend/access/gist/gistscan.c +++ b/src/backend/access/gist/gistscan.c @@ -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); } } diff --git a/src/backend/access/hash/hash.c b/src/backend/access/hash/hash.c index b30f041d70..9015e4f84b 100644 --- a/src/backend/access/hash/hash.c +++ b/src/backend/access/hash/hash.c @@ -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); diff --git a/src/backend/access/hash/hashscan.c b/src/backend/access/hash/hashscan.c index e74cdce893..e2f002e4e0 100644 --- a/src/backend/access/hash/hashscan.c +++ b/src/backend/access/hash/hashscan.c @@ -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; diff --git a/src/backend/access/hash/hashsearch.c b/src/backend/access/hash/hashsearch.c index 40a91d9b07..3e72367323 100644 --- a/src/backend/access/hash/hashsearch.c +++ b/src/backend/access/hash/hashsearch.c @@ -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); diff --git a/src/backend/access/hash/hashutil.c b/src/backend/access/hash/hashutil.c index 9b3090b515..8e881193e8 100644 --- a/src/backend/access/hash/hashutil.c +++ b/src/backend/access/hash/hashutil.c @@ -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; diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index 2c9399f62c..551f5e0c58 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -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); - - if (scan->rs_ctup.t_data == NULL && !BufferIsValid(scan->rs_cbuf)) - { - HEAPDEBUG_2; /* heap_getnext returning EOS */ - return NULL; - } - } - else + /* + * 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)) { - /* - * 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); } diff --git a/src/backend/access/heap/tuptoaster.c b/src/backend/access/heap/tuptoaster.c index ad8212b477..5e5d6db554 100644 --- a/src/backend/access/heap/tuptoaster.c +++ b/src/backend/access/heap/tuptoaster.c @@ -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 */ diff --git a/src/backend/access/index/genam.c b/src/backend/access/index/genam.c index 8dca673349..f28142b2db 100644 --- a/src/backend/access/index/genam.c +++ b/src/backend/access/index/genam.c @@ -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); } diff --git a/src/backend/access/index/indexam.c b/src/backend/access/index/indexam.c index 1cc8cd8e5b..caf369fde1 100644 --- a/src/backend/access/index/indexam.c +++ b/src/backend/access/index/indexam.c @@ -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; diff --git a/src/backend/access/nbtree/nbtree.c b/src/backend/access/nbtree/nbtree.c index 8f5dfd2fcb..ebe5c18dc9 100644 --- a/src/backend/access/nbtree/nbtree.c +++ b/src/backend/access/nbtree/nbtree.c @@ -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; diff --git a/src/backend/access/nbtree/nbtsearch.c b/src/backend/access/nbtree/nbtsearch.c index eab5336864..92f19ebd25 100644 --- a/src/backend/access/nbtree/nbtsearch.c +++ b/src/backend/access/nbtree/nbtsearch.c @@ -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; diff --git a/src/backend/access/nbtree/nbtutils.c b/src/backend/access/nbtree/nbtutils.c index ef7b6eee8b..ac41eddb60 100644 --- a/src/backend/access/nbtree/nbtutils.c +++ b/src/backend/access/nbtree/nbtutils.c @@ -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; diff --git a/src/backend/access/rtree/rtget.c b/src/backend/access/rtree/rtget.c index 20d600a752..445a88a276 100644 --- a/src/backend/access/rtree/rtget.c +++ b/src/backend/access/rtree/rtget.c @@ -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; + + 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 ip; + return true; } diff --git a/src/backend/access/rtree/rtree.c b/src/backend/access/rtree/rtree.c index 9cd520376e..44fe6c1826 100644 --- a/src/backend/access/rtree/rtree.c +++ b/src/backend/access/rtree/rtree.c @@ -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); diff --git a/src/backend/access/rtree/rtscan.c b/src/backend/access/rtree/rtscan.c index 584aa5a20e..c62b8a5d99 100644 --- a/src/backend/access/rtree/rtscan.c +++ b/src/backend/access/rtree/rtscan.c @@ -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); } } diff --git a/src/backend/bootstrap/bootstrap.c b/src/backend/bootstrap/bootstrap.c index d5903f5f43..16761775bd 100644 --- a/src/backend/bootstrap/bootstrap.c +++ b/src/backend/bootstrap/bootstrap.c @@ -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, diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c index d5d3c8f80e..e6ebe64e24 100644 --- a/src/backend/catalog/aclchk.c +++ b/src/backend/catalog/aclchk.c @@ -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); diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c index 933abc462f..eb65f30de1 100644 --- a/src/backend/catalog/heap.c +++ b/src/backend/catalog/heap.c @@ -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); diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index b14cde0ff5..84488eb78a 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -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); diff --git a/src/backend/catalog/namespace.c b/src/backend/catalog/namespace.c index 870d587df2..996a803089 100644 --- a/src/backend/catalog/namespace.c +++ b/src/backend/catalog/namespace.c @@ -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; diff --git a/src/backend/catalog/pg_largeobject.c b/src/backend/catalog/pg_largeobject.c index 7e09499ca8..8114cf6693 100644 --- a/src/backend/catalog/pg_largeobject.c +++ b/src/backend/catalog/pg_largeobject.c @@ -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); - - tuple.t_datamcxt = CurrentMemoryContext; - tuple.t_data = NULL; + sd = index_beginscan(pg_largeobject, pg_lo_idx, SnapshotNow, 1, skey); - 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); diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f13e247916..ee1defbc97 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -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) diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index 5838883b46..ed503ea97b 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -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); diff --git a/src/backend/commands/cluster.c b/src/backend/commands/cluster.c index 1aa5e3845d..2929ade5fa 100644 --- a/src/backend/commands/cluster.c +++ b/src/backend/commands/cluster.c @@ -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); diff --git a/src/backend/commands/comment.c b/src/backend/commands/comment.c index 402326781c..c6fbf2d1f2 100644 --- a/src/backend/commands/comment.c +++ b/src/backend/commands/comment.c @@ -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); - - while ((indexRes = index_getnext(sd, ForwardScanDirection))) - { - oldtuple.t_self = indexRes->heap_iptr; - heap_fetch(description, SnapshotNow, &oldtuple, &buffer, sd); - pfree(indexRes); - - if (oldtuple.t_data == NULL) - continue; /* time qual failed */ + description = heap_openr(DescriptionRelationName, RowExclusiveLock); - simple_heap_delete(description, &oldtuple.t_self); + sd = systable_beginscan(description, DescriptionObjIndex, true, + SnapshotNow, 2, skey); - ReleaseBuffer(buffer); + while ((oldtuple = systable_getnext(sd)) != NULL) + { + 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); diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c index f0590ddef2..a8e7bb48da 100644 --- a/src/backend/commands/copy.c +++ b/src/backend/commands/copy.c @@ -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; diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c index 6b6906cb4f..8b7aba30de 100644 --- a/src/backend/commands/dbcommands.c +++ b/src/backend/commands/dbcommands.c @@ -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) diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c index 481bb3c3f4..29f30cd471 100644 --- a/src/backend/commands/indexcmds.c +++ b/src/backend/commands/indexcmds.c @@ -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) { diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index e1597d0ae3..bdfdece412 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -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); + { + ScanKeyEntryInitialize(&skey[0], 0x0, + Anum_pg_trigger_tgconstrrelid, + F_OIDEQ, + ObjectIdGetDatum(relid)); + trigscan = systable_beginscan(tgrel, TriggerConstrRelidIndex, + true, SnapshotNow, + 1, skey); + } 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); + { + ScanKeyEntryInitialize(&skey[0], 0x0, + Anum_pg_trigger_tgrelid, + F_OIDEQ, + ObjectIdGetDatum(relid)); + trigscan = systable_beginscan(tgrel, TriggerRelidNameIndex, + true, SnapshotNow, + 1, skey); + } - while ((idxres = index_getnext(idxtgscan, ForwardScanDirection)) != NULL) + while ((tuple = systable_getnext(trigscan)) != NULL) { - HeapTupleData tupledata; - Buffer buffer; - HeapTuple tuple; - Form_pg_trigger pg_trigger; + 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; } @@ -1463,11 +1459,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 */ simple_heap_update(tgrel, &tuple->t_self, tuple); @@ -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 */ diff --git a/src/backend/commands/user.c b/src/backend/commands/user.c index 7c43954a03..b3ab1b9966 100644 --- a/src/backend/commands/user.c +++ b/src/backend/commands/user.c @@ -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; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 4abb35fb32..88327f07da 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -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); diff --git a/src/backend/executor/nodeIndexscan.c b/src/backend/executor/nodeIndexscan.c index 4561bb58b6..75f142e8d4 100644 --- a/src/backend/executor/nodeIndexscan.c +++ b/src/backend/executor/nodeIndexscan.c @@ -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)); /* @@ -1011,17 +993,10 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent) } /* - * 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; /* diff --git a/src/backend/executor/nodeSeqscan.c b/src/backend/executor/nodeSeqscan.c index ce1f709293..2616d55c50 100644 --- a/src/backend/executor/nodeSeqscan.c +++ b/src/backend/executor/nodeSeqscan.c @@ -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 */ } diff --git a/src/backend/optimizer/path/indxpath.c b/src/backend/optimizer/path/indxpath.c index 969eba822d..8fa69b06fe 100644 --- a/src/backend/optimizer/path/indxpath.c +++ b/src/backend/optimizer/path/indxpath.c @@ -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)) diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c index 51b53a5831..9e7d2c88ed 100644 --- a/src/backend/optimizer/util/plancat.c +++ b/src/backend/optimizer/util/plancat.c @@ -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); diff --git a/src/backend/parser/parse_func.c b/src/backend/parser/parse_func.c index 84c7bb788c..993b70d5f9 100644 --- a/src/backend/parser/parse_func.c +++ b/src/backend/parser/parse_func.c @@ -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); diff --git a/src/backend/postmaster/pgstat.c b/src/backend/postmaster/pgstat.c index 210be8d72b..e40a1f88c0 100644 --- a/src/backend/postmaster/pgstat.c +++ b/src/backend/postmaster/pgstat.c @@ -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) { diff --git a/src/backend/rewrite/rewriteDefine.c b/src/backend/rewrite/rewriteDefine.c index 5dfb721018..435102fc27 100644 --- a/src/backend/rewrite/rewriteDefine.c +++ b/src/backend/rewrite/rewriteDefine.c @@ -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; diff --git a/src/backend/storage/large_object/inv_api.c b/src/backend/storage/large_object/inv_api.c index 49d2bc80fa..8bdc36791c 100644 --- a/src/backend/storage/large_object/inv_api.c +++ b/src/backend/storage/large_object/inv_api.c @@ -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); - - tuple.t_datamcxt = CurrentMemoryContext; - tuple.t_data = NULL; + sd = index_beginscan(obj_desc->heap_r, obj_desc->index_r, + SnapshotNow, 2, skey); - 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) diff --git a/src/backend/utils/adt/not_in.c b/src/backend/utils/adt/not_in.c index b0004c6a61..c64ebbb465 100644 --- a/src/backend/utils/adt/not_in.c +++ b/src/backend/utils/adt/not_in.c @@ -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, diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c index aa3c49e358..bb5176bc9e 100644 --- a/src/backend/utils/init/postinit.c +++ b/src/backend/utils/init/postinit.c @@ -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); diff --git a/src/backend/utils/misc/superuser.c b/src/backend/utils/misc/superuser.c index 8d48903f9b..042b46a320 100644 --- a/src/backend/utils/misc/superuser.c +++ b/src/backend/utils/misc/superuser.c @@ -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; diff --git a/src/backend/utils/sort/tuplesort.c b/src/backend/utils/sort/tuplesort.c index 5187efe016..bd8428cb7b 100644 --- a/src/backend/utils/sort/tuplesort.c +++ b/src/backend/utils/sort/tuplesort.c @@ -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); diff --git a/src/include/access/genam.h b/src/include/access/genam.h index d002a50bf1..9e047af3f4 100644 --- a/src/include/access/genam.h +++ b/src/include/access/genam.h @@ -1,7 +1,7 @@ /*------------------------------------------------------------------------- * * genam.h - * POSTGRES general access method definitions. + * POSTGRES generalized index access method definitions. * * * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group @@ -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); diff --git a/src/include/access/hash.h b/src/include/access/hash.h index b565f11bed..12ea4d9ce6 100644 --- a/src/include/access/hash.h +++ b/src/include/access/hash.h @@ -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); diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h index 718b2bc9e8..07fad4bb43 100644 --- a/src/include/access/heapam.h +++ b/src/include/access/heapam.h @@ -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); diff --git a/src/include/access/itup.h b/src/include/access/itup.h index bb7a1cec0c..2d0111932d 100644 --- a/src/include/access/itup.h +++ b/src/include/access/itup.h @@ -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 */ diff --git a/src/include/access/nbtree.h b/src/include/access/nbtree.h index d1fe308035..435a1d3739 100644 --- a/src/include/access/nbtree.h +++ b/src/include/access/nbtree.h @@ -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); /* diff --git a/src/include/access/relscan.h b/src/include/access/relscan.h index 77955ebbc2..b2ff9df581 100644 --- a/src/include/access/relscan.h +++ b/src/include/access/relscan.h @@ -1,7 +1,7 @@ /*------------------------------------------------------------------------- * * relscan.h - * POSTGRES internal relation scan descriptor definitions. + * POSTGRES relation scan descriptor definitions. * * * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group @@ -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 diff --git a/src/include/access/rtree.h b/src/include/access/rtree.h index 3ec24e00cc..8b71ea60a6 100644 --- a/src/include/access/rtree.h +++ b/src/include/access/rtree.h @@ -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; diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h index dbd5892b94..7b92897542 100644 --- a/src/include/catalog/pg_proc.h +++ b/src/include/catalog/pg_proc.h @@ -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)"); diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h index 8815630198..7a0410fea9 100644 --- a/src/include/nodes/execnodes.h +++ b/src/include/nodes/execnodes.h @@ -463,7 +463,6 @@ typedef struct IndexScanState bool iss_RuntimeKeysReady; RelationPtr iss_RelationDescs; IndexScanDescPtr iss_ScanDescs; - HeapTupleData iss_htup; } IndexScanState; /* ---------------- |