]> granicus.if.org Git - postgresql/commitdiff
Upgrade formrdesc() so that it can correctly initialize the tupledesc
authorTom Lane <tgl@sss.pgh.pa.us>
Sun, 12 Dec 2004 05:07:50 +0000 (05:07 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Sun, 12 Dec 2004 05:07:50 +0000 (05:07 +0000)
(rd_att) field of a nailed-in-cache relcache entry.  This fixes the bug
reported by Alvaro 8-Dec-2004; I believe it probably also explains
Grant Finnemore's report of 10-Sep-2004.

In an unrelated change in the same file, put back 7.4's response to
failure to rename() the relcache init file, ie, unlink the useless
temp file.  I did not put back the warning message, since there might
actually be some reason not to have that.

src/backend/utils/cache/relcache.c
src/include/catalog/pg_type.h

index 36c11709ab3309d84f0b58d8b5a2755c2a8c2c6b..5c2d81c06e707b3e12828ef58316e45d3dbfbc78 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/utils/cache/relcache.c,v 1.212 2004/11/20 20:19:52 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/utils/cache/relcache.c,v 1.213 2004/12/12 05:07:47 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -257,8 +257,8 @@ static Relation RelationSysNameCacheGetRelation(const char *relationName);
 static bool load_relcache_init_file(void);
 static void write_relcache_init_file(void);
 
-static void formrdesc(const char *relationName, int natts,
-                 FormData_pg_attribute *att);
+static void formrdesc(const char *relationName, Oid relationReltype,
+                                         bool hasoids, int natts, FormData_pg_attribute *att);
 
 static HeapTuple ScanPgRelation(RelationBuildDescInfo buildinfo, bool indexOK);
 static Relation AllocateRelationDesc(Relation relation, Form_pg_class relp);
@@ -1265,16 +1265,15 @@ LookupOpclassInfo(Oid operatorClassOid,
  * NOTE: we assume we are already switched into CacheMemoryContext.
  */
 static void
-formrdesc(const char *relationName,
-                 int natts,
-                 FormData_pg_attribute *att)
+formrdesc(const char *relationName, Oid relationReltype,
+                 bool hasoids, int natts, FormData_pg_attribute *att)
 {
        Relation        relation;
        int                     i;
        bool            has_not_null;
 
        /*
-        * allocate new relation desc clear all fields of reldesc
+        * allocate new relation desc, clear all fields of reldesc
         */
        relation = (Relation) palloc0(sizeof(RelationData));
        relation->rd_targblock = InvalidBlockNumber;
@@ -1306,6 +1305,7 @@ formrdesc(const char *relationName,
 
        namestrcpy(&relation->rd_rel->relname, relationName);
        relation->rd_rel->relnamespace = PG_CATALOG_NAMESPACE;
+       relation->rd_rel->reltype = relationReltype;
 
        /*
         * It's important to distinguish between shared and non-shared
@@ -1318,7 +1318,7 @@ formrdesc(const char *relationName,
        relation->rd_rel->relpages = 1;
        relation->rd_rel->reltuples = 1;
        relation->rd_rel->relkind = RELKIND_RELATION;
-       relation->rd_rel->relhasoids = true;
+       relation->rd_rel->relhasoids = hasoids;
        relation->rd_rel->relnatts = (int16) natts;
 
        /*
@@ -1327,12 +1327,10 @@ formrdesc(const char *relationName,
         * Unlike the case with the relation tuple, this data had better be right
         * because it will never be replaced.  The input values must be
         * correctly defined by macros in src/include/catalog/ headers.
-        *
-        * Note however that rd_att's tdtypeid, tdtypmod, tdhasoid fields are not
-        * right at this point.  They will be fixed later when the real
-        * pg_class row is loaded.
         */
-       relation->rd_att = CreateTemplateTupleDesc(natts, false);
+       relation->rd_att = CreateTemplateTupleDesc(natts, hasoids);
+       relation->rd_att->tdtypeid = relationReltype;
+       relation->rd_att->tdtypmod = -1;        /* unnecessary, but... */
 
        /*
         * initialize tuple desc info
@@ -1380,10 +1378,12 @@ formrdesc(const char *relationName,
        /*
         * initialize the rel-has-index flag, using hardwired knowledge
         */
-       relation->rd_rel->relhasindex = false;
-
-       /* In bootstrap mode, we have no indexes */
-       if (!IsBootstrapProcessingMode())
+       if (IsBootstrapProcessingMode())
+       {
+               /* In bootstrap mode, we have no indexes */
+               relation->rd_rel->relhasindex = false;
+       }
+       else
        {
                /* Otherwise, all the rels formrdesc is used for have indexes */
                relation->rd_rel->relhasindex = true;
@@ -2348,14 +2348,14 @@ RelationCacheInitialize(void)
        if (IsBootstrapProcessingMode() ||
                !load_relcache_init_file())
        {
-               formrdesc(RelationRelationName,
-                                 Natts_pg_class, Desc_pg_class);
-               formrdesc(AttributeRelationName,
-                                 Natts_pg_attribute, Desc_pg_attribute);
-               formrdesc(ProcedureRelationName,
-                                 Natts_pg_proc, Desc_pg_proc);
-               formrdesc(TypeRelationName,
-                                 Natts_pg_type, Desc_pg_type);
+               formrdesc(RelationRelationName, PG_CLASS_RELTYPE_OID,
+                                 true, Natts_pg_class, Desc_pg_class);
+               formrdesc(AttributeRelationName, PG_ATTRIBUTE_RELTYPE_OID,
+                                 false, Natts_pg_attribute, Desc_pg_attribute);
+               formrdesc(ProcedureRelationName, PG_PROC_RELTYPE_OID,
+                                 true, Natts_pg_proc, Desc_pg_proc);
+               formrdesc(TypeRelationName, PG_TYPE_RELTYPE_OID,
+                                 true, Natts_pg_type, Desc_pg_type);
 
 #define NUM_CRITICAL_RELS      4       /* fix if you change list above */
        }
@@ -3422,16 +3422,22 @@ write_relcache_init_file(void)
                /*
                 * OK, rename the temp file to its final name, deleting any
                 * previously-existing init file.
+                *
+                * Note: a failure here is possible under Cygwin, if some other
+                * backend is holding open an unlinked-but-not-yet-gone init file.
+                * So treat this as a noncritical failure; just remove the useless
+                * temp file on failure.
                 */
-               rename(tempfilename, finalfilename);
-               LWLockRelease(RelCacheInitLock);
+               if (rename(tempfilename, finalfilename) < 0)
+                       unlink(tempfilename);
        }
        else
        {
                /* Delete the already-obsolete temp file */
                unlink(tempfilename);
-               LWLockRelease(RelCacheInitLock);
        }
+
+       LWLockRelease(RelCacheInitLock);
 }
 
 /*
index 67c93d08a7be8510ed81a2978346f9449ec07b2b..aa41720d86566c35b3862628aea36d62cad18e7d 100644 (file)
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1996-2004, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/catalog/pg_type.h,v 1.156 2004/08/29 05:06:55 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_type.h,v 1.157 2004/12/12 05:07:50 tgl Exp $
  *
  * NOTES
  *       the genbki.sh script reads this file and generates .bki
@@ -305,9 +305,13 @@ DESCR("array of INDEX_MAX_KEYS oids, used in system tables");
 #define OIDVECTOROID   30
 
 DATA(insert OID = 71 ( pg_type                 PGNSP PGUID -1 f c t \054 1247 0 record_in record_out record_recv record_send - d x f 0 -1 0 _null_ _null_ ));
+#define PG_TYPE_RELTYPE_OID 71
 DATA(insert OID = 75 ( pg_attribute    PGNSP PGUID -1 f c t \054 1249 0 record_in record_out record_recv record_send - d x f 0 -1 0 _null_ _null_ ));
+#define PG_ATTRIBUTE_RELTYPE_OID 75
 DATA(insert OID = 81 ( pg_proc                 PGNSP PGUID -1 f c t \054 1255 0 record_in record_out record_recv record_send - d x f 0 -1 0 _null_ _null_ ));
+#define PG_PROC_RELTYPE_OID 81
 DATA(insert OID = 83 ( pg_class                PGNSP PGUID -1 f c t \054 1259 0 record_in record_out record_recv record_send - d x f 0 -1 0 _null_ _null_ ));
+#define PG_CLASS_RELTYPE_OID 83
 DATA(insert OID = 86 ( pg_shadow               PGNSP PGUID -1 f c t \054 1260 0 record_in record_out record_recv record_send - d x f 0 -1 0 _null_ _null_ ));
 DATA(insert OID = 87 ( pg_group                PGNSP PGUID -1 f c t \054 1261 0 record_in record_out record_recv record_send - d x f 0 -1 0 _null_ _null_ ));
 DATA(insert OID = 88 ( pg_database             PGNSP PGUID -1 f c t \054 1262 0 record_in record_out record_recv record_send - d x f 0 -1 0 _null_ _null_ ));