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,
7676 Oid * classOids ,
7777 bool 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)
16891690 return 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 */
17361750 if (iRel -> rd_rel -> relisshared )
17371751 {
17381752 if (!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 )) );
17421756 inplace = true;
17431757 }
1758+ #ifndef ENABLE_REINDEX_NAILED_RELATIONS
17441759 if (iRel -> rd_isnailed )
17451760 {
17461761 if (!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 )) );
17501765 inplace = true;
17511766 }
1767+ #endif /* ENABLE_REINDEX_NAILED_RELATIONS */
17521768
17531769 /* Fetch info needed for index_build */
17541770 indexInfo = BuildIndexInfo (iRel );
@@ -1787,12 +1803,13 @@ reindex_index(Oid indexId, bool force, bool inplace)
17871803 return 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 }
18151832 return true;
18161833}
1817- #endif /* NOT_USED */
18181834
1819- /*
1820- * reindex_relation - This routine is used to recreate all 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)
18291846 HeapTuple indexTuple ;
18301847 bool old ,
18311848 reindexed ;
1832- bool overwrite ;
1849+ bool deactivate_needed ,
1850+ overwrite ;
18331851 Relation 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)
18421860 rel = heap_open (relid , AccessExclusiveLock );
18431861
18441862 /*
1845- * Should be ignoring system indexes if we are reindexing a system table.
1846- * (This is elog not ereport because caller should have caught it.)
1863+ * ignore the indexes of the target system relation while processing
1864+ * reindex.
18471865 */
18481866 if (!IsIgnoringSystemIndexes () &&
18491867 IsSystemRelation (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 */
18581874 if (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
18671887 old = 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 */
18721907 heap_close (rel , NoLock );
18731908
1874- /*
1875- * Find table's indexes by looking in pg_index (not trusting indexes...)
1876- */
18771909 indexRelation = 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 ));
18821912 scan = heap_beginscan (indexRelation , SnapshotNow , 1 , & entry );
18831913 reindexed = false;
18841914 while ((indexTuple = heap_getnext (scan , ForwardScanDirection )) != NULL )
18851915 {
18861916 Form_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 ))
18891919 reindexed = true;
18901920 else
18911921 {
@@ -1895,7 +1925,31 @@ reindex_relation(Oid relid, bool force)
18951925 }
18961926 heap_endscan (scan );
18971927 heap_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+ }
18991953 SetReindexProcessing (old );
19001954
19011955 return reindexed ;
0 commit comments