8
8
*
9
9
*
10
10
* IDENTIFICATION
11
- * $PostgreSQL: pgsql/src/backend/utils/cache/relcache.c,v 1.259 2007/03/29 00:15:38 tgl Exp $
11
+ * $PostgreSQL: pgsql/src/backend/utils/cache/relcache.c,v 1.260 2007/05/02 21:08:46 tgl Exp $
12
12
*
13
13
*-------------------------------------------------------------------------
14
14
*/
@@ -181,7 +181,7 @@ static HTAB *OpClassCache = NULL;
181
181
182
182
static void RelationClearRelation (Relation relation , bool rebuild );
183
183
184
- static void RelationReloadClassinfo (Relation relation );
184
+ static void RelationReloadIndexInfo (Relation relation );
185
185
static void RelationFlushRelation (Relation relation );
186
186
static bool load_relcache_init_file (void );
187
187
static void write_relcache_init_file (void );
@@ -1504,7 +1504,7 @@ RelationIdGetRelation(Oid relationId)
1504
1504
RelationIncrementReferenceCount (rd );
1505
1505
/* revalidate nailed index if necessary */
1506
1506
if (!rd -> rd_isvalid )
1507
- RelationReloadClassinfo (rd );
1507
+ RelationReloadIndexInfo (rd );
1508
1508
return rd ;
1509
1509
}
1510
1510
@@ -1579,24 +1579,24 @@ RelationClose(Relation relation)
1579
1579
}
1580
1580
1581
1581
/*
1582
- * RelationReloadClassinfo - reload the pg_class row (only)
1582
+ * RelationReloadIndexInfo - reload minimal information for an open index
1583
1583
*
1584
- * This function is used only for indexes. We currently allow only the
1585
- * pg_class row of an existing index to change (to support changes of
1586
- * owner, tablespace, or relfilenode), not its pg_index row or other
1587
- * subsidiary index schema information. Therefore it's sufficient to do
1588
- * this when we get an SI invalidation. Furthermore, there are cases
1589
- * where it's necessary not to throw away the index information, especially
1590
- * for "nailed" indexes which we are unable to rebuild on- the-fly .
1584
+ * This function is used only for indexes. A relcache inval on an index
1585
+ * can mean that its pg_class or pg_index row changed. There are only
1586
+ * very limited changes that are allowed to an existing index's schema,
1587
+ * so we can update the relcache entry without a complete rebuild; which
1588
+ * is fortunate because we can't rebuild an index entry that is "nailed"
1589
+ * and/or in active use. We support full replacement of the pg_class row,
1590
+ * as well as updates of a few simple fields of the pg_index row .
1591
1591
*
1592
- * We can't necessarily reread the pg_class row right away; we might be
1592
+ * We can't necessarily reread the catalog rows right away; we might be
1593
1593
* in a failed transaction when we receive the SI notification. If so,
1594
1594
* RelationClearRelation just marks the entry as invalid by setting
1595
1595
* rd_isvalid to false. This routine is called to fix the entry when it
1596
1596
* is next needed.
1597
1597
*/
1598
1598
static void
1599
- RelationReloadClassinfo (Relation relation )
1599
+ RelationReloadIndexInfo (Relation relation )
1600
1600
{
1601
1601
bool indexOK ;
1602
1602
HeapTuple pg_class_tuple ;
@@ -1635,6 +1635,33 @@ RelationReloadClassinfo(Relation relation)
1635
1635
if (relation -> rd_amcache )
1636
1636
pfree (relation -> rd_amcache );
1637
1637
relation -> rd_amcache = NULL ;
1638
+
1639
+ /*
1640
+ * For a non-system index, there are fields of the pg_index row that are
1641
+ * allowed to change, so re-read that row and update the relcache entry.
1642
+ * Most of the info derived from pg_index (such as support function lookup
1643
+ * info) cannot change, and indeed the whole point of this routine is to
1644
+ * update the relcache entry without clobbering that data; so wholesale
1645
+ * replacement is not appropriate.
1646
+ */
1647
+ if (!IsSystemRelation (relation ))
1648
+ {
1649
+ HeapTuple tuple ;
1650
+ Form_pg_index index ;
1651
+
1652
+ tuple = SearchSysCache (INDEXRELID ,
1653
+ ObjectIdGetDatum (RelationGetRelid (relation )),
1654
+ 0 , 0 , 0 );
1655
+ if (!HeapTupleIsValid (tuple ))
1656
+ elog (ERROR , "cache lookup failed for index %u" ,
1657
+ RelationGetRelid (relation ));
1658
+ index = (Form_pg_index ) GETSTRUCT (tuple );
1659
+
1660
+ relation -> rd_index -> indisvalid = index -> indisvalid ;
1661
+
1662
+ ReleaseSysCache (tuple );
1663
+ }
1664
+
1638
1665
/* Okay, now it's valid again */
1639
1666
relation -> rd_isvalid = true;
1640
1667
}
@@ -1683,7 +1710,7 @@ RelationClearRelation(Relation relation, bool rebuild)
1683
1710
{
1684
1711
relation -> rd_isvalid = false; /* needs to be revalidated */
1685
1712
if (relation -> rd_refcnt > 1 )
1686
- RelationReloadClassinfo (relation );
1713
+ RelationReloadIndexInfo (relation );
1687
1714
}
1688
1715
return ;
1689
1716
}
@@ -1693,14 +1720,14 @@ RelationClearRelation(Relation relation, bool rebuild)
1693
1720
* have valid index support information. This avoids problems with active
1694
1721
* use of the index support information. As with nailed indexes, we
1695
1722
* re-read the pg_class row to handle possible physical relocation of the
1696
- * index.
1723
+ * index, and we check for pg_index updates too .
1697
1724
*/
1698
1725
if (relation -> rd_rel -> relkind == RELKIND_INDEX &&
1699
1726
relation -> rd_refcnt > 0 &&
1700
1727
relation -> rd_indexcxt != NULL )
1701
1728
{
1702
1729
relation -> rd_isvalid = false; /* needs to be revalidated */
1703
- RelationReloadClassinfo (relation );
1730
+ RelationReloadIndexInfo (relation );
1704
1731
return ;
1705
1732
}
1706
1733
0 commit comments