88 *
99 *
1010 * IDENTIFICATION
11- * $PostgreSQL: pgsql/src/backend/utils/cache/relcache.c,v 1.212 2004/11/20 20:19:52 tgl Exp $
11+ * $PostgreSQL: pgsql/src/backend/utils/cache/relcache.c,v 1.213 2004/12/12 05:07:47 tgl Exp $
1212 *
1313 *-------------------------------------------------------------------------
1414 */
@@ -257,8 +257,8 @@ static Relation RelationSysNameCacheGetRelation(const char *relationName);
257257static bool load_relcache_init_file (void );
258258static void write_relcache_init_file (void );
259259
260- static void formrdesc (const char * relationName ,int natts ,
261- FormData_pg_attribute * att );
260+ static void formrdesc (const char * relationName ,Oid relationReltype ,
261+ bool hasoids , int natts , FormData_pg_attribute * att );
262262
263263static HeapTuple ScanPgRelation (RelationBuildDescInfo buildinfo ,bool indexOK );
264264static Relation AllocateRelationDesc (Relation relation ,Form_pg_class relp );
@@ -1265,16 +1265,15 @@ LookupOpclassInfo(Oid operatorClassOid,
12651265 * NOTE: we assume we are already switched into CacheMemoryContext.
12661266 */
12671267static void
1268- formrdesc (const char * relationName ,
1269- int natts ,
1270- FormData_pg_attribute * att )
1268+ formrdesc (const char * relationName ,Oid relationReltype ,
1269+ bool hasoids ,int natts ,FormData_pg_attribute * att )
12711270{
12721271Relation relation ;
12731272int i ;
12741273bool has_not_null ;
12751274
12761275/*
1277- * allocate new relation desc clear all fields of reldesc
1276+ * allocate new relation desc, clear all fields of reldesc
12781277 */
12791278relation = (Relation )palloc0 (sizeof (RelationData ));
12801279relation -> rd_targblock = InvalidBlockNumber ;
@@ -1306,6 +1305,7 @@ formrdesc(const char *relationName,
13061305
13071306namestrcpy (& relation -> rd_rel -> relname ,relationName );
13081307relation -> rd_rel -> relnamespace = PG_CATALOG_NAMESPACE ;
1308+ relation -> rd_rel -> reltype = relationReltype ;
13091309
13101310/*
13111311 * It's important to distinguish between shared and non-shared
@@ -1318,7 +1318,7 @@ formrdesc(const char *relationName,
13181318relation -> rd_rel -> relpages = 1 ;
13191319relation -> rd_rel -> reltuples = 1 ;
13201320relation -> rd_rel -> relkind = RELKIND_RELATION ;
1321- relation -> rd_rel -> relhasoids = true ;
1321+ relation -> rd_rel -> relhasoids = hasoids ;
13221322relation -> rd_rel -> relnatts = (int16 )natts ;
13231323
13241324/*
@@ -1327,12 +1327,10 @@ formrdesc(const char *relationName,
13271327 * Unlike the case with the relation tuple, this data had better be right
13281328 * because it will never be replaced. The input values must be
13291329 * correctly defined by macros in src/include/catalog/ headers.
1330- *
1331- * Note however that rd_att's tdtypeid, tdtypmod, tdhasoid fields are not
1332- * right at this point. They will be fixed later when the real
1333- * pg_class row is loaded.
13341330 */
1335- relation -> rd_att = CreateTemplateTupleDesc (natts , false);
1331+ relation -> rd_att = CreateTemplateTupleDesc (natts ,hasoids );
1332+ relation -> rd_att -> tdtypeid = relationReltype ;
1333+ relation -> rd_att -> tdtypmod = -1 ;/* unnecessary, but... */
13361334
13371335/*
13381336 * initialize tuple desc info
@@ -1380,10 +1378,12 @@ formrdesc(const char *relationName,
13801378/*
13811379 * initialize the rel-has-index flag, using hardwired knowledge
13821380 */
1383- relation -> rd_rel -> relhasindex = false;
1384-
1385- /* In bootstrap mode, we have no indexes */
1386- if (!IsBootstrapProcessingMode ())
1381+ if (IsBootstrapProcessingMode ())
1382+ {
1383+ /* In bootstrap mode, we have no indexes */
1384+ relation -> rd_rel -> relhasindex = false;
1385+ }
1386+ else
13871387{
13881388/* Otherwise, all the rels formrdesc is used for have indexes */
13891389relation -> rd_rel -> relhasindex = true;
@@ -2348,14 +2348,14 @@ RelationCacheInitialize(void)
23482348if (IsBootstrapProcessingMode ()||
23492349!load_relcache_init_file ())
23502350{
2351- formrdesc (RelationRelationName ,
2352- Natts_pg_class ,Desc_pg_class );
2353- formrdesc (AttributeRelationName ,
2354- Natts_pg_attribute ,Desc_pg_attribute );
2355- formrdesc (ProcedureRelationName ,
2356- Natts_pg_proc ,Desc_pg_proc );
2357- formrdesc (TypeRelationName ,
2358- Natts_pg_type ,Desc_pg_type );
2351+ formrdesc (RelationRelationName ,PG_CLASS_RELTYPE_OID ,
2352+ true, Natts_pg_class ,Desc_pg_class );
2353+ formrdesc (AttributeRelationName ,PG_ATTRIBUTE_RELTYPE_OID ,
2354+ false, Natts_pg_attribute ,Desc_pg_attribute );
2355+ formrdesc (ProcedureRelationName ,PG_PROC_RELTYPE_OID ,
2356+ true, Natts_pg_proc ,Desc_pg_proc );
2357+ formrdesc (TypeRelationName ,PG_TYPE_RELTYPE_OID ,
2358+ true, Natts_pg_type ,Desc_pg_type );
23592359
23602360#define NUM_CRITICAL_RELS 4/* fix if you change list above */
23612361}
@@ -3422,16 +3422,22 @@ write_relcache_init_file(void)
34223422/*
34233423 * OK, rename the temp file to its final name, deleting any
34243424 * previously-existing init file.
3425+ *
3426+ * Note: a failure here is possible under Cygwin, if some other
3427+ * backend is holding open an unlinked-but-not-yet-gone init file.
3428+ * So treat this as a noncritical failure; just remove the useless
3429+ * temp file on failure.
34253430 */
3426- rename (tempfilename ,finalfilename );
3427- LWLockRelease ( RelCacheInitLock );
3431+ if ( rename (tempfilename ,finalfilename )< 0 )
3432+ unlink ( tempfilename );
34283433}
34293434else
34303435{
34313436/* Delete the already-obsolete temp file */
34323437unlink (tempfilename );
3433- LWLockRelease (RelCacheInitLock );
34343438}
3439+
3440+ LWLockRelease (RelCacheInitLock );
34353441}
34363442
34373443/*