1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-07 19:06:32 +03:00

Create new routines systable_beginscan_ordered, systable_getnext_ordered,

systable_endscan_ordered that have API similar to systable_beginscan etc
(in particular, the passed-in scankeys have heap not index attnums),
but guarantee ordered output, unlike the existing functions.  For the moment
these are just very thin wrappers around index_beginscan/index_getnext/etc.
Someday they might need to get smarter; but for now this is just a code
refactoring exercise to reduce the number of direct callers of index_getnext,
in preparation for changing that function's API.

In passing, remove index_getnext_indexitem, which has been dead code for
quite some time, and will have even less use than that in the presence
of run-time-lossy indexes.
This commit is contained in:
Tom Lane
2008-04-12 23:14:21 +00:00
parent 00832809a0
commit ec498cdcbb
9 changed files with 168 additions and 124 deletions

View File

@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/index/genam.c,v 1.66 2008/04/10 22:25:25 tgl Exp $
* $PostgreSQL: pgsql/src/backend/access/index/genam.c,v 1.67 2008/04/12 23:14:21 tgl Exp $
*
* NOTES
* many of the old access method routines have been turned into
@@ -258,3 +258,87 @@ systable_endscan(SysScanDesc sysscan)
pfree(sysscan);
}
/*
* systable_beginscan_ordered --- set up for ordered catalog scan
*
* These routines have essentially the same API as systable_beginscan etc,
* except that they guarantee to return multiple matching tuples in
* index order. Also, for largely historical reasons, the index to use
* is opened and locked by the caller, not here.
*
* Currently we do not support non-index-based scans here. (In principle
* we could do a heapscan and sort, but the uses are in places that
* probably don't need to still work with corrupted catalog indexes.)
* For the moment, therefore, these functions are merely the thinnest of
* wrappers around index_beginscan/index_getnext. The main reason for their
* existence is to centralize possible future support of lossy operators
* in catalog scans.
*/
SysScanDesc
systable_beginscan_ordered(Relation heapRelation,
Relation indexRelation,
Snapshot snapshot,
int nkeys, ScanKey key)
{
SysScanDesc sysscan;
int i;
/* REINDEX can probably be a hard error here ... */
if (ReindexIsProcessingIndex(RelationGetRelid(indexRelation)))
elog(ERROR, "cannot do ordered scan on index \"%s\", because it is the current REINDEX target",
RelationGetRelationName(indexRelation));
/* ... but we only throw a warning about violating IgnoreSystemIndexes */
if (IgnoreSystemIndexes)
elog(WARNING, "using index \"%s\" despite IgnoreSystemIndexes",
RelationGetRelationName(indexRelation));
sysscan = (SysScanDesc) palloc(sizeof(SysScanDescData));
sysscan->heap_rel = heapRelation;
sysscan->irel = indexRelation;
/*
* Change attribute numbers to be index column numbers.
*
* This code could be generalized to search for the index key numbers
* to substitute, but for now there's no need.
*/
for (i = 0; i < nkeys; i++)
{
Assert(key[i].sk_attno == indexRelation->rd_index->indkey.values[i]);
key[i].sk_attno = i + 1;
}
sysscan->iscan = index_beginscan(heapRelation, indexRelation,
snapshot, nkeys, key);
sysscan->scan = NULL;
return sysscan;
}
/*
* systable_getnext_ordered --- get next tuple in an ordered catalog scan
*/
HeapTuple
systable_getnext_ordered(SysScanDesc sysscan, ScanDirection direction)
{
HeapTuple htup;
Assert(sysscan->irel);
htup = index_getnext(sysscan->iscan, direction);
return htup;
}
/*
* systable_endscan_ordered --- close scan, release resources
*/
void
systable_endscan_ordered(SysScanDesc sysscan)
{
Assert(sysscan->irel);
index_endscan(sysscan->iscan);
pfree(sysscan);
}

View File

@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/index/indexam.c,v 1.105 2008/04/10 22:25:25 tgl Exp $
* $PostgreSQL: pgsql/src/backend/access/index/indexam.c,v 1.106 2008/04/12 23:14:21 tgl Exp $
*
* INTERFACE ROUTINES
* index_open - open an index relation by relation OID
@@ -206,12 +206,7 @@ index_insert(Relation indexRelation,
/*
* index_beginscan - start a scan of an index with amgettuple
*
* 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. Caller must also
* be holding a lock on the index.
* Caller must be holding suitable locks on the heap and the index.
*/
IndexScanDesc
index_beginscan(Relation heapRelation,
@@ -634,45 +629,6 @@ index_getnext(IndexScanDesc scan, ScanDirection direction)
return NULL; /* failure exit */
}
/* ----------------
* index_getnext_indexitem - get the next index tuple from a scan
*
* Finds the next index tuple satisfying the scan keys. Note that the
* corresponding heap tuple is not accessed, and thus no time qual (snapshot)
* check is done, other than the index AM's internal check for killed tuples
* (which most callers of this routine will probably want to suppress by
* setting scan->ignore_killed_tuples = false).
*
* On success (TRUE return), the heap TID of the found index entry is in
* scan->xs_ctup.t_self. scan->xs_cbuf is untouched.
* ----------------
*/
bool
index_getnext_indexitem(IndexScanDesc scan,
ScanDirection direction)
{
FmgrInfo *procedure;
bool found;
SCAN_CHECKS;
GET_SCAN_PROCEDURE(amgettuple);
/* just make sure this is false... */
scan->kill_prior_tuple = false;
/*
* have the am's gettuple proc do all the work.
*/
found = DatumGetBool(FunctionCall2(procedure,
PointerGetDatum(scan),
Int32GetDatum(direction)));
if (found)
pgstat_count_index_tuples(scan->indexRelation, 1);
return found;
}
/* ----------------
* index_getbitmap - get all tuples at once from an index scan
*