Get rid of pg_class.reltoastidxid.
authorFujii Masao <fujii@postgresql.org>
Wed, 3 Jul 2013 18:24:09 +0000 (03:24 +0900)
committerFujii Masao <fujii@postgresql.org>
Wed, 3 Jul 2013 18:24:09 +0000 (03:24 +0900)
Treat TOAST index just the same as normal one and get the OID
of TOAST index from pg_index but not pg_class.reltoastidxid.
This change allows us to handle multiple TOAST indexes, and
which is required infrastructure for upcoming
REINDEX CONCURRENTLY feature.

Patch by Michael Paquier, reviewed by Andres Freund and me.

21 files changed:
contrib/pg_upgrade/info.c
doc/src/sgml/catalogs.sgml
doc/src/sgml/diskusage.sgml
doc/src/sgml/monitoring.sgml
src/backend/access/heap/tuptoaster.c
src/backend/catalog/heap.c
src/backend/catalog/index.c
src/backend/catalog/system_views.sql
src/backend/commands/cluster.c
src/backend/commands/tablecmds.c
src/backend/rewrite/rewriteDefine.c
src/backend/utils/adt/dbsize.c
src/bin/pg_dump/pg_dump.c
src/include/access/tuptoaster.h
src/include/catalog/catversion.h
src/include/catalog/pg_class.h
src/test/regress/expected/oidjoins.out
src/test/regress/expected/rules.out
src/test/regress/sql/oidjoins.sql
src/test/regress/sql/rules.sql
src/tools/findoidjoins/README

index c381f112f14ecd463e9a4649de1bc96b683ef8fb..18daf1c32f71c320a4063f48cd76d2279a2ab6ae 100644 (file)
@@ -321,12 +321,19 @@ get_rel_infos(ClusterInfo *cluster, DbInfo *dbinfo)
                                                          "INSERT INTO info_rels "
                                                          "SELECT reltoastrelid "
                                                          "FROM info_rels i JOIN pg_catalog.pg_class c "
-                                                         "             ON i.reloid = c.oid"));
+                                                         "             ON i.reloid = c.oid "
+                                                         "             AND c.reltoastrelid != %u", InvalidOid));
        PQclear(executeQueryOrDie(conn,
                                                          "INSERT INTO info_rels "
-                                                         "SELECT reltoastidxid "
-                                                         "FROM info_rels i JOIN pg_catalog.pg_class c "
-                                                         "             ON i.reloid = c.oid"));
+                                                         "SELECT indexrelid "
+                                                         "FROM pg_index "
+                                                         "WHERE indisvalid "
+                                                         "    AND indrelid IN (SELECT reltoastrelid "
+                                                         "        FROM info_rels i "
+                                                         "            JOIN pg_catalog.pg_class c "
+                                                         "            ON i.reloid = c.oid "
+                                                         "            AND c.reltoastrelid != %u)",
+                                                         InvalidOid));
 
        snprintf(query, sizeof(query),
                         "SELECT c.oid, n.nspname, c.relname, "
index 09f7e40b29f29d1d1e119336907b01d8ebc84b50..67157829fdfc67d5f0e64b6e024712d4232c00a9 100644 (file)
       </entry>
      </row>
 
-     <row>
-      <entry><structfield>reltoastidxid</structfield></entry>
-      <entry><type>oid</type></entry>
-      <entry><literal><link linkend="catalog-pg-class"><structname>pg_class</structname></link>.oid</literal></entry>
-      <entry>
-       For a TOAST table, the OID of its index.  0 if not a TOAST table.
-      </entry>
-     </row>
-
      <row>
       <entry><structfield>relhasindex</structfield></entry>
       <entry><type>bool</type></entry>
index de1d0b4b00b6573773b891936053a99f3edd4e4c..461deb9dbad4f0697229894c4112575f888a9a61 100644 (file)
    stored. If the table has any columns with potentially-wide values,
    there also might be a <acronym>TOAST</> file associated with the table,
    which is used to store values too wide to fit comfortably in the main
-   table (see <xref linkend="storage-toast">).  There will be one index on the
-   <acronym>TOAST</> table, if present. There also might be indexes associated
-   with the base table.  Each table and index is stored in a separate disk
-   file &mdash; possibly more than one file, if the file would exceed one
-   gigabyte.  Naming conventions for these files are described in <xref
-   linkend="storage-file-layout">.
+   table (see <xref linkend="storage-toast">).  There will be one valid index
+   on the <acronym>TOAST</> table, if present. There also might be indexes
+   associated with the base table.  Each table and index is stored in a
+   separate disk file &mdash; possibly more than one file, if the file would
+   exceed one gigabyte.  Naming conventions for these files are described
+   in <xref linkend="storage-file-layout">.
   </para>
 
   <para>
@@ -44,7 +44,7 @@
 <programlisting>
 SELECT pg_relation_filepath(oid), relpages FROM pg_class WHERE relname = 'customer';
 
- pg_relation_filepath | relpages 
+ pg_relation_filepath | relpages
 ----------------------+----------
  base/16384/16806     |       60
 (1 row)
@@ -65,12 +65,12 @@ FROM pg_class,
       FROM pg_class
       WHERE relname = 'customer') AS ss
 WHERE oid = ss.reltoastrelid OR
-      oid = (SELECT reltoastidxid
-             FROM pg_class
-             WHERE oid = ss.reltoastrelid)
+      oid = (SELECT indexrelid
+             FROM pg_index
+             WHERE indrelid = ss.reltoastrelid)
 ORDER BY relname;
 
-       relname        | relpages 
+       relname        | relpages
 ----------------------+----------
  pg_toast_16806       |        0
  pg_toast_16806_index |        1
@@ -87,7 +87,7 @@ WHERE c.relname = 'customer' AND
       c2.oid = i.indexrelid
 ORDER BY c2.relname;
 
-       relname        | relpages 
+       relname        | relpages
 ----------------------+----------
  customer_id_indexdex |       26
 </programlisting>
@@ -101,7 +101,7 @@ SELECT relname, relpages
 FROM pg_class
 ORDER BY relpages DESC;
 
-       relname        | relpages 
+       relname        | relpages
 ----------------------+----------
  bigtable             |     3290
  customer             |     3144
index b37b6c301cb3c241514027c2c97bf782caafbb93..d38c009db3aafc475488e40a0158a2f8bfb2f401 100644 (file)
@@ -1163,12 +1163,12 @@ postgres: <replaceable>user</> <replaceable>database</> <replaceable>host</> <re
     <row>
      <entry><structfield>tidx_blks_read</></entry>
      <entry><type>bigint</></entry>
-     <entry>Number of disk blocks read from this table's TOAST table index (if any)</entry>
+     <entry>Number of disk blocks read from this table's TOAST table indexes (if any)</entry>
     </row>
     <row>
      <entry><structfield>tidx_blks_hit</></entry>
      <entry><type>bigint</></entry>
