aboutsummaryrefslogtreecommitdiff
path: root/src/backend/access/index/genam.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/access/index/genam.c')
-rw-r--r--src/backend/access/index/genam.c233
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);
}