88 *
99 *
1010 * IDENTIFICATION
11- * $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.180 2002/11/13 00:39:47 momjian Exp $
11+ * $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.181 2002/11/15 17:18:49 tgl Exp $
1212 *
1313 *-------------------------------------------------------------------------
1414 */
@@ -1333,8 +1333,8 @@ LookupOpclassInfo(Oid operatorClassOid,
13331333 * formrdesc is currently used for: pg_class, pg_attribute, pg_proc,
13341334 * and pg_type (see RelationCacheInitialize).
13351335 *
1336- * Note that these catalogs can't have constraints, default values ,
1337- * rules, or triggers, since we don't cope with any of that.
1336+ * Note that these catalogs can't have constraints (except attnotnull) ,
1337+ *default values, rules, or triggers, since we don't cope with any of that.
13381338 *
13391339 * NOTE: we assume we are already switched into CacheMemoryContext.
13401340 */
@@ -1345,6 +1345,7 @@ formrdesc(const char *relationName,
13451345{
13461346Relation relation ;
13471347int i ;
1348+ bool has_not_null ;
13481349
13491350/*
13501351 * allocate new relation desc
@@ -1408,19 +1409,30 @@ formrdesc(const char *relationName,
14081409/*
14091410 * initialize tuple desc info
14101411 */
1412+ has_not_null = false;
14111413for (i = 0 ;i < natts ;i ++ )
14121414{
14131415relation -> rd_att -> attrs [i ]= (Form_pg_attribute )palloc (ATTRIBUTE_TUPLE_SIZE );
14141416memcpy ((char * )relation -> rd_att -> attrs [i ],
14151417 (char * )& att [i ],
14161418ATTRIBUTE_TUPLE_SIZE );
1419+ has_not_null |=att [i ].attnotnull ;
14171420/* make sure attcacheoff is valid */
14181421relation -> rd_att -> attrs [i ]-> attcacheoff = -1 ;
14191422}
14201423
14211424/* initialize first attribute's attcacheoff, cf RelationBuildTupleDesc */
14221425relation -> rd_att -> attrs [0 ]-> attcacheoff = 0 ;
14231426
1427+ /* mark not-null status */
1428+ if (has_not_null )
1429+ {
1430+ TupleConstr * constr = (TupleConstr * )palloc0 (sizeof (TupleConstr ));
1431+
1432+ constr -> has_not_null = true;
1433+ relation -> rd_att -> constr = constr ;
1434+ }
1435+
14241436/*
14251437 * initialize relation id from info in att array (my, this is ugly)
14261438 */
@@ -2035,6 +2047,7 @@ RelationBuildLocalRelation(const char *relname,
20352047MemoryContext oldcxt ;
20362048int natts = tupDesc -> natts ;
20372049int i ;
2050+ bool has_not_null ;
20382051
20392052AssertArg (natts > 0 );
20402053
@@ -2081,8 +2094,20 @@ RelationBuildLocalRelation(const char *relname,
20812094 * however.
20822095 */
20832096rel -> rd_att = CreateTupleDescCopy (tupDesc );
2097+ has_not_null = false;
20842098for (i = 0 ;i < natts ;i ++ )
2099+ {
20852100rel -> rd_att -> attrs [i ]-> attnotnull = tupDesc -> attrs [i ]-> attnotnull ;
2101+ has_not_null |=tupDesc -> attrs [i ]-> attnotnull ;
2102+ }
2103+
2104+ if (has_not_null )
2105+ {
2106+ TupleConstr * constr = (TupleConstr * )palloc0 (sizeof (TupleConstr ));
2107+
2108+ constr -> has_not_null = true;
2109+ rel -> rd_att -> constr = constr ;
2110+ }
20862111
20872112/*
20882113 * initialize relation tuple form (caller may add/override data later)
@@ -2723,6 +2748,7 @@ load_relcache_init_file(void)
27232748size_t nread ;
27242749Relation rel ;
27252750Form_pg_class relform ;
2751+ bool has_not_null ;
27262752
27272753/* first read the relation descriptor length */
27282754if ((nread = fread (& len ,1 ,sizeof (len ),fp ))!= sizeof (len ))
@@ -2764,6 +2790,7 @@ load_relcache_init_file(void)
27642790relform -> relhasoids );
27652791
27662792/* next read all the attribute tuple form data entries */
2793+ has_not_null = false;
27672794for (i = 0 ;i < relform -> relnatts ;i ++ )
27682795{
27692796if ((nread = fread (& len ,1 ,sizeof (len ),fp ))!= sizeof (len ))
@@ -2773,6 +2800,17 @@ load_relcache_init_file(void)
27732800
27742801if ((nread = fread (rel -> rd_att -> attrs [i ],1 ,len ,fp ))!= len )
27752802gotoread_failed ;
2803+
2804+ has_not_null |=rel -> rd_att -> attrs [i ]-> attnotnull ;
2805+ }
2806+
2807+ /* mark not-null status */
2808+ if (has_not_null )
2809+ {
2810+ TupleConstr * constr = (TupleConstr * )palloc0 (sizeof (TupleConstr ));
2811+
2812+ constr -> has_not_null = true;
2813+ rel -> rd_att -> constr = constr ;
27762814}
27772815
27782816/* If it's an index, there's more to do */