OSDN Git Service

Fetch information about DEFAULT/CHECK while openning a relation.
authorVadim B. Mikheev <vadim4o@yahoo.com>
Fri, 22 Aug 1997 03:35:44 +0000 (03:35 +0000)
committerVadim B. Mikheev <vadim4o@yahoo.com>
Fri, 22 Aug 1997 03:35:44 +0000 (03:35 +0000)
src/backend/utils/cache/relcache.c

index fa52573..258e764 100644 (file)
@@ -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.