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