Index: src/backend/utils/cache/inval.c =================================================================== RCS file: /home/cvs/hot/cvs/pgsql/src/backend/utils/cache/inval.c,v retrieving revision 1.79 retrieving revision 1.79.2.1 diff -c -r1.79 -r1.79.2.1 *** src/backend/utils/cache/inval.c 5 Jan 2007 22:19:43 -0000 1.79 --- src/backend/utils/cache/inval.c 3 Apr 2007 05:53:46 -0000 1.79.2.1 *************** *** 596,601 **** --- 596,612 ---- */ databaseId = MyDatabaseId; } + else if (tupleRelId == IndexRelationId) + { + Form_pg_index indextup = (Form_pg_index) GETSTRUCT(tuple); + + /* + * When a pg_index row is updated, we should send SI invaliation + * to the index relation + */ + relationId = indextup->indexrelid; + databaseId = MyDatabaseId; + } else return; Index: src/backend/utils/cache/relcache.c =================================================================== RCS file: /home/cvs/hot/cvs/pgsql/src/backend/utils/cache/relcache.c,v retrieving revision 1.259 diff -c -r1.259 relcache.c *** src/backend/utils/cache/relcache.c 29 Mar 2007 00:15:38 -0000 1.259 --- src/backend/utils/cache/relcache.c 5 Apr 2007 06:39:07 -0000 *************** *** 212,217 **** --- 212,218 ---- static OpClassCacheEnt *LookupOpclassInfo(Oid operatorClassOid, StrategyNumber numStrats, StrategyNumber numSupport); + static void RelationReloadIndexInfo(Relation relation); /* *************** *** 1581,1593 **** /* * RelationReloadClassinfo - reload the pg_class row (only) * ! * This function is used only for indexes. We currently allow only the * pg_class row of an existing index to change (to support changes of * owner, tablespace, or relfilenode), not its pg_index row or other ! * subsidiary index schema information. Therefore it's sufficient to do ! * this when we get an SI invalidation. Furthermore, there are cases ! * where it's necessary not to throw away the index information, especially ! * for "nailed" indexes which we are unable to rebuild on-the-fly. * * We can't necessarily reread the pg_class row right away; we might be * in a failed transaction when we receive the SI notification. If so, --- 1582,1598 ---- /* * RelationReloadClassinfo - reload the pg_class row (only) * ! * This function is used only for indexes. We used to allow only the * pg_class row of an existing index to change (to support changes of * owner, tablespace, or relfilenode), not its pg_index row or other ! * subsidiary index schema information. But for CREATE INDEX CONCURRENTLY ! * we need to change the pg_index attribute 'indisvalid' and update ! * pg_index row. In future, there might be similar requirements for ! * the existing and/or new attributes of pg_index to change. To ! * support that we now re-read the pg_index row and update one ! * or more fields selectively. We don't rebuild the entire the ! * entire information because that may not be even possible for ! * "nailed" indexes. * * We can't necessarily reread the pg_class row right away; we might be * in a failed transaction when we receive the SI notification. If so, *************** *** 1635,1640 **** --- 1640,1653 ---- if (relation->rd_amcache) pfree(relation->rd_amcache); relation->rd_amcache = NULL; + + /* + * Before we mark the relation valid, re-read the pg_index row + * and update some of the fields selectively. + */ + if (!IsSystemRelation(relation)) + RelationReloadIndexInfo(relation); + /* Okay, now it's valid again */ relation->rd_isvalid = true; } *************** *** 3758,3760 **** --- 3771,3802 ---- unlink(initfilename); /* ignore any error, since it might not be there at all */ } + + /* + * Reload index-access-method support data for an index relation + */ + static void + RelationReloadIndexInfo(Relation relation) + { + HeapTuple tuple; + Form_pg_index index; + + tuple = SearchSysCache(INDEXRELID, + ObjectIdGetDatum(RelationGetRelid(relation)), + 0, 0, 0); + if (!HeapTupleIsValid(tuple)) + elog(ERROR, "cache lookup failed for index %u", + RelationGetRelid(relation)); + + index = (Form_pg_index) GETSTRUCT(tuple); + + Assert(relation->rd_indextuple); + Assert(relation->rd_index); + + relation->rd_index->indisvalid = index->indisvalid; + relation->rd_index->indcreatexid = index->indcreatexid; + relation->rd_index->indisrdonly = index->indisrdonly; + + ReleaseSysCache(tuple); + return; + }