diff options
Diffstat (limited to 'src/backend/access/index/genam.c')
-rw-r--r-- | src/backend/access/index/genam.c | 86 |
1 files changed, 85 insertions, 1 deletions
diff --git a/src/backend/access/index/genam.c b/src/backend/access/index/genam.c index 8877938322d..cafb1e6867a 100644 --- a/src/backend/access/index/genam.c +++ b/src/backend/access/index/genam.c @@ -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); +} |