Create new routines systable_beginscan_ordered, systable_getnext_ordered,
authorTom Lane
Sat, 12 Apr 2008 23:14:21 +0000 (23:14 +0000)
committerTom Lane
Sat, 12 Apr 2008 23:14:21 +0000 (23:14 +0000)
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.

src/backend/access/heap/tuptoaster.c
src/backend/access/index/genam.c
src/backend/access/index/indexam.c
src/backend/catalog/catalog.c
src/backend/storage/large_object/inv_api.c
src/backend/utils/cache/ts_cache.c
src/include/access/genam.h
src/include/access/relscan.h
src/include/catalog/catalog.h

index bd92b9adfbb245256248736c919a33c233895eec..cf2edbf31ee503ffd959ff8ef8b13ce04fbe8055 100644 (file)
@@ -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);
 
index 8877938322d5c83b8be4a4b4c38f7a02a5b04026..cafb1e6867aa1bcade2849c801c65370cc7dbf0c 100644 (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);
+}
index d59f1529db1c7033a5ccc6a7f8f99da6a9140f35..7a06d0074e8516b89e8a03ef8df675be18c02f99 100644 (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
  *
index b23c8b36ab361fd6b5617d353b8430af2d310d48..314b75a7b07d1631a343fd66cc1533c4471cf5b1 100644 (file)
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/catalog/catalog.c,v 1.74 2008/03/26 16:20:46 alvherre Exp $
+ *   $PostgreSQL: pgsql/src/backend/catalog/catalog.c,v 1.75 2008/04/12 23:14:21 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -312,9 +312,7 @@ IsSharedRelation(Oid relationId)
 Oid
 GetNewOid(Relation relation)
 {
-   Oid         newOid;
    Oid         oidIndex;
-   Relation    indexrel;
 
    /* If relation doesn't have OIDs at all, caller is confused */
    Assert(relation->rd_rel->relhasoids);
@@ -342,11 +340,7 @@ GetNewOid(Relation relation)
    }
 
    /* Otherwise, use the index to find a nonconflicting OID */
-   indexrel = index_open(oidIndex, AccessShareLock);
-   newOid = GetNewOidWithIndex(relation, indexrel);
-   index_close(indexrel, AccessShareLock);
-
-   return newOid;
+   return GetNewOidWithIndex(relation, oidIndex, ObjectIdAttributeNumber);
 }
 
 /*
@@ -357,16 +351,17 @@ GetNewOid(Relation relation)
  * an index that will not be recognized by RelationGetOidIndex: TOAST tables
  * and pg_largeobject have indexes that are usable, but have multiple columns
  * and are on ordinary columns rather than a true OID column.  This code
- * will work anyway, so long as the OID is the index's first column.
+ * will work anyway, so long as the OID is the index's first column.  The
+ * caller must pass in the actual heap attnum of the OID column, however.
  *
  * Caller must have a suitable lock on the relation.
  */
 Oid
-GetNewOidWithIndex(Relation relation, Relation indexrel)
+GetNewOidWithIndex(Relation relation, Oid indexId, AttrNumber oidcolumn)
 {
    Oid         newOid;
    SnapshotData SnapshotDirty;
-   IndexScanDesc scan;
+   SysScanDesc scan;
    ScanKeyData key;
    bool        collides;
 
@@ -380,17 +375,17 @@ GetNewOidWithIndex(Relation relation, Relation indexrel)
        newOid = GetNewObjectId();
 
        ScanKeyInit(&key,
-                   (AttrNumber) 1,
+                   oidcolumn,
                    BTEqualStrategyNumber, F_OIDEQ,
                    ObjectIdGetDatum(newOid));
 
        /* see notes above about using SnapshotDirty */
-       scan = index_beginscan(relation, indexrel,
-                              &SnapshotDirty, 1, &key);
+       scan = systable_beginscan(relation, indexId, true,
+                                 &SnapshotDirty, 1, &key);
 
-       collides = HeapTupleIsValid(index_getnext(scan, ForwardScanDirection));
+       collides = HeapTupleIsValid(systable_getnext(scan));
 
-       index_endscan(scan);
+       systable_endscan(scan);
    } while (collides);
 
    return newOid;
