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