summaryrefslogtreecommitdiff
path: root/src/backend/access
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2008-04-12 23:14:21 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2008-04-12 23:14:21 +0000
commitec498cdcbb7e7b430acc7236ab19ef70f116441a (patch)
tree48ab9fa79a3b9ac79f58a6079c28328243312f56 /src/backend/access
parent00832809a0fe271487d6851af72d0d88246a5d94 (diff)
downloadpostgresql-ec498cdcbb7e7b430acc7236ab19ef70f116441a.tar.gz
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.
Diffstat (limited to 'src/backend/access')
-rw-r--r--src/backend/access/heap/tuptoaster.c43
-rw-r--r--src/backend/access/index/genam.c86
-rw-r--r--src/backend/access/index/indexam.c48
3 files changed, 110 insertions, 67 deletions
diff --git a/src/backend/access/heap/tuptoaster.c b/src/backend/access/heap/tuptoaster.c
index bd92b9adfb..cf2edbf31e 100644
--- a/src/backend/access/heap/tuptoaster.c
+++ b/src/backend/access/heap/tuptoaster.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/access/heap/tuptoaster.c,v 1.85 2008/03/26 21:10:37 alvherre Exp $
+ * $PostgreSQL: pgsql/src/backend/access/heap/tuptoaster.c,v 1.86 2008/04/12 23:14:21 tgl Exp $
*
*
* INTERFACE ROUTINES
@@ -1184,7 +1184,9 @@ toast_save_datum(Relation rel, Datum value,
toast_pointer.va_extsize = data_todo;
}
- toast_pointer.va_valueid = GetNewOidWithIndex(toastrel, toastidx);
+ toast_pointer.va_valueid = GetNewOidWithIndex(toastrel,
+ RelationGetRelid(toastidx),
+ (AttrNumber) 1);
toast_pointer.va_toastrelid = rel->rd_rel->reltoastrelid;
/*
@@ -1273,7 +1275,7 @@ toast_delete_datum(Relation rel, Datum value)
Relation toastrel;
Relation toastidx;
ScanKeyData toastkey;
- IndexScanDesc toastscan;
+ SysScanDesc toastscan;
HeapTuple toasttup;
if (!VARATT_IS_EXTERNAL(attr))
@@ -1289,8 +1291,7 @@ toast_delete_datum(Relation rel, Datum value)
toastidx = index_open(toastrel->rd_rel->reltoastidxid, RowExclusiveLock);
/*
- * Setup a scan key to fetch from the index by va_valueid (we don't
- * particularly care whether we see them in sequence or not)
+ * Setup a scan key to find chunks with matching va_valueid
*/
ScanKeyInit(&toastkey,
(AttrNumber) 1,
@@ -1298,11 +1299,13 @@ toast_delete_datum(Relation rel, Datum value)
ObjectIdGetDatum(toast_pointer.va_valueid));
/*
- * Find the chunks by index
+ * Find all the chunks. (We don't actually care whether we see them in
+ * sequence or not, but since we've already locked the index we might
+ * as well use systable_beginscan_ordered.)
*/
- toastscan = index_beginscan(toastrel, toastidx,
- SnapshotToast, 1, &toastkey);
- while ((toasttup = index_getnext(toastscan, ForwardScanDirection)) != NULL)
+ toastscan = systable_beginscan_ordered(toastrel, toastidx,
+ SnapshotToast, 1, &toastkey);
+ while ((toasttup = systable_getnext_ordered(toastscan, ForwardScanDirection)) != NULL)
{
/*
* Have a chunk, delete it
@@ -1313,7 +1316,7 @@ toast_delete_datum(Relation rel, Datum value)
/*
* End scan and close relations
*/
- index_endscan(toastscan);
+ systable_endscan_ordered(toastscan);
index_close(toastidx, RowExclusiveLock);
heap_close(toastrel, RowExclusiveLock);
}
@@ -1332,7 +1335,7 @@ toast_fetch_datum(struct varlena * attr)
Relation toastrel;
Relation toastidx;
ScanKeyData toastkey;
- IndexScanDesc toastscan;
+ SysScanDesc toastscan;
HeapTuple ttup;
TupleDesc toasttupDesc;
struct varlena *result;
@@ -1383,9 +1386,9 @@ toast_fetch_datum(struct varlena * attr)
*/
nextidx = 0;
- toastscan = index_beginscan(toastrel, toastidx,
- SnapshotToast, 1, &toastkey);
- while ((ttup = index_getnext(toastscan, ForwardScanDirection)) != NULL)
+ toastscan = systable_beginscan_ordered(toastrel, toastidx,
+ SnapshotToast, 1, &toastkey);
+ while ((ttup = systable_getnext_ordered(toastscan, ForwardScanDirection)) != NULL)
{
/*
* Have a chunk, extract the sequence number and the data
@@ -1464,7 +1467,7 @@ toast_fetch_datum(struct varlena * attr)
/*
* End scan and close relations
*/
- index_endscan(toastscan);
+ systable_endscan_ordered(toastscan);
index_close(toastidx, AccessShareLock);
heap_close(toastrel, AccessShareLock);
@@ -1485,7 +1488,7 @@ toast_fetch_datum_slice(struct varlena * attr, int32 sliceoffset, int32 length)
Relation toastidx;
ScanKeyData toastkey[3];
int nscankeys;
- IndexScanDesc toastscan;
+ SysScanDesc toastscan;
HeapTuple ttup;
TupleDesc toasttupDesc;
struct varlena *result;
@@ -1592,9 +1595,9 @@ toast_fetch_datum_slice(struct varlena * attr, int32 sliceoffset, int32 length)
* The index is on (valueid, chunkidx) so they will come in order
*/
nextidx = startchunk;
- toastscan = index_beginscan(toastrel, toastidx,
- SnapshotToast, nscankeys, toastkey);
- while ((ttup = index_getnext(toastscan, ForwardScanDirection)) != NULL)
+ toastscan = systable_beginscan_ordered(toastrel, toastidx,
+ SnapshotToast, nscankeys, toastkey);
+ while ((ttup = systable_getnext_ordered(toastscan, ForwardScanDirection)) != NULL)
{
/*
* Have a chunk, extract the sequence number and the data
@@ -1681,7 +1684,7 @@ toast_fetch_datum_slice(struct varlena * attr, int32 sliceoffset, int32 length)
/*
* End scan and close relations
*/
- index_endscan(toastscan);
+ systable_endscan_ordered(toastscan);
index_close(toastidx, AccessShareLock);
heap_close(toastrel, AccessShareLock);
diff --git a/src/backend/access/index/genam.c b/src/backend/access/index/genam.c
index 8877938322..cafb1e6867 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);
+}
diff --git a/src/backend/access/index/indexam.c b/src/backend/access/index/indexam.c
index d59f1529db..7a06d0074e 100644
--- a/src/backend/access/index/indexam.c
+++ b/src/backend/access/index/indexam.c
@@ -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,
@@ -635,45 +630,6 @@ index_getnext(IndexScanDesc scan, ScanDirection direction)
}
/* ----------------
- * 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
*
* Adds the TIDs of all heap tuples satisfying the scan keys to a bitmap.