index 16ad2b0349524fcf5ba0c8d1c11098938c58a5fa..00fbfd89ed6d801f5d09fe0ff1c99edb8bfbf18a 100644 (file)
@@ -24,7 +24,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/storage/large_object/inv_api.c,v 1.131 2008/03/26 21:10:38 alvherre Exp $
+ *   $PostgreSQL: pgsql/src/backend/storage/large_object/inv_api.c,v 1.132 2008/04/12 23:14:21 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -201,7 +201,8 @@ inv_create(Oid lobjId)
    {
        open_lo_relation();
 
-       lobjId = GetNewOidWithIndex(lo_heap_r, lo_index_r);
+       lobjId = GetNewOidWithIndex(lo_heap_r, LargeObjectLOidPNIndexId,
+                                   Anum_pg_largeobject_loid);
    }
 
    /*
@@ -311,7 +312,7 @@ inv_getsize(LargeObjectDesc *obj_desc)
    bool        found = false;
    uint32      lastbyte = 0;
    ScanKeyData skey[1];
-   IndexScanDesc sd;
+   SysScanDesc sd;
    HeapTuple   tuple;
 
    Assert(PointerIsValid(obj_desc));
@@ -323,8 +324,8 @@ inv_getsize(LargeObjectDesc *obj_desc)
                BTEqualStrategyNumber, F_OIDEQ,
                ObjectIdGetDatum(obj_desc->id));
 
-   sd = index_beginscan(lo_heap_r, lo_index_r,
-                        obj_desc->snapshot, 1, skey);
+   sd = systable_beginscan_ordered(lo_heap_r, lo_index_r,
+                                   obj_desc->snapshot, 1, skey);
 
    /*
     * Because the pg_largeobject index is on both loid and pageno, but we
@@ -332,7 +333,7 @@ inv_getsize(LargeObjectDesc *obj_desc)
     * large object in reverse pageno order.  So, it's sufficient to examine
     * the first valid tuple (== last valid page).
     */
-   while ((tuple = index_getnext(sd, BackwardScanDirection)) != NULL)
+   while ((tuple = systable_getnext_ordered(sd, BackwardScanDirection)) != NULL)
    {
        Form_pg_largeobject data;
        bytea      *datafield;
@@ -356,7 +357,7 @@ inv_getsize(LargeObjectDesc *obj_desc)
        break;
    }
 
-   index_endscan(sd);
+   systable_endscan_ordered(sd);
 
    if (!found)
        ereport(ERROR,
@@ -415,7 +416,7 @@ inv_read(LargeObjectDesc *obj_desc, char *buf, int nbytes)
    int32       pageno = (int32) (obj_desc->offset / LOBLKSIZE);
    uint32      pageoff;
    ScanKeyData skey[2];
-   IndexScanDesc sd;
+   SysScanDesc sd;
    HeapTuple   tuple;
 
    Assert(PointerIsValid(obj_desc));
@@ -436,10 +437,10 @@ inv_read(LargeObjectDesc *obj_desc, char *buf, int nbytes)
                BTGreaterEqualStrategyNumber, F_INT4GE,
                Int32GetDatum(pageno));
 
-   sd = index_beginscan(lo_heap_r, lo_index_r,
-                        obj_desc->snapshot, 2, skey);
+   sd = systable_beginscan_ordered(lo_heap_r, lo_index_r,
+                                   obj_desc->snapshot, 2, skey);
 
-   while ((tuple = index_getnext(sd, ForwardScanDirection)) != NULL)
+   while ((tuple = systable_getnext_ordered(sd, ForwardScanDirection)) != NULL)
    {
        Form_pg_largeobject data;
        bytea      *datafield;
@@ -450,7 +451,7 @@ inv_read(LargeObjectDesc *obj_desc, char *buf, int nbytes)
        data = (Form_pg_largeobject) GETSTRUCT(tuple);
 
        /*
-        * We assume the indexscan will deliver pages in order.  However,
+        * We expect the indexscan will deliver pages in order.  However,
         * there may be missing pages if the LO contains unwritten "holes". We
         * want missing sections to read out as zeroes.
         */
@@ -495,7 +496,7 @@ inv_read(LargeObjectDesc *obj_desc, char *buf, int nbytes)
            break;
    }
 
-   index_endscan(sd);
+   systable_endscan_ordered(sd);
 
    return nread;
 }
@@ -509,7 +510,7 @@ inv_write(LargeObjectDesc *obj_desc, const char *buf, int nbytes)
    int         len;
    int32       pageno = (int32) (obj_desc->offset / LOBLKSIZE);
    ScanKeyData skey[2];
-   IndexScanDesc sd;
+   SysScanDesc sd;
    HeapTuple   oldtuple;
    Form_pg_largeobject olddata;
    bool        neednextpage;
@@ -555,8 +556,8 @@ inv_write(LargeObjectDesc *obj_desc, const char *buf, int nbytes)
                BTGreaterEqualStrategyNumber, F_INT4GE,
                Int32GetDatum(pageno));
 
