diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fa52573b2db6ed13a72751ba86bcce3f9cdc0758..258e764ecfcd9dea5636d2b1f783e4a7cf6febfc 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *    $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.18 1997/08/21 04:09:51 vadim Exp $
+ *    $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.19 1997/08/22 03:35:44 vadim Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -82,6 +82,7 @@
 #include "catalog/pg_log.h"
 #include "catalog/pg_time.h"
 #include "catalog/pg_attrdef.h"
+#include "catalog/pg_relcheck.h"
 #include "catalog/indexing.h"
 #include "catalog/index.h"
 #include "fmgr.h"
@@ -260,6 +261,7 @@ static void build_tupdesc_ind(RelationBuildDescInfo buildinfo,
 static Relation RelationBuildDesc(RelationBuildDescInfo buildinfo);
 static void IndexedAccessMethodInitialize(Relation relation);
 static void AttrDefaultFetch (Relation relation);
+static void RelCheckFetch (Relation relation);
 
 /*
  * newlyCreatedRelns -
@@ -482,7 +484,7 @@ AllocateRelationDesc(u_int natts, Form_pg_class relp)
  *	RelationBuildTupleDesc
  *
  *	Form the relation's tuple descriptor from information in
- *	the pg_attribute system catalog.
+ *	the pg_attribute, pg_attrdef & pg_relcheck system cataloges.
  * --------------------------------
  */
 static void
@@ -499,13 +501,7 @@ RelationBuildTupleDesc(RelationBuildDescInfo buildinfo,
     if (IsBootstrapProcessingMode())
 	build_tupdesc_seq(buildinfo, relation, natts);
     else
-    {
-    	relation->rd_att->constr = (TupleConstr *) palloc(sizeof(TupleConstr));
-    	relation->rd_att->constr->num_check = 0;
-    	relation->rd_att->constr->num_defval = 0;
-    	relation->rd_att->constr->has_not_null = false;
 	build_tupdesc_ind(buildinfo, relation, natts);
-    }
 }
 
 static void
@@ -580,10 +576,13 @@ build_tupdesc_ind(RelationBuildDescInfo buildinfo,
     Relation attrel;
     HeapTuple atttup;
     AttributeTupleForm	attp;
+    TupleConstr *constr = (TupleConstr *) palloc(sizeof(TupleConstr));
     AttrDefault	*attrdef = NULL;
     int ndef = 0;
     int i;
-
+    
+    constr->has_not_null = false;
+    
     attrel = heap_openr(AttributeRelationName);
     
     for (i = 1; i <= relation->rd_rel->relnatts; i++) {
@@ -604,7 +603,7 @@ build_tupdesc_ind(RelationBuildDescInfo buildinfo,
 
 	/* Update if this attribute have a constraint */
 	if (attp->attnotnull)
-	    relation->rd_att->constr->has_not_null = true;
+	    constr->has_not_null = true;
 	
 	if (attp->atthasdef)
 	{
@@ -619,16 +618,39 @@ build_tupdesc_ind(RelationBuildDescInfo buildinfo,
     }
     
     heap_close(attrel);
-
-    if ( ndef > 0 )
+    
+    if ( constr->has_not_null || ndef > 0 || relation->rd_rel->relchecks )
     {
-    	if ( ndef > relation->rd_rel->relnatts )
-    	    relation->rd_att->constr->defval = (AttrDefault*) 
+    	relation->rd_att->constr = constr;
+    	
+    	if ( ndef > 0 )					/* DEFAULTs */
+    	{
+    	    if ( ndef < relation->rd_rel->relnatts )
+    	    	constr->defval = (AttrDefault*) 
     	    		repalloc (attrdef, ndef * sizeof (AttrDefault));
+    	    else
+    	    	constr->defval = attrdef;
+    	    constr->num_defval = ndef;
+    	    AttrDefaultFetch (relation);
+    	}
     	else
-    	    relation->rd_att->constr->defval = attrdef;
-    	relation->rd_att->constr->num_defval = ndef;
-    	AttrDefaultFetch (relation);
+    	    constr->num_defval = 0;
+    	
+	if ( relation->rd_rel->relchecks > 0 )		/* CHECKs */
+	{
+	    constr->num_check = relation->rd_rel->relchecks;
+	    constr->check = (ConstrCheck *) palloc (constr->num_check * 
+	    						sizeof (ConstrCheck));
+	    memset (constr->check, 0, constr->num_check * sizeof (ConstrCheck));
+	    RelCheckFetch (relation);
+	}
+	else
+	    constr->num_check = 0;
+    }
+    else
+    {
+    	pfree (constr);
+    	relation->rd_att->constr = NULL;
     }
     
 }
@@ -1252,8 +1274,6 @@ static void
 RelationFlushRelation(Relation *relationPtr,
 		      bool onlyFlushReferenceCountZero)
 {
-    int			i;
-    AttributeTupleForm	*p;
     MemoryContext	oldcxt;
     Relation 		relation = *relationPtr;
     
@@ -1268,14 +1288,8 @@ RelationFlushRelation(Relation *relationPtr,
 	oldcxt = MemoryContextSwitchTo((MemoryContext)CacheCxt);
 	
 	RelationCacheDelete(relation);
-
-	p = relation->rd_att->attrs;
-	for (i = 0; i < relation->rd_rel->relnatts; i++, p++)
-	    pfree (*p);
-	pfree (relation->rd_att->attrs);
-        if (relation->rd_att->constr)
-           pfree (relation->rd_att->constr);
-        pfree (relation->rd_att);
+	
+	FreeTupleDesc (relation->rd_att);
 
 #if 0
 	if (relation->rd_rules) {
@@ -1641,8 +1655,9 @@ AttrDefaultFetch (Relation relation)
 	pfree(indexRes);
     	if (!HeapTupleIsValid(tuple))
     	    continue;
+    	found++;
     	adform = (Form_pg_attrdef) GETSTRUCT(tuple);
-    	for (i = 1; i <= ndef; i++)
+    	for (i = 0; i < ndef; i++)
     	{
     	    if ( adform->adnum != attrdef[i].adnum )
     	    	continue;
@@ -1667,10 +1682,10 @@ AttrDefaultFetch (Relation relation)
     	    	    NAMEDATALEN, relation->rd_att->attrs[adform->adnum - 1]->attname.data,
     	    	    NAMEDATALEN, relation->rd_rel->relname.data);
     	    attrdef[i].adsrc = textout (val);
-    	    found++;
+    	    break;
     	}
 	
-    	if ( i > ndef )
+    	if ( i >= ndef )
     	    elog (WARN, "AttrDefaultFetch: unexpected record found for attr %d in rel %.*s",
     	    	    	adform->adnum,
     	    	    	NAMEDATALEN, relation->rd_rel->relname.data);
@@ -1689,6 +1704,88 @@ AttrDefaultFetch (Relation relation)
     
 }
 
+static void
+RelCheckFetch (Relation relation)
+{
+    ConstrCheck *check = relation->rd_att->constr->check;
+    int ncheck = relation->rd_att->constr->num_check;
+    Relation rcrel;
+    Relation irel;
+    ScanKeyData skey;
+    HeapTuple tuple;
+    IndexScanDesc sd;
+    RetrieveIndexResult indexRes;
+    Buffer buffer;
+    ItemPointer iptr;
+    Name rcname;
+    struct varlena *val;
+    bool isnull;
+    int found;
+    
+    ScanKeyEntryInitialize(&skey,
+			   (bits16)0x0,
+			   (AttrNumber)1,
+			   (RegProcedure)ObjectIdEqualRegProcedure,
+			   ObjectIdGetDatum(relation->rd_id));
+    
+    rcrel = heap_openr(RelCheckRelationName);
+    irel = index_openr(RelCheckIndex);
+    sd = index_beginscan(irel, false, 1, &skey);
+    tuple = (HeapTuple)NULL;
+    
+    for (found = 0; ; )
+    {
+	indexRes = index_getnext(sd, ForwardScanDirection);
+	if (!indexRes)
+	    break;
+	    
+	iptr = &indexRes->heap_iptr;
+	tuple = heap_fetch(rcrel, NowTimeQual, iptr, &buffer);
+	pfree(indexRes);
+    	if (!HeapTupleIsValid(tuple))
+    	    continue;
+    	if ( found == ncheck )
+    	    elog (WARN, "RelCheckFetch: unexpected record found for rel %.*s",
+    	    	    	NAMEDATALEN, relation->rd_rel->relname.data);
+    	
+    	rcname = (Name) fastgetattr (tuple, 
+    	    				Anum_pg_relcheck_rcname,
+    	    				rcrel->rd_att, &isnull);
+    	if ( isnull )
+    	    elog (WARN, "RelCheckFetch: rcname IS NULL for rel %.*s",
+    	    	    NAMEDATALEN, relation->rd_rel->relname.data);
+    	check[found].ccname = nameout (rcname);
+    	val = (struct varlena*) fastgetattr (tuple, 
+    	    					Anum_pg_relcheck_rcbin,
+    	    					rcrel->rd_att, &isnull);
+    	if ( isnull )
+    	    elog (WARN, "RelCheckFetch: rcbin IS NULL for rel %.*s",
+    	    	    NAMEDATALEN, relation->rd_rel->relname.data);
+    	check[found].ccbin = textout (val);
+    	val = (struct varlena*) fastgetattr (tuple, 
+    	    					Anum_pg_relcheck_rcsrc,
+    	    					rcrel->rd_att, &isnull);
+    	if ( isnull )
+    	    elog (WARN, "RelCheckFetch: rcsrc IS NULL for rel %.*s",
+    	    	    NAMEDATALEN, relation->rd_rel->relname.data);
+    	check[found].ccsrc = textout (val);
+    	found++;
+	
+	ReleaseBuffer(buffer);
+    }
+    
+    if ( found < ncheck )
+    	elog (WARN, "RelCheckFetch: %d record not found for rel %.*s",
+    	    	    	ncheck - found,
+    	    	    	NAMEDATALEN, relation->rd_rel->relname.data);
+    
+    index_endscan (sd);
+    pfree (sd);
+    index_close (irel);
+    heap_close (rcrel);
+    
+}
+
 /*
  *  init_irels(), write_irels() -- handle special-case initialization of
  *				   index relation descriptors.