-     <entry>Number of buffer hits in this table's TOAST table index (if any)</entry>
+     <entry>Number of buffer hits in this table's TOAST table indexes (if any)</entry>
     </row>
    </tbody>
    </tgroup>
index 445a7ed9fbc202d9480773cd6934654a6ea74226..675bfcc81fe475229cd9352b1ac72967ada8775e 100644 (file)
@@ -78,6 +78,12 @@ static bool toastid_valueid_exists(Oid toastrelid, Oid valueid);
 static struct varlena *toast_fetch_datum(struct varlena * attr);
 static struct varlena *toast_fetch_datum_slice(struct varlena * attr,
                                                int32 sliceoffset, int32 length);
+static int toast_open_indexes(Relation toastrel,
+                                                         LOCKMODE lock,
+                                                         Relation **toastidxs,
+                                                         int *num_indexes);
+static void toast_close_indexes(Relation *toastidxs, int num_indexes,
+                                                               LOCKMODE lock);
 
 
 /* ----------
@@ -1286,6 +1292,39 @@ toast_compress_datum(Datum value)
 }
 
 
+/* ----------
+ * toast_get_valid_index
+ *
+ *     Get OID of valid index associated to given toast relation. A toast
+ *     relation can have only one valid index at the same time.
+ */
+Oid
+toast_get_valid_index(Oid toastoid, LOCKMODE lock)
+{
+       int                     num_indexes;
+       int                     validIndex;
+       Oid                     validIndexOid;
+       Relation   *toastidxs;
+       Relation        toastrel;
+
+       /* Open the toast relation */
+       toastrel = heap_open(toastoid, lock);
+
+       /* Look for the valid index of the toast relation */
+       validIndex = toast_open_indexes(toastrel,
+                                                                       lock,
+                                                                       &toastidxs,
+                                                                       &num_indexes);
+       validIndexOid = RelationGetRelid(toastidxs[validIndex]);
+
+       /* Close the toast relation and all its indexes */
+       toast_close_indexes(toastidxs, num_indexes, lock);
+       heap_close(toastrel, lock);
+
+       return validIndexOid;
+}
+
+
 /* ----------
  * toast_save_datum -
  *
@@ -1303,7 +1342,7 @@ toast_save_datum(Relation rel, Datum value,
                                 struct varlena * oldexternal, int options)
 {
        Relation        toastrel;
-       Relation        toastidx;
+       Relation   *toastidxs;
        HeapTuple       toasttup;
        TupleDesc       toasttupDesc;
        Datum           t_values[3];
@@ -1322,17 +1361,24 @@ toast_save_datum(Relation rel, Datum value,
        char       *data_p;
        int32           data_todo;
        Pointer         dval = DatumGetPointer(value);
+       int                     num_indexes;
+       int                     validIndex;
 
        Assert(!VARATT_IS_EXTERNAL(value));
 
        /*
-        * Open the toast relation and its index.  We can use the index to check
+        * Open the toast relation and its indexes.  We can use the index to check
         * uniqueness of the OID we assign to the toasted item, even though it has
         * additional columns besides OID.
         */
        toastrel = heap_open(rel->rd_rel->reltoastrelid, RowExclusiveLock);
        toasttupDesc = toastrel->rd_att;
-       toastidx = index_open(toastrel->rd_rel->reltoastidxid, RowExclusiveLock);
+
+       /* Open all the toast indexes and look for the valid */
+       validIndex = toast_open_indexes(toastrel,
+                                                                       RowExclusiveLock,
+                                                                       &toastidxs,
+                                                                       &num_indexes);
 
        /*
         * Get the data pointer and length, and compute va_rawsize and va_extsize.
@@ -1397,7 +1443,7 @@ toast_save_datum(Relation rel, Datum value,
                /* normal case: just choose an unused OID */
                toast_pointer.va_valueid =
                        GetNewOidWithIndex(toastrel,
-                                                          RelationGetRelid(toastidx),
+                                                          RelationGetRelid(toastidxs[validIndex]),
                                                           (AttrNumber) 1);
        }
        else