-   sd = index_beginscan(lo_heap_r, lo_index_r,
-                        obj_desc->snapshot, 2, skey);
+   sd = systable_beginscan_ordered(lo_heap_r, lo_index_r,
+                                   obj_desc->snapshot, 2, skey);
 
    oldtuple = NULL;
    olddata = NULL;
@@ -565,12 +566,12 @@ inv_write(LargeObjectDesc *obj_desc, const char *buf, int nbytes)
    while (nwritten < nbytes)
    {
        /*
-        * If possible, get next pre-existing page of the LO.  We assume the
+        * If possible, get next pre-existing page of the LO.  We expect the
         * indexscan will deliver these in order --- but there may be holes.
         */
        if (neednextpage)
        {
-           if ((oldtuple = index_getnext(sd, ForwardScanDirection)) != NULL)
+           if ((oldtuple = systable_getnext_ordered(sd, ForwardScanDirection)) != NULL)
            {
                if (HeapTupleHasNulls(oldtuple))        /* paranoia */
                    elog(ERROR, "null field found in pg_largeobject");
@@ -685,7 +686,7 @@ inv_write(LargeObjectDesc *obj_desc, const char *buf, int nbytes)
        pageno++;
    }
 
-   index_endscan(sd);
+   systable_endscan_ordered(sd);
 
    CatalogCloseIndexes(indstate);
 
@@ -704,7 +705,7 @@ inv_truncate(LargeObjectDesc *obj_desc, int len)
    int32       pageno = (int32) (len / LOBLKSIZE);
    int         off;
    ScanKeyData skey[2];
-   IndexScanDesc sd;
+   SysScanDesc sd;
    HeapTuple   oldtuple;
    Form_pg_largeobject olddata;
    struct
@@ -743,15 +744,15 @@ inv_truncate(LargeObjectDesc *obj_desc, int len)
                BTGreaterEqualStrategyNumber, F_INT4GE,
                Int32GetDatum(pageno));
 
-   sd = index_beginscan(lo_heap_r, lo_index_r,
-                        obj_desc->snapshot, 2, skey);
+   sd = systable_beginscan_ordered(lo_heap_r, lo_index_r,
+                                   obj_desc->snapshot, 2, skey);
 
    /*
     * If possible, get the page the truncation point is in. The truncation
     * point may be beyond the end of the LO or in a hole.
     */
    olddata = NULL;
-   if ((oldtuple = index_getnext(sd, ForwardScanDirection)) != NULL)
+   if ((oldtuple = systable_getnext_ordered(sd, ForwardScanDirection)) != NULL)
    {
        if (HeapTupleHasNulls(oldtuple))        /* paranoia */
            elog(ERROR, "null field found in pg_largeobject");
@@ -846,12 +847,12 @@ inv_truncate(LargeObjectDesc *obj_desc, int len)
    /*
     * Delete any pages after the truncation point
     */
-   while ((oldtuple = index_getnext(sd, ForwardScanDirection)) != NULL)
+   while ((oldtuple = systable_getnext_ordered(sd, ForwardScanDirection)) != NULL)
    {
        simple_heap_delete(lo_heap_r, &oldtuple->t_self);
    }
 
-   index_endscan(sd);
+   systable_endscan_ordered(sd);
 
    CatalogCloseIndexes(indstate);
 
index 08ae22528a42d8a29280011aa922175de14518d6..81ff577125eb607d684f179024ec7358e6c4a88f 100644 (file)
@@ -20,7 +20,7 @@
  * Copyright (c) 2006-2008, PostgreSQL Global Development Group
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/utils/cache/ts_cache.c,v 1.6 2008/03/26 21:10:39 alvherre Exp $
+ *   $PostgreSQL: pgsql/src/backend/utils/cache/ts_cache.c,v 1.7 2008/04/12 23:14:21 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -419,7 +419,7 @@ lookup_ts_config_cache(Oid cfgId)
        Relation    maprel;
        Relation    mapidx;
        ScanKeyData mapskey;
-       IndexScanDesc mapscan;
+       SysScanDesc mapscan;
        HeapTuple   maptup;
        ListDictionary maplists[MAXTOKENTYPE + 1];
        Oid         mapdicts[MAXDICTSPERTT];
@@ -488,9 +488,10 @@ lookup_ts_config_cache(Oid cfgId)
 
        maprel = heap_open(TSConfigMapRelationId, AccessShareLock);
        mapidx = index_open(TSConfigMapIndexId, AccessShareLock);
-       mapscan = index_beginscan(maprel, mapidx, SnapshotNow, 1, &mapskey);
+       mapscan = systable_beginscan_ordered(maprel, mapidx,
+                                            SnapshotNow, 1, &mapskey);
 
-       while ((maptup = index_getnext(mapscan, ForwardScanDirection)) != NULL)
+       while ((maptup = systable_getnext_ordered(mapscan, ForwardScanDirection)) != NULL)
        {
            Form_pg_ts_config_map cfgmap = (Form_pg_ts_config_map) GETSTRUCT(maptup);
            int         toktype = cfgmap->maptokentype;
@@ -524,7 +525,7 @@ lookup_ts_config_cache(Oid cfgId)
            }
        }
 
-       index_endscan(mapscan);
+       systable_endscan_ordered(mapscan);
        index_close(mapidx, AccessShareLock);
        heap_close(maprel, AccessShareLock);
 
index 57785913394b07398119ca5a2cbda69e77454a38..51ce605766554a5810c8ed151a013249edd82e13 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/access/genam.h,v 1.70 2008/04/10 22:25:25 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/access/genam.h,v 1.71 2008/04/12 23:14:21 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -108,8 +108,6 @@ extern void index_endscan(IndexScanDesc scan);
 extern void index_markpos(IndexScanDesc scan);
 extern void index_restrpos(IndexScanDesc scan);
 extern HeapTuple index_getnext(IndexScanDesc scan, ScanDirection direction);
-extern bool index_getnext_indexitem(IndexScanDesc scan,
-                       ScanDirection direction);
 extern int64 index_getbitmap(IndexScanDesc scan, TIDBitmap *bitmap);
 
 extern IndexBulkDeleteResult *index_bulk_delete(IndexVacuumInfo *info,
@@ -140,5 +138,12 @@ extern SysScanDesc systable_beginscan(Relation heapRelation,
                   int nkeys, ScanKey key);
 extern HeapTuple systable_getnext(SysScanDesc sysscan);
 extern void systable_endscan(SysScanDesc sysscan);
+extern SysScanDesc systable_beginscan_ordered(Relation heapRelation,
+                                             Relation indexRelation,
+                                             Snapshot snapshot,
+                                             int nkeys, ScanKey key);
+extern HeapTuple systable_getnext_ordered(SysScanDesc sysscan,
+                                         ScanDirection direction);
+extern void systable_endscan_ordered(SysScanDesc sysscan);
 
 #endif   /* GENAM_H */
index 677fd04e2c2d94c300d11dd46e0f0186350c5031..637b363f52855beb3750224a28a1d331237fef18 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/access/relscan.h,v 1.62 2008/04/10 22:25:25 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/access/relscan.h,v 1.63 2008/04/12 23:14:21 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -76,14 +76,12 @@ typedef struct IndexScanDescData
    /* index access method's private state */
    void       *opaque;         /* access-method-specific info */
 
-   /*
-    * xs_ctup/xs_cbuf are valid after a successful index_getnext. After
-    * index_getnext_indexitem, xs_ctup.t_self contains the heap tuple TID
-    * from the index entry, but its other fields are not valid.
-    */
+   /* xs_ctup/xs_cbuf are valid after a successful index_getnext */
    HeapTupleData xs_ctup;      /* current heap tuple, if any */
    Buffer      xs_cbuf;        /* current heap buffer in scan, if any */
    /* NB: if xs_cbuf is not InvalidBuffer, we hold a pin on that buffer */
+
+   /* state data for traversing HOT chains in index_getnext */
    TransactionId xs_prev_xmax; /* previous HOT chain member's XMAX, if any */
    OffsetNumber xs_next_hot;   /* next member of HOT chain, if any */
    bool        xs_hot_dead;    /* T if all members of HOT chain are dead */
index 8ab902563e951420ce31919d446f52172c5d6eb8..753926f14ea5d485fa9b93624b450b27778f0a3f 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/catalog/catalog.h,v 1.38 2008/01/01 19:45:56 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/catalog.h,v 1.39 2008/04/12 23:14:21 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -34,7 +34,8 @@ extern bool IsReservedName(const char *name);
 extern bool IsSharedRelation(Oid relationId);
 
 extern Oid GetNewOid(Relation relation);
-extern Oid GetNewOidWithIndex(Relation relation, Relation indexrel);
+extern Oid GetNewOidWithIndex(Relation relation, Oid indexId,
+                              AttrNumber oidcolumn);
 extern Oid GetNewRelFileNode(Oid reltablespace, bool relisshared,
                  Relation pg_class);