88 *
99 *
1010 * IDENTIFICATION
11- * $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.215 2003/09/19 19:57:42 tgl Exp $
11+ * $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.216 2003/09/23 01:51:09 inoue Exp $
1212 *
1313 *
1414 * INTERFACE ROUTINES
@@ -76,6 +76,7 @@ static void UpdateIndexRelation(Oid indexoid, Oid heapoid,
7676Oid * classOids ,
7777bool primary );
7878static Oid IndexGetRelation (Oid indexId );
79+ static bool activate_index (Oid indexId ,bool activate ,bool inplace );
7980
8081
8182static bool reindexing = false;
@@ -1689,8 +1690,23 @@ IndexGetRelation(Oid indexId)
16891690return result ;
16901691}
16911692
1692- /*
1693+ /* ---------------------------------
1694+ * activate_index -- activate/deactivate the specified index.
1695+ *Note that currently PostgreSQL doesn't hold the
1696+ *status per index
1697+ * ---------------------------------
1698+ */
1699+ static bool
1700+ activate_index (Oid indexId ,bool activate ,bool inplace )
1701+ {
1702+ if (!activate )/* Currently does nothing */
1703+ return true;
1704+ return reindex_index (indexId , false,inplace );
1705+ }
1706+
1707+ /* --------------------------------
16931708 * reindex_index - This routine is used to recreate an index
1709+ * --------------------------------
16941710 */
16951711bool
16961712reindex_index (Oid indexId ,bool force ,bool inplace )
@@ -1729,26 +1745,26 @@ reindex_index(Oid indexId, bool force, bool inplace)
17291745 * the relcache can't cope with changing its relfilenode.
17301746 *
17311747 * In either of these cases, we are definitely processing a system index,
1732- * so we'd better be ignoring system indexes. (These checks are just
1733- * for paranoia's sake --- upstream code should have disallowed reindex
1734- * in such cases already.)
1748+ * so we'd better be ignoring system indexes.
17351749 */
17361750if (iRel -> rd_rel -> relisshared )
17371751{
17381752if (!IsIgnoringSystemIndexes ())
1739- elog (ERROR ,
1740- "must be ignoring system indexes to reindex shared index %u" ,
1741- indexId );
1753+ ereport (ERROR ,
1754+ ( errcode ( ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE ) ,
1755+ errmsg ( "the target relation %u is shared" , indexId )) );
17421756inplace = true;
17431757}
1758+ #ifndef ENABLE_REINDEX_NAILED_RELATIONS
17441759if (iRel -> rd_isnailed )
17451760{
17461761if (!IsIgnoringSystemIndexes ())
1747- elog (ERROR ,
1748- "must be ignoring system indexes to reindex nailed index %u" ,
1749- indexId );
1762+ ereport (ERROR ,
1763+ ( errcode ( ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE ) ,
1764+ errmsg ( "the target relation %u is nailed" , indexId )) );
17501765inplace = true;
17511766}
1767+ #endif /* ENABLE_REINDEX_NAILED_RELATIONS */
17521768
17531769/* Fetch info needed for index_build */
17541770indexInfo = BuildIndexInfo (iRel );
@@ -1787,12 +1803,13 @@ reindex_index(Oid indexId, bool force, bool inplace)
17871803return true;
17881804}
17891805
1790- #ifdef NOT_USED
17911806/*
1807+ * ----------------------------
17921808 * activate_indexes_of_a_table
17931809 *activate/deactivate indexes of the specified table.
17941810 *
17951811 * Caller must already hold exclusive lock on the table.
1812+ * ----------------------------
17961813 */
17971814bool
17981815activate_indexes_of_a_table (Relation heaprel ,bool activate )
@@ -1814,11 +1831,11 @@ activate_indexes_of_a_table(Relation heaprel, bool activate)
18141831}
18151832return true;
18161833}
1817- #endif /* NOT_USED */
18181834
1819- /*
1820- * reindex_relation - This routine is used to recreateall indexes
1835+ /* --------------------------------
1836+ * reindex_relation - This routine is used to recreate indexes
18211837 * of a relation.
1838+ * --------------------------------
18221839 */
18231840bool
18241841reindex_relation (Oid relid ,bool force )
@@ -1829,10 +1846,11 @@ reindex_relation(Oid relid, bool force)
18291846HeapTuple indexTuple ;
18301847bool old ,
18311848reindexed ;
1832- bool overwrite ;
1849+ bool deactivate_needed ,
1850+ overwrite ;
18331851Relation rel ;
18341852
1835- overwrite = false;
1853+ overwrite = deactivate_needed = false;
18361854
18371855/*
18381856 * Ensure to hold an exclusive lock throughout the transaction. The
@@ -1842,50 +1860,62 @@ reindex_relation(Oid relid, bool force)
18421860rel = heap_open (relid ,AccessExclusiveLock );
18431861
18441862/*
1845- *Should be ignoring system indexesif we are reindexing a system table.
1846- *(This is elog not ereport because caller should have caught it.)
1863+ *ignore the indexesof the target system relation while processing
1864+ *reindex.
18471865 */
18481866if (!IsIgnoringSystemIndexes ()&&
18491867IsSystemRelation (rel )&& !IsToastRelation (rel ))
1850- elog (ERROR ,
1851- "must be ignoring system indexes to reindex system table %u" ,
1852- relid );
1868+ deactivate_needed = true;
18531869
18541870/*
18551871 * Shared system indexes must be overwritten because it's impossible
18561872 * to update pg_class tuples of all databases.
18571873 */
18581874if (rel -> rd_rel -> relisshared )
18591875{
1860- if (!IsIgnoringSystemIndexes ())/* shouldn't happen */
1861- elog (ERROR ,
1862- "must be ignoring system indexes to reindex shared table %u" ,
1863- relid );
1864- overwrite = true;
1876+ if (IsIgnoringSystemIndexes ())
1877+ {
1878+ overwrite = true;
1879+ deactivate_needed = true;
1880+ }
1881+ else
1882+ ereport (ERROR ,
1883+ (errcode (ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE ),
1884+ errmsg ("the target relation %u is shared" ,relid )));
18651885}
18661886
18671887old = SetReindexProcessing (true);
18681888
1889+ if (deactivate_needed )
1890+ {
1891+ if (IndexesAreActive (rel ))
1892+ {
1893+ if (!force )
1894+ {
1895+ SetReindexProcessing (old );
1896+ heap_close (rel ,NoLock );
1897+ return false;
1898+ }
1899+ activate_indexes_of_a_table (rel , false);
1900+ CommandCounterIncrement ();
1901+ }
1902+ }
1903+
18691904/*
18701905 * Continue to hold the lock.
18711906 */
18721907heap_close (rel ,NoLock );
18731908
1874- /*
1875- * Find table's indexes by looking in pg_index (not trusting indexes...)
1876- */
18771909indexRelation = heap_openr (IndexRelationName ,AccessShareLock );
1878- ScanKeyEntryInitialize (& entry ,0 ,
1879- Anum_pg_index_indrelid ,
1880- F_OIDEQ ,
1881- ObjectIdGetDatum (relid ));
1910+ ScanKeyEntryInitialize (& entry ,0 ,Anum_pg_index_indrelid ,
1911+ F_OIDEQ ,ObjectIdGetDatum (relid ));
18821912scan = heap_beginscan (indexRelation ,SnapshotNow ,1 ,& entry );
18831913reindexed = false;
18841914while ((indexTuple = heap_getnext (scan ,ForwardScanDirection ))!= NULL )
18851915{
18861916Form_pg_index index = (Form_pg_index )GETSTRUCT (indexTuple );
18871917
1888- if (reindex_index (index -> indexrelid ,false ,overwrite ))
1918+ if (activate_index (index -> indexrelid ,true ,overwrite ))
18891919reindexed = true;
18901920else
18911921{
@@ -1895,7 +1925,31 @@ reindex_relation(Oid relid, bool force)
18951925}
18961926heap_endscan (scan );
18971927heap_close (indexRelation ,AccessShareLock );
1928+ if (reindexed )
1929+ {
1930+ /*
1931+ * Ok,we could use the reindexed indexes of the target system
1932+ * relation now.
1933+ */
1934+ if (deactivate_needed )
1935+ {
1936+ if (!overwrite && relid == RelOid_pg_class )
1937+ {
1938+ /*
1939+ * For pg_class, relhasindex should be set to true here in
1940+ * place.
1941+ */
1942+ setRelhasindex (relid , true, false,InvalidOid );
1943+ CommandCounterIncrement ();
18981944
1945+ /*
1946+ * However the following setRelhasindex() is needed to
1947+ * keep consistency with WAL.
1948+ */
1949+ }
1950+ setRelhasindex (relid , true, false,InvalidOid );
1951+ }
1952+ }
18991953SetReindexProcessing (old );
19001954
19011955return reindexed ;