@@ -1451,7 +1497,7 @@ toast_save_datum(Relation rel, Datum value,
                        {
                                toast_pointer.va_valueid =
                                        GetNewOidWithIndex(toastrel,
-                                                                          RelationGetRelid(toastidx),
+                                                                          RelationGetRelid(toastidxs[validIndex]),
                                                                           (AttrNumber) 1);
                        } while (toastid_valueid_exists(rel->rd_toastoid,
                                                                                        toast_pointer.va_valueid));
@@ -1472,6 +1518,8 @@ toast_save_datum(Relation rel, Datum value,
         */
        while (data_todo > 0)
        {
+               int i;
+
                /*
                 * Calculate the size of this chunk
                 */
@@ -1490,16 +1538,22 @@ toast_save_datum(Relation rel, Datum value,
                /*
                 * Create the index entry.      We cheat a little here by not using
                 * FormIndexDatum: this relies on the knowledge that the index columns
-                * are the same as the initial columns of the table.
+                * are the same as the initial columns of the table for all the
+                * indexes.
                 *
                 * Note also that there had better not be any user-created index on
                 * the TOAST table, since we don't bother to update anything else.
                 */
-               index_insert(toastidx, t_values, t_isnull,
-                                        &(toasttup->t_self),
-                                        toastrel,
-                                        toastidx->rd_index->indisunique ?
-                                        UNIQUE_CHECK_YES : UNIQUE_CHECK_NO);
+               for (i = 0; i < num_indexes; i++)
+               {
+                       /* Only index relations marked as ready can updated */
+                       if (IndexIsReady(toastidxs[i]->rd_index))
+                               index_insert(toastidxs[i], t_values, t_isnull,
+                                                        &(toasttup->t_self),
+                                                        toastrel,
+                                                        toastidxs[i]->rd_index->indisunique ?
+                                                        UNIQUE_CHECK_YES : UNIQUE_CHECK_NO);
+               }
 
                /*
                 * Free memory
@@ -1514,9 +1568,9 @@ toast_save_datum(Relation rel, Datum value,
        }
 
        /*
-        * Done - close toast relation
+        * Done - close toast relation and its indexes
         */
-       index_close(toastidx, RowExclusiveLock);
+       toast_close_indexes(toastidxs, num_indexes, RowExclusiveLock);
        heap_close(toastrel, RowExclusiveLock);
 
        /*
@@ -1542,10 +1596,12 @@ toast_delete_datum(Relation rel, Datum value)
        struct varlena *attr = (struct varlena *) DatumGetPointer(value);
        struct varatt_external toast_pointer;
        Relation        toastrel;
-       Relation        toastidx;
+       Relation   *toastidxs;
        ScanKeyData toastkey;
        SysScanDesc toastscan;
        HeapTuple       toasttup;
+       int                     num_indexes;
+       int                     validIndex;
 
        if (!VARATT_IS_EXTERNAL_ONDISK(attr))
                return;
@@ -1554,10 +1610,15 @@ toast_delete_datum(Relation rel, Datum value)
        VARATT_EXTERNAL_GET_POINTER(toast_pointer, attr);
 
        /*
-        * Open the toast relation and its index
+        * Open the toast relation and its indexes
         */
        toastrel = heap_open(toast_pointer.va_toastrelid, RowExclusiveLock);
-       toastidx = index_open(toastrel->rd_rel->reltoastidxid, RowExclusiveLock);
+
+       /* Fetch valid relation used for process */
+       validIndex = toast_open_indexes(toastrel,
+                                                                       RowExclusiveLock,
+                                                                       &toastidxs,
+                                                                       &num_indexes);
 
        /*
         * Setup a scan key to find chunks with matching va_valueid
@@ -1572,7 +1633,7 @@ toast_delete_datum(Relation rel, Datum value)
         * sequence or not, but since we've already locked the index we might as
         * well use systable_beginscan_ordered.)
         */
-       toastscan = systable_beginscan_ordered(toastrel, toastidx,
+       toastscan = systable_beginscan_ordered(toastrel, toastidxs[validIndex],
                                                                                   SnapshotToast, 1, &toastkey);
        while ((toasttup = systable_getnext_ordered(toastscan, ForwardScanDirection)) != NULL)
        {
@@ -1586,7 +1647,7 @@ toast_delete_datum(Relation rel, Datum value)
         * End scan and close relations
         */
        systable_endscan_ordered(toastscan);
-       index_close(toastidx, RowExclusiveLock);
+       toast_close_indexes(toastidxs, num_indexes, RowExclusiveLock);
        heap_close(toastrel, RowExclusiveLock);
 }
 
@@ -1603,6 +1664,15 @@ toastrel_valueid_exists(Relation toastrel, Oid valueid)
        bool            result = false;
        ScanKeyData toastkey;
        SysScanDesc toastscan;
+       int                     num_indexes;
+       int                     validIndex;
+       Relation   *toastidxs;
+
+       /* Fetch a valid index relation */
+       validIndex = toast_open_indexes(toastrel,
+                                                                       RowExclusiveLock,
+                                                                       &toastidxs,
+                                                                       &num_indexes);
 
        /*
         * Setup a scan key to find chunks with matching va_valueid
@@ -1615,14 +1685,18 @@ toastrel_valueid_exists(Relation toastrel, Oid valueid)
        /*
         * Is there any such chunk?
         */
-       toastscan = systable_beginscan(toastrel, toastrel->rd_rel->reltoastidxid,
-                                                                  true, SnapshotToast, 1, &toastkey);
+       toastscan = systable_beginscan(toastrel,
+                                                  RelationGetRelid(toastidxs[validIndex]),
+                                                  true, SnapshotToast, 1, &toastkey);
 
        if (systable_getnext(toastscan) != NULL)
                result = true;
 
        systable_endscan(toastscan);
 
+       /* Clean up */
+       toast_close_indexes(toastidxs, num_indexes, RowExclusiveLock);
+
        return result;
 }
 
@@ -1659,7 +1733,7 @@ static struct varlena *
 toast_fetch_datum(struct varlena * attr)
 {
        Relation        toastrel;
-       Relation        toastidx;
+       Relation   *toastidxs;
        ScanKeyData toastkey;
        SysScanDesc toastscan;
        HeapTuple       ttup;
@@ -1674,6 +1748,8 @@ toast_fetch_datum(struct varlena * attr)
        bool            isnull;
        char       *chunkdata;
        int32           chunksize;
+       int                     num_indexes;
+       int                     validIndex;
 
        if (VARATT_IS_EXTERNAL_INDIRECT(attr))
                elog(ERROR, "shouldn't be called for indirect tuples");
@@ -1692,11 +1768,16 @@ toast_fetch_datum(struct varlena * attr)
                SET_VARSIZE(result, ressize + VARHDRSZ);
 
        /*
-        * Open the toast relation and its index
+        * Open the toast relation and its indexes
         */
        toastrel = heap_open(toast_pointer.va_toastrelid, AccessShareLock);
        toasttupDesc = toastrel->rd_att;
-       toastidx = index_open(toastrel->rd_rel->reltoastidxid, AccessShareLock);
+
+       /* Look for the valid index of the toast relation */
+       validIndex = toast_open_indexes(toastrel,
+                                                                       AccessShareLock,
+                                                                       &toastidxs,
+                                                                       &num_indexes);
 
        /*
         * Setup a scan key to fetch from the index by va_valueid
@@ -1715,7 +1796,7 @@ toast_fetch_datum(struct varlena * attr)
         */
        nextidx = 0;
 
-       toastscan = systable_beginscan_ordered(toastrel, toastidx,
+       toastscan = systable_beginscan_ordered(toastrel, toastidxs[validIndex],
                                                                                   SnapshotToast, 1, &toastkey);
        while ((ttup = systable_getnext_ordered(toastscan, ForwardScanDirection)) != NULL)
        {
@@ -1804,7 +1885,7 @@ toast_fetch_datum(struct varlena * attr)
         * End scan and close relations
         */
        systable_endscan_ordered(toastscan);
-       index_close(toastidx, AccessShareLock);
+       toast_close_indexes(toastidxs, num_indexes, AccessShareLock);
        heap_close(toastrel, AccessShareLock);
 
        return result;
@@ -1821,7 +1902,7 @@ static struct varlena *
 toast_fetch_datum_slice(struct varlena * attr, int32 sliceoffset, int32 length)
 {
        Relation        toastrel;
-       Relation        toastidx;
+       Relation   *toastidxs;
        ScanKeyData toastkey[3];
        int                     nscankeys;
        SysScanDesc toastscan;
@@ -1844,6 +1925,8 @@ toast_fetch_datum_slice(struct varlena * attr, int32 sliceoffset, int32 length)
        int32           chunksize;
        int32           chcpystrt;
        int32           chcpyend;
+       int                     num_indexes;
+       int                     validIndex;
 
        Assert(VARATT_IS_EXTERNAL_ONDISK(attr));
 
@@ -1886,11 +1969,16 @@ toast_fetch_datum_slice(struct varlena * attr, int32 sliceoffset, int32 length)
        endoffset = (sliceoffset + length - 1) % TOAST_MAX_CHUNK_SIZE;
 
        /*
-        * Open the toast relation and its index
+        * Open the toast relation and its indexes
         */
        toastrel = heap_open(toast_pointer.va_toastrelid, AccessShareLock);
        toasttupDesc = toastrel->rd_att;
-       toastidx = index_open(toastrel->rd_rel->reltoastidxid, AccessShareLock);
+
+       /* Look for the valid index of toast relation */
+       validIndex = toast_open_indexes(toastrel,
+                                                                       AccessShareLock,
+                                                                       &toastidxs,
+                                                                       &num_indexes);
 
        /*
         * Setup a scan key to fetch from the index. This is either two keys or
@@ -1931,7 +2019,7 @@ 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 = systable_beginscan_ordered(toastrel, toastidx,
+       toastscan = systable_beginscan_ordered(toastrel, toastidxs[validIndex],
                                                                                 SnapshotToast, nscankeys, toastkey);
        while ((ttup = systable_getnext_ordered(toastscan, ForwardScanDirection)) != NULL)
        {
@@ -2028,8 +2116,85 @@ toast_fetch_datum_slice(struct varlena * attr, int32 sliceoffset, int32 length)
         * End scan and close relations
         */
        systable_endscan_ordered(toastscan);
-       index_close(toastidx, AccessShareLock);
+       toast_close_indexes(toastidxs, num_indexes, AccessShareLock);
        heap_close(toastrel, AccessShareLock);
 
        return result;
 }
+
+/* ----------
+ * toast_open_indexes
+ *
+ *     Get an array of the indexes associated to the given toast relation
+ *     and return as well the position of the valid index used by the toast
+ *     relation in this array. It is the responsibility of the caller of this
+ *     function to close the indexes as well as free them.
+ */
+static int
+toast_open_indexes(Relation toastrel,
+                                  LOCKMODE lock,
+                                  Relation **toastidxs,
+                                  int *num_indexes)
+{
+       int                     i = 0;
+       int                     res = 0;
+       bool            found = false;
+       List       *indexlist;
+       ListCell   *lc;
+
+       /* Get index list of the toast relation */
+       indexlist = RelationGetIndexList(toastrel);
+       Assert(indexlist != NIL);
+
+       *num_indexes = list_length(indexlist);
+
+       /* Open all the index relations */
+       *toastidxs = (Relation *) palloc(*num_indexes * sizeof(Relation));
+       foreach(lc, indexlist)
+               (*toastidxs)[i++] = index_open(lfirst_oid(lc), lock);
+
+       /* Fetch the first valid index in list */
+       for (i = 0; i < *num_indexes; i++)
+       {
+               Relation toastidx = *toastidxs[i];
+               if (toastidx->rd_index->indisvalid)
+               {
+                       res = i;
+                       found = true;
+                       break;
+               }
+       }
+
+       /*
+        * Free index list, not necessary anymore as relations are opened
+        * and a valid index has been found.
+        */
+       list_free(indexlist);
+
+       /*
+        * The toast relation should have one valid index, so something is
+        * going wrong if there is nothing.
+        */
+       if (!found)
+               elog(ERROR, "no valid index found for toast relation with Oid %d",
+                        RelationGetRelid(toastrel));
+
+       return res;
+}
+
+/* ----------
+ * toast_close_indexes
+ *
+ *     Close an array of indexes for a toast relation and free it. This should
+ *     be called for a set of indexes opened previously with toast_open_indexes.
+ */
+static void
+toast_close_indexes(Relation *toastidxs, int num_indexes, LOCKMODE lock)
+{
+       int i;
+
+       /* Close relations and clean up things */
+       for (i = 0; i < num_indexes; i++)
+               index_close(toastidxs[i], lock);
+       pfree(toastidxs);
+}
index 4fd42ed1af50226c71acd958fba19216dfb1f878..f1cdef9e130ddcf42a0c306441edf1c5deef2101 100644 (file)
@@ -781,7 +781,6 @@ InsertPgClassTuple(Relation pg_class_desc,
        values[Anum_pg_class_reltuples - 1] = Float4GetDatum(rd_rel->reltuples);
        values[Anum_pg_class_relallvisible - 1] = Int32GetDatum(rd_rel->relallvisible);
        values[Anum_pg_class_reltoastrelid - 1] = ObjectIdGetDatum(rd_rel->reltoastrelid);
-       values[Anum_pg_class_reltoastidxid - 1] = ObjectIdGetDatum(rd_rel->reltoastidxid);
        values[Anum_pg_class_relhasindex - 1] = BoolGetDatum(rd_rel->relhasindex);
        values[Anum_pg_class_relisshared - 1] = BoolGetDatum(rd_rel->relisshared);
        values[Anum_pg_class_relpersistence - 1] = CharGetDatum(rd_rel->relpersistence);
index ca0c672c38141f19a998df1becce6a9565b7b6b7..8525cb9ec83877348647d01ff679ad8105ba192d 100644 (file)
@@ -103,7 +103,7 @@ static void UpdateIndexRelation(Oid indexoid, Oid heapoid,
                                        bool isvalid);
 static void index_update_stats(Relation rel,
                                   bool hasindex, bool isprimary,
-                                  Oid reltoastidxid, double reltuples);
+                                  double reltuples);
 static void IndexCheckExclusion(Relation heapRelation,
                                        Relation indexRelation,
                                        IndexInfo *indexInfo);
@@ -1072,7 +1072,6 @@ index_create(Relation heapRelation,
                index_update_stats(heapRelation,
                                                   true,
                                                   isprimary,
-                                                  InvalidOid,
                                                   -1.0);
                /* Make the above update visible */
                CommandCounterIncrement();
@@ -1254,7 +1253,6 @@ index_constraint_create(Relation heapRelation,
                index_update_stats(heapRelation,
                                                   true,
                                                   true,
-                                                  InvalidOid,
                                                   -1.0);
 
        /*
@@ -1764,8 +1762,6 @@ FormIndexDatum(IndexInfo *indexInfo,
  *
  * hasindex: set relhasindex to this value
  * isprimary: if true, set relhaspkey true; else no change
- * reltoastidxid: if not InvalidOid, set reltoastidxid to this value;
- *             else no change
  * reltuples: if >= 0, set reltuples to this value; else no change
  *
  * If reltuples >= 0, relpages and relallvisible are also updated (using
@@ -1781,8 +1777,9 @@ FormIndexDatum(IndexInfo *indexInfo,
  */
 static void
 index_update_stats(Relation rel,
-                                  bool hasindex, bool isprimary,
-                                  Oid reltoastidxid, double reltuples)
+                                  bool hasindex,
+                                  bool isprimary,
+                                  double reltuples)
 {
        Oid                     relid = RelationGetRelid(rel);
        Relation        pg_class;
@@ -1876,15 +1873,6 @@ index_update_stats(Relation rel,
                        dirty = true;
                }
        }
-       if (OidIsValid(reltoastidxid))
-       {
-               Assert(rd_rel->relkind == RELKIND_TOASTVALUE);
-               if (rd_rel->reltoastidxid != reltoastidxid)
-               {
-                       rd_rel->reltoastidxid = reltoastidxid;
-                       dirty = true;
-               }
-       }
 
        if (reltuples >= 0)
        {
@@ -2072,14 +2060,11 @@ index_build(Relation heapRelation,
        index_update_stats(heapRelation,
                                           true,
                                           isprimary,
-                                          (heapRelation->rd_rel->relkind == RELKIND_TOASTVALUE) ?
-                                          RelationGetRelid(indexRelation) : InvalidOid,
                                           stats->heap_tuples);
 
        index_update_stats(indexRelation,
                                           false,
                                           false,
-                                          InvalidOid,
                                           stats->index_tuples);
 
        /* Make the updated catalog row versions visible */
index 81d7c4fec8c57de6acee36e2f14b21532588dd3f..d3086f43dd66ca6bee2ab849f069b36af33b7625 100644 (file)
@@ -473,16 +473,16 @@ CREATE VIEW pg_statio_all_tables AS
             pg_stat_get_blocks_fetched(T.oid) -
                     pg_stat_get_blocks_hit(T.oid) AS toast_blks_read,
             pg_stat_get_blocks_hit(T.oid) AS toast_blks_hit,
-            pg_stat_get_blocks_fetched(X.oid) -
-                    pg_stat_get_blocks_hit(X.oid) AS tidx_blks_read,
-            pg_stat_get_blocks_hit(X.oid) AS tidx_blks_hit
+            sum(pg_stat_get_blocks_fetched(X.indexrelid) -
+                    pg_stat_get_blocks_hit(X.indexrelid))::bigint AS tidx_blks_read,
+            sum(pg_stat_get_blocks_hit(X.indexrelid))::bigint AS tidx_blks_hit
     FROM pg_class C LEFT JOIN
             pg_index I ON C.oid = I.indrelid LEFT JOIN
             pg_class T ON C.reltoastrelid = T.oid LEFT JOIN
-            pg_class X ON T.reltoastidxid = X.oid
+            pg_index X ON T.oid = X.indrelid
             LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
     WHERE C.relkind IN ('r', 't', 'm')
-    GROUP BY C.oid, N.nspname, C.relname, T.oid, X.oid;
+    GROUP BY C.oid, N.nspname, C.relname, T.oid, X.indrelid;
 
 CREATE VIEW pg_statio_sys_tables AS
     SELECT * FROM pg_statio_all_tables
index f23730c26f74a114150f469b41a778e5bda5dd97..686770f881e4e5f28feb3a7b89765c2859f2dfdb 100644 (file)
@@ -21,6 +21,7 @@
 #include "access/relscan.h"
 #include "access/rewriteheap.h"
 #include "access/transam.h"
+#include "access/tuptoaster.h"
 #include "access/xact.h"
 #include "catalog/catalog.h"
 #include "catalog/dependency.h"
@@ -1177,8 +1178,6 @@ swap_relation_files(Oid r1, Oid r2, bool target_is_pg_class,
                        swaptemp = relform1->reltoastrelid;
                        relform1->reltoastrelid = relform2->reltoastrelid;
                        relform2->reltoastrelid = swaptemp;
-
-                       /* we should NOT swap reltoastidxid */
                }
        }
        else
@@ -1398,18 +1397,30 @@ swap_relation_files(Oid r1, Oid r2, bool target_is_pg_class,
 
        /*
         * If we're swapping two toast tables by content, do the same for their
-        * indexes.
+        * valid index. The swap can actually be safely done only if the relations
+        * have indexes.
         */
        if (swap_toast_by_content &&
-               relform1->reltoastidxid && relform2->reltoastidxid)
-               swap_relation_files(relform1->reltoastidxid,
-                                                       relform2->reltoastidxid,
+               relform1->relkind == RELKIND_TOASTVALUE &&
+               relform2->relkind == RELKIND_TOASTVALUE)
+       {
+               Oid                     toastIndex1, toastIndex2;
+
+               /* Get valid index for each relation */
+               toastIndex1 = toast_get_valid_index(r1,
+                                                                                       AccessExclusiveLock);
+               toastIndex2 = toast_get_valid_index(r2,
+                                                                                       AccessExclusiveLock);
+
+               swap_relation_files(toastIndex1,
+                                                       toastIndex2,
                                                        target_is_pg_class,
                                                        swap_toast_by_content,
                                                        is_internal,
                                                        InvalidTransactionId,
                                                        InvalidMultiXactId,
                                                        mapped_tables);
+       }
 
        /* Clean up. */
        heap_freetuple(reltup1);
@@ -1533,14 +1544,12 @@ finish_heap_swap(Oid OIDOldHeap, Oid OIDNewHeap,
                newrel = heap_open(OIDOldHeap, NoLock);
                if (OidIsValid(newrel->rd_rel->reltoastrelid))
                {
-                       Relation        toastrel;
                        Oid                     toastidx;
                        char            NewToastName[NAMEDATALEN];
 
-                       toastrel = relation_open(newrel->rd_rel->reltoastrelid,
-                                                                        AccessShareLock);
-                       toastidx = toastrel->rd_rel->reltoastidxid;
-                       relation_close(toastrel, AccessShareLock);
+                       /* Get the associated valid index to be renamed */
+                       toastidx = toast_get_valid_index(newrel->rd_rel->reltoastrelid,
+                                                                                        AccessShareLock);
 
                        /* rename the toast table ... */
                        snprintf(NewToastName, NAMEDATALEN, "pg_toast_%u",
@@ -1548,9 +1557,10 @@ finish_heap_swap(Oid OIDOldHeap, Oid OIDNewHeap,
                        RenameRelationInternal(newrel->rd_rel->reltoastrelid,
                                                                   NewToastName, true);
 
-                       /* ... and its index too */
+                       /* ... and its valid index too. */
                        snprintf(NewToastName, NAMEDATALEN, "pg_toast_%u_index",
                                         OIDOldHeap);
+
                        RenameRelationInternal(toastidx,
                                                                   NewToastName, true);
                }
index 6a7aa44ccc66e9302edea0f00947ec2696802b5a..6708725d696da5f0391600ff099888e2cc972550 100644 (file)
@@ -8878,7 +8878,6 @@ ATExecSetTableSpace(Oid tableOid, Oid newTableSpace, LOCKMODE lockmode)
        Relation        rel;
        Oid                     oldTableSpace;
        Oid                     reltoastrelid;
-       Oid                     reltoastidxid;
        Oid                     newrelfilenode;
        RelFileNode newrnode;
        SMgrRelation dstrel;
@@ -8886,6 +8885,8 @@ ATExecSetTableSpace(Oid tableOid, Oid newTableSpace, LOCKMODE lockmode)
        HeapTuple       tuple;
        Form_pg_class rd_rel;
        ForkNumber      forkNum;
+       List       *reltoastidxids = NIL;
+       ListCell   *lc;
 
        /*
         * Need lock here in case we are recursing to toast table or index
@@ -8932,7 +8933,13 @@ ATExecSetTableSpace(Oid tableOid, Oid newTableSpace, LOCKMODE lockmode)
                                 errmsg("cannot move temporary tables of other sessions")));
 
        reltoastrelid = rel->rd_rel->reltoastrelid;
-       reltoastidxid = rel->rd_rel->reltoastidxid;
+       /* Fetch the list of indexes on toast relation if necessary */
+       if (OidIsValid(reltoastrelid))
+       {
+               Relation toastRel = relation_open(reltoastrelid, lockmode);
+               reltoastidxids = RelationGetIndexList(toastRel);
+               relation_close(toastRel, lockmode);
+       }
 
        /* Get a modifiable copy of the relation's pg_class row */
        pg_class = heap_open(RelationRelationId, RowExclusiveLock);
@@ -9010,11 +9017,14 @@ ATExecSetTableSpace(Oid tableOid, Oid newTableSpace, LOCKMODE lockmode)
        /* Make sure the reltablespace change is visible */
        CommandCounterIncrement();
 
-       /* Move associated toast relation and/or index, too */
+       /* Move associated toast relation and/or indexes, too */
        if (OidIsValid(reltoastrelid))
                ATExecSetTableSpace(reltoastrelid, newTableSpace, lockmode);
-       if (OidIsValid(reltoastidxid))
-               ATExecSetTableSpace(reltoastidxid, newTableSpace, lockmode);
+       foreach(lc, reltoastidxids)
+               ATExecSetTableSpace(lfirst_oid(lc), newTableSpace, lockmode);
+
+       /* Clean up */
+       list_free(reltoastidxids);
 }
 
 /*
index 3157aba330d9a21e77f602af85d328b9d153f6cb..92396b39bd38dca9073ffd0df131aa31b3243909 100644 (file)
@@ -579,8 +579,8 @@ DefineQueryRewrite(char *rulename,
 
                /*
                 * Fix pg_class entry to look like a normal view's, including setting
-                * the correct relkind and removal of reltoastrelid/reltoastidxid of
-                * the toast table we potentially removed above.
+                * the correct relkind and removal of reltoastrelid of the toast table
+                * we potentially removed above.
                 */
                classTup = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(event_relid));
                if (!HeapTupleIsValid(classTup))
@@ -592,7 +592,6 @@ DefineQueryRewrite(char *rulename,
                classForm->reltuples = 0;
                classForm->relallvisible = 0;
                classForm->reltoastrelid = InvalidOid;
-               classForm->reltoastidxid = InvalidOid;
                classForm->relhasindex = false;
                classForm->relkind = RELKIND_VIEW;
                classForm->relhasoids = false;
index 5ddeffe4820fe136900adc9920acd46443b5e1bc..34482abee3e9aea297a891def7e5d0a1f6464858 100644 (file)
@@ -332,7 +332,7 @@ pg_relation_size(PG_FUNCTION_ARGS)
 }
 
 /*
- * Calculate total on-disk size of a TOAST relation, including its index.
+ * Calculate total on-disk size of a TOAST relation, including its indexes.
  * Must not be applied to non-TOAST relations.
  */
 static int64
@@ -340,8 +340,9 @@ calculate_toast_table_size(Oid toastrelid)
 {
        int64           size = 0;
        Relation        toastRel;
-       Relation        toastIdxRel;
        ForkNumber      forkNum;
+       ListCell   *lc;
+       List       *indexlist;
 
        toastRel = relation_open(toastrelid, AccessShareLock);
 
@@ -351,12 +352,21 @@ calculate_toast_table_size(Oid toastrelid)
                                                                                toastRel->rd_backend, forkNum);
 
        /* toast index size, including FSM and VM size */
-       toastIdxRel = relation_open(toastRel->rd_rel->reltoastidxid, AccessShareLock);
-       for (forkNum = 0; forkNum <= MAX_FORKNUM; forkNum++)
-               size += calculate_relation_size(&(toastIdxRel->rd_node),
-                                                                               toastIdxRel->rd_backend, forkNum);
+       indexlist = RelationGetIndexList(toastRel);
 
-       relation_close(toastIdxRel, AccessShareLock);
+       /* Size is calculated using all the indexes available */
+       foreach(lc, indexlist)
+       {
+               Relation        toastIdxRel;
+               toastIdxRel = relation_open(lfirst_oid(lc),
+                                                                       AccessShareLock);
+               for (forkNum = 0; forkNum <= MAX_FORKNUM; forkNum++)
+                       size += calculate_relation_size(&(toastIdxRel->rd_node),
+                                                                                       toastIdxRel->rd_backend, forkNum);
+
+               relation_close(toastIdxRel, AccessShareLock);
+       }
+       list_free(indexlist);
        relation_close(toastRel, AccessShareLock);
 
        return size;
index 9ee9ea2bafa8789e7cd9c66849f404d934822720..f40961ffceae37b19a5ba93760f207a15e79716d 100644 (file)
@@ -2778,19 +2778,19 @@ binary_upgrade_set_pg_class_oids(Archive *fout,
        PQExpBuffer upgrade_query = createPQExpBuffer();
        PGresult   *upgrade_res;
        Oid                     pg_class_reltoastrelid;
-       Oid                     pg_class_reltoastidxid;
+       Oid                     pg_index_indexrelid;
 
        appendPQExpBuffer(upgrade_query,
-                                         "SELECT c.reltoastrelid, t.reltoastidxid "
+                                         "SELECT c.reltoastrelid, i.indexrelid "
                                          "FROM pg_catalog.pg_class c LEFT JOIN "
-                                         "pg_catalog.pg_class t ON (c.reltoastrelid = t.oid) "
+                                         "pg_catalog.pg_index i ON (c.reltoastrelid = i.indrelid AND i.indisvalid) "
                                          "WHERE c.oid = '%u'::pg_catalog.oid;",
                                          pg_class_oid);
 
        upgrade_res = ExecuteSqlQueryForSingleRow(fout, upgrade_query->data);
 
        pg_class_reltoastrelid = atooid(PQgetvalue(upgrade_res, 0, PQfnumber(upgrade_res, "reltoastrelid")));
-       pg_class_reltoastidxid = atooid(PQgetvalue(upgrade_res, 0, PQfnumber(upgrade_res, "reltoastidxid")));
+       pg_index_indexrelid = atooid(PQgetvalue(upgrade_res, 0, PQfnumber(upgrade_res, "indexrelid")));
 
        appendPQExpBuffer(upgrade_buffer,
                                   "\n-- For binary upgrade, must preserve pg_class oids\n");
@@ -2819,7 +2819,7 @@ binary_upgrade_set_pg_class_oids(Archive *fout,
                        /* every toast table has an index */
                        appendPQExpBuffer(upgrade_buffer,
                                                          "SELECT binary_upgrade.set_next_index_pg_class_oid('%u'::pg_catalog.oid);\n",
-                                                         pg_class_reltoastidxid);
+                                                         pg_index_indexrelid);
                }
        }
        else
@@ -13126,7 +13126,7 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
                 * attislocal correctly, plus fix up any inherited CHECK constraints.
                 * Analogously, we set up typed tables using ALTER TABLE / OF here.
                 */
-               if (binary_upgrade && (tbinfo->relkind == RELKIND_RELATION || 
+               if (binary_upgrade && (tbinfo->relkind == RELKIND_RELATION ||
                                                           tbinfo->relkind == RELKIND_FOREIGN_TABLE) )
                {
                        for (j = 0; j < tbinfo->numatts; j++)
@@ -13151,7 +13151,7 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
                                        else
                                                appendPQExpBuffer(q, "ALTER FOREIGN TABLE %s ",
                                                                                  fmtId(tbinfo->dobj.name));
-                                               
+
                                        appendPQExpBuffer(q, "DROP COLUMN %s;\n",
                                                                          fmtId(tbinfo->attnames[j]));
                                }
index d0c17fde036103dd7229f1cebad0e28e52361e9c..b4e0242c14e8129d702896fb999cd331aa2ebb18 100644 (file)
@@ -15,6 +15,7 @@
 
 #include "access/htup_details.h"
 #include "utils/relcache.h"
+#include "storage/lock.h"
 
 /*
  * This enables de-toasting of index entries.  Needed until VACUUM is
@@ -193,4 +194,12 @@ extern Size toast_raw_datum_size(Datum value);
  */
 extern Size toast_datum_size(Datum value);
 
+/* ----------
+ * toast_get_valid_index -
+ *
+ *     Return OID of valid index associated to a toast relation
+ * ----------
+ */
+extern Oid toast_get_valid_index(Oid toastoid, LOCKMODE lock);
+
 #endif   /* TUPTOASTER_H */
index d46fe9ede373fe60b715e0dd1f11a8057da24f72..9358e955475ab6a08abb523d9d42c6d30757e40d 100644 (file)
@@ -53,6 +53,6 @@
  */
 
 /*                                                     yyyymmddN */
-#define CATALOG_VERSION_NO     201306121
+#define CATALOG_VERSION_NO     201307031
 
 #endif
index 2225787e406ab00062d6d82f4eb67544c7e6c065..49c4f6f136bd26fa4fab2c5838ac8c137907ddd6 100644 (file)
@@ -48,7 +48,6 @@ CATALOG(pg_class,1259) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83) BKI_SCHEMA_MACRO
        int32           relallvisible;  /* # of all-visible blocks (not always
                                                                 * up-to-date) */
        Oid                     reltoastrelid;  /* OID of toast table; 0 if none */
-       Oid                     reltoastidxid;  /* if toast table, OID of chunk_id index */
        bool            relhasindex;    /* T if has (or has had) any indexes */
        bool            relisshared;    /* T if shared across databases */
        char            relpersistence; /* see RELPERSISTENCE_xxx constants below */
@@ -94,7 +93,7 @@ typedef FormData_pg_class *Form_pg_class;
  * ----------------
  */
 
-#define Natts_pg_class                                 29
+#define Natts_pg_class                                 28
 #define Anum_pg_class_relname                  1
 #define Anum_pg_class_relnamespace             2
 #define Anum_pg_class_reltype                  3
@@ -107,23 +106,22 @@ typedef FormData_pg_class *Form_pg_class;
 #define Anum_pg_class_reltuples                        10
 #define Anum_pg_class_relallvisible            11
 #define Anum_pg_class_reltoastrelid            12
-#define Anum_pg_class_reltoastidxid            13
-#define Anum_pg_class_relhasindex              14
-#define Anum_pg_class_relisshared              15
-#define Anum_pg_class_relpersistence   16
-#define Anum_pg_class_relkind                  17
-#define Anum_pg_class_relnatts                 18
-#define Anum_pg_class_relchecks                        19
-#define Anum_pg_class_relhasoids               20
-#define Anum_pg_class_relhaspkey               21
-#define Anum_pg_class_relhasrules              22
-#define Anum_pg_class_relhastriggers   23
-#define Anum_pg_class_relhassubclass   24
-#define Anum_pg_class_relispopulated   25
-#define Anum_pg_class_relfrozenxid             26
-#define Anum_pg_class_relminmxid               27
-#define Anum_pg_class_relacl                   28
-#define Anum_pg_class_reloptions               29
+#define Anum_pg_class_relhasindex              13
+#define Anum_pg_class_relisshared              14
+#define Anum_pg_class_relpersistence   15
+#define Anum_pg_class_relkind                  16
+#define Anum_pg_class_relnatts                 17
+#define Anum_pg_class_relchecks                        18
+#define Anum_pg_class_relhasoids               19
+#define Anum_pg_class_relhaspkey               20
+#define Anum_pg_class_relhasrules              21
+#define Anum_pg_class_relhastriggers   22
+#define Anum_pg_class_relhassubclass   23
+#define Anum_pg_class_relispopulated   24
+#define Anum_pg_class_relfrozenxid             25
+#define Anum_pg_class_relminmxid               26
+#define Anum_pg_class_relacl                   27
+#define Anum_pg_class_reloptions               28
 
 /* ----------------
  *             initial contents of pg_class
@@ -138,13 +136,13 @@ typedef FormData_pg_class *Form_pg_class;
  * Note: "3" in the relfrozenxid column stands for FirstNormalTransactionId;
  * similarly, "1" in relminmxid stands for FirstMultiXactId
  */
-DATA(insert OID = 1247 (  pg_type              PGNSP 71 0 PGUID 0 0 0 0 0 0 0 f f p r 30 0 t f f f f t 3 1 _null_ _null_ ));
+DATA(insert OID = 1247 (  pg_type              PGNSP 71 0 PGUID 0 0 0 0 0 0 0 f f p r 30 0 t f f f f t 3 1 _null_ _null_ ));
 DESCR("");
-DATA(insert OID = 1249 (  pg_attribute PGNSP 75 0 PGUID 0 0 0 0 0 0 0 f f p r 21 0 f f f f f t 3 1 _null_ _null_ ));
+DATA(insert OID = 1249 (  pg_attribute PGNSP 75 0 PGUID 0 0 0 0 0 0 0 f f p r 21 0 f f f f f t 3 1 _null_ _null_ ));
 DESCR("");
-DATA(insert OID = 1255 (  pg_proc              PGNSP 81 0 PGUID 0 0 0 0 0 0 0 f f p r 27 0 t f f f f t 3 1 _null_ _null_ ));
+DATA(insert OID = 1255 (  pg_proc              PGNSP 81 0 PGUID 0 0 0 0 0 0 0 f f p r 27 0 t f f f f t 3 1 _null_ _null_ ));
 DESCR("");
-DATA(insert OID = 1259 (  pg_class             PGNSP 83 0 PGUID 0 0 0 0 0 0 0 0 f f p r 29 0 t f f f f t 3 1 _null_ _null_ ));
+DATA(insert OID = 1259 (  pg_class             PGNSP 83 0 PGUID 0 0 0 0 0 0 0 f f p r 28 0 t f f f f t 3 1 _null_ _null_ ));
 DESCR("");
 
 
index 06ed85677aed366249ac3d717a2b89da25bba4c0..6c5cb5a8737ae2c8c45ba5a30a100eae86c7d1cb 100644 (file)
@@ -353,14 +353,6 @@ WHERE      reltoastrelid != 0 AND
 ------+---------------
 (0 rows)
 
-SELECT ctid, reltoastidxid
-FROM   pg_catalog.pg_class fk
-WHERE  reltoastidxid != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_class pk WHERE pk.oid = fk.reltoastidxid);
- ctid | reltoastidxid 
-------+---------------
-(0 rows)
-
 SELECT ctid, collnamespace
 FROM   pg_catalog.pg_collation fk
 WHERE  collnamespace != 0 AND
index 57ae8427ecd577b5d2f2da6ffe279decce3fec30..4b182e7f5414d86f46c57abf032b9a916002be8f 100644 (file)
@@ -1852,15 +1852,15 @@ SELECT viewname, definition FROM pg_views WHERE schemaname <> 'information_schem
                                  |     (sum(pg_stat_get_blocks_hit(i.indexrelid)))::bigint AS idx_blks_hit,                                                                                                                                       +
                                  |     (pg_stat_get_blocks_fetched(t.oid) - pg_stat_get_blocks_hit(t.oid)) AS toast_blks_read,                                                                                                                    +
                                  |     pg_stat_get_blocks_hit(t.oid) AS toast_blks_hit,                                                                                                                                                           +
-                                 |     (pg_stat_get_blocks_fetched(x.oid) - pg_stat_get_blocks_hit(x.oid)) AS tidx_blks_read,                                                                                                                     +
-                                 |     pg_stat_get_blocks_hit(x.oid) AS tidx_blks_hit                                                                                                                                                             +
+                                 |     (sum((pg_stat_get_blocks_fetched(x.indexrelid) - pg_stat_get_blocks_hit(x.indexrelid))))::bigint AS tidx_blks_read,                                                                                        +
+                                 |     (sum(pg_stat_get_blocks_hit(x.indexrelid)))::bigint AS tidx_blks_hit                                                                                                                                       +
                                  |    FROM ((((pg_class c                                                                                                                                                                                         +
                                  |    LEFT JOIN pg_index i ON ((c.oid = i.indrelid)))                                                                                                                                                             +
                                  |    LEFT JOIN pg_class t ON ((c.reltoastrelid = t.oid)))                                                                                                                                                        +
-                                 |    LEFT JOIN pg_class x ON ((t.reltoastidxid = x.oid)))                                                                                                                                                        +
+                                 |    LEFT JOIN pg_index x ON ((t.oid = x.indrelid)))                                                                                                                                                             +
                                  |    LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))                                                                                                                                                     +
                                  |   WHERE (c.relkind = ANY (ARRAY['r'::"char", 't'::"char", 'm'::"char"]))                                                                                                                                       +
-                                 |   GROUP BY c.oid, n.nspname, c.relname, t.oid, x.oid;
+                                 |   GROUP BY c.oid, n.nspname, c.relname, t.oid, x.indrelid;
  pg_statio_sys_indexes           |  SELECT pg_statio_all_indexes.relid,                                                                                                                                                                           +
                                  |     pg_statio_all_indexes.indexrelid,                                                                                                                                                                          +
                                  |     pg_statio_all_indexes.schemaname,                                                                                                                                                                          +
@@ -2347,11 +2347,11 @@ select xmin, * from fooview;  -- fail, views don't have such a column
 ERROR:  column "xmin" does not exist
 LINE 1: select xmin, * from fooview;
                ^
-select reltoastrelid, reltoastidxid, relkind, relfrozenxid
+select reltoastrelid, relkind, relfrozenxid
   from pg_class where oid = 'fooview'::regclass;
- reltoastrelid | reltoastidxid | relkind | relfrozenxid 
----------------+---------------+---------+--------------
-             0 |             0 | v       |            0
+ reltoastrelid | relkind | relfrozenxid 
+---------------+---------+--------------
+             0 | v       |            0
 (1 row)
 
 drop view fooview;
index 6422da26ad957fd7fa1d690d79569c7e774673f8..9b91683ea5a560abb9ed90afa88c257d7c6ec215 100644 (file)
@@ -177,10 +177,6 @@ SELECT     ctid, reltoastrelid
 FROM   pg_catalog.pg_class fk
 WHERE  reltoastrelid != 0 AND
        NOT EXISTS(SELECT 1 FROM pg_catalog.pg_class pk WHERE pk.oid = fk.reltoastrelid);
-SELECT ctid, reltoastidxid
-FROM   pg_catalog.pg_class fk
-WHERE  reltoastidxid != 0 AND
-       NOT EXISTS(SELECT 1 FROM pg_catalog.pg_class pk WHERE pk.oid = fk.reltoastidxid);
 SELECT ctid, collnamespace
 FROM   pg_catalog.pg_collation fk
 WHERE  collnamespace != 0 AND
index d5a357108752b1e39b8963e543041c6eea7c9c3d..6361297155b25d3f50478d4257528f6fbbd39000 100644 (file)
@@ -872,7 +872,7 @@ create rule "_RETURN" as on select to fooview do instead
 select * from fooview;
 select xmin, * from fooview;  -- fail, views don't have such a column
 
-select reltoastrelid, reltoastidxid, relkind, relfrozenxid
+select reltoastrelid, relkind, relfrozenxid
   from pg_class where oid = 'fooview'::regclass;
 
 drop view fooview;
index b5c4d1b805e3385922980f77fad1fc616be68d63..e3e8a2adde78e715ef33b6b5830e272a0dd2bbc1 100644 (file)
@@ -86,7 +86,6 @@ Join pg_catalog.pg_class.relowner => pg_catalog.pg_authid.oid
 Join pg_catalog.pg_class.relam => pg_catalog.pg_am.oid
 Join pg_catalog.pg_class.reltablespace => pg_catalog.pg_tablespace.oid
 Join pg_catalog.pg_class.reltoastrelid => pg_catalog.pg_class.oid
-Join pg_catalog.pg_class.reltoastidxid => pg_catalog.pg_class.oid
 Join pg_catalog.pg_collation.collnamespace => pg_catalog.pg_namespace.oid
 Join pg_catalog.pg_collation.collowner => pg_catalog.pg_authid.oid
 Join pg_catalog.pg_constraint.connamespace => pg_catalog.pg_namespace.oid