]> granicus.if.org Git - postgresql/commitdiff
Read info for DEFAULT from pg_attrdef.
authorVadim B. Mikheev <vadim4o@yahoo.com>
Thu, 21 Aug 1997 01:36:09 +0000 (01:36 +0000)
committerVadim B. Mikheev <vadim4o@yahoo.com>
Thu, 21 Aug 1997 01:36:09 +0000 (01:36 +0000)
src/backend/utils/cache/relcache.c

index 69e34d3aa4c8f6c100dff83ce07f8b7401c3c9ba..8cb08e6ab128d7b33f054fc6747d8d002e6f159a 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *    $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.16 1997/08/20 14:54:07 momjian Exp $
+ *    $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.17 1997/08/21 01:36:09 vadim Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -81,6 +81,7 @@
 #include "catalog/pg_variable.h"
 #include "catalog/pg_log.h"
 #include "catalog/pg_time.h"
+#include "catalog/pg_attrdef.h"
 #include "catalog/indexing.h"
 #include "catalog/index.h"
 #include "fmgr.h"
@@ -90,22 +91,6 @@ static void RelationFlushRelation(Relation *relationPtr,
 static Relation RelationNameCacheGetRelation(char *relationName);
 static void init_irels(void);
 static void write_irels(void);
-/* non-export function prototypes */
-static void formrdesc(char *relationName, u_int natts,
-                     FormData_pg_attribute att[]);
-static HeapTuple ScanPgRelation(RelationBuildDescInfo buildinfo);
-static HeapTuple scan_pg_rel_seq(RelationBuildDescInfo buildinfo);
-static HeapTuple scan_pg_rel_ind(RelationBuildDescInfo buildinfo);
-static Relation AllocateRelationDesc(u_int natts, Form_pg_class relp);
-static void RelationBuildTupleDesc(RelationBuildDescInfo buildinfo,    
-               Relation relation, AttributeTupleForm attp, u_int natts);
-static void build_tupdesc_seq(RelationBuildDescInfo buildinfo,
-               Relation relation, AttributeTupleForm attp, u_int natts);
-static void build_tupdesc_ind(RelationBuildDescInfo buildinfo,
-               Relation relation, AttributeTupleForm attp, u_int natts);
-static Relation RelationBuildDesc(RelationBuildDescInfo buildinfo);
-static void IndexedAccessMethodInitialize(Relation relation);
-
 
 /* ----------------
  *     defines
@@ -254,6 +239,28 @@ typedef struct relnamecacheent {
          } \
     }
 
+/* non-export function prototypes */
+static void formrdesc(char *relationName, u_int natts,
+                     FormData_pg_attribute att[]);
+
+#if 0          /* See comments at line 1304 */
+static void RelationFlushIndexes(Relation *r, Oid accessMethodId);
+#endif
+
+static HeapTuple ScanPgRelation(RelationBuildDescInfo buildinfo);
+static HeapTuple scan_pg_rel_seq(RelationBuildDescInfo buildinfo);
+static HeapTuple scan_pg_rel_ind(RelationBuildDescInfo buildinfo);
+static Relation AllocateRelationDesc(u_int natts, Form_pg_class relp);
+static void RelationBuildTupleDesc(RelationBuildDescInfo buildinfo,    
+               Relation relation, u_int natts);
+static void build_tupdesc_seq(RelationBuildDescInfo buildinfo,
+               Relation relation, u_int natts);
+static void build_tupdesc_ind(RelationBuildDescInfo buildinfo,
+               Relation relation, u_int natts);
+static Relation RelationBuildDesc(RelationBuildDescInfo buildinfo);
+static void IndexedAccessMethodInitialize(Relation relation);
+static void AttrDefaultFetch (Relation relation);
+
 /*
  * newlyCreatedRelns -
  *    relations created during this transaction. We need to keep track of
@@ -268,7 +275,7 @@ static List *newlyCreatedRelns = NULL;
  */
  
 
-#ifdef NOT_USED                /* XXX This doesn't seem to be used anywhere */
+#if NOT_USED           /* XXX This doesn't seem to be used anywhere */
 /* --------------------------------
  *     BuildDescInfoError returns a string appropriate to
  *     the buildinfo passed to it
@@ -481,7 +488,6 @@ AllocateRelationDesc(u_int natts, Form_pg_class relp)
 static void
 RelationBuildTupleDesc(RelationBuildDescInfo buildinfo,    
                       Relation relation,
-                      AttributeTupleForm attp,
                       u_int natts)
 {
     /*
@@ -491,20 +497,26 @@ RelationBuildTupleDesc(RelationBuildDescInfo buildinfo,
      */
     
     if (IsBootstrapProcessingMode())
-       build_tupdesc_seq(buildinfo, relation, attp, natts);
+       build_tupdesc_seq(buildinfo, relation, natts);
     else
-       build_tupdesc_ind(buildinfo, relation, attp, natts);
+    {
+       relation->rd_att->constr = (AttrConstr *) palloc(sizeof(struct attrConstr));
+       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
 build_tupdesc_seq(RelationBuildDescInfo buildinfo,
                  Relation relation,
-                 AttributeTupleForm attp,
                  u_int natts)
 {
     HeapTuple    pg_attribute_tuple;
     Relation    pg_attribute_desc;
     HeapScanDesc pg_attribute_scan;
+    AttributeTupleForm attp;
     ScanKeyData         key;
     int                 need;
                                    
@@ -530,9 +542,6 @@ build_tupdesc_seq(RelationBuildDescInfo buildinfo,
      * ----------------
      */
     need = natts;
-    if (!relation->rd_att->constr)
-      relation->rd_att->constr = (AttrConstr *) palloc(sizeof(struct attrConstr));
-    relation->rd_att->constr->has_not_null = false;
 
     pg_attribute_tuple = heap_getnext(pg_attribute_scan, 0, (Buffer *) NULL);
     while (HeapTupleIsValid(pg_attribute_tuple) && need > 0) {
@@ -545,11 +554,6 @@ build_tupdesc_seq(RelationBuildDescInfo buildinfo,
            memmove((char *) (relation->rd_att->attrs[attp->attnum - 1]),
                    (char *) attp,
                    ATTRIBUTE_TUPLE_SIZE);
-
-            /* Update if this attribute have a constraint */
-            if (attp->attnotnull)
-             relation->rd_att->constr->has_not_null = true;
-           
            need--;
        }
        pg_attribute_tuple = heap_getnext(pg_attribute_scan,
@@ -571,17 +575,15 @@ build_tupdesc_seq(RelationBuildDescInfo buildinfo,
 static void
 build_tupdesc_ind(RelationBuildDescInfo buildinfo,
                  Relation      relation,
-                 AttributeTupleForm attp,
                  u_int natts)
 {
     Relation attrel;
     HeapTuple atttup;
+    AttributeTupleForm attp;
+    AttrDefault        *attrdef = NULL;
+    int ndef = 0;
     int i;
 
-    if (!relation->rd_att->constr)
-      relation->rd_att->constr = (AttrConstr *) palloc(sizeof(struct attrConstr));
-    relation->rd_att->constr->has_not_null = false;
-     
     attrel = heap_openr(AttributeRelationName);
     
     for (i = 1; i <= relation->rd_rel->relnatts; i++) {
@@ -589,8 +591,8 @@ build_tupdesc_ind(RelationBuildDescInfo buildinfo,
        atttup = (HeapTuple) AttributeNumIndexScan(attrel, relation->rd_id, i);
        
        if (!HeapTupleIsValid(atttup))
-           elog(WARN, "cannot find attribute %d of relation %.16s", i,
-                &(relation->rd_rel->relname.data[0]));
+           elog(WARN, "cannot find attribute %d of relation %.*s", i,
+                NAMEDATALEN, &(relation->rd_rel->relname.data[0]));
        attp = (AttributeTupleForm) GETSTRUCT(atttup);
        
        relation->rd_att->attrs[i - 1] = 
@@ -602,10 +604,33 @@ build_tupdesc_ind(RelationBuildDescInfo buildinfo,
 
        /* Update if this attribute have a constraint */
        if (attp->attnotnull)
-         relation->rd_att->constr->has_not_null = true;
+           relation->rd_att->constr->has_not_null = true;
+       
+       if (attp->atthasdef)
+       {
+           if ( attrdef == NULL )
+               attrdef = (AttrDefault*) palloc (relation->rd_rel->relnatts *
+                                               sizeof (AttrDefault));
+           attrdef[ndef].adnum = i;
+           attrdef[ndef].adbin = NULL;
+           attrdef[ndef].adsrc = NULL;
+           ndef++;
+       }
     }
     
     heap_close(attrel);
+
+    if ( ndef > 0 )
+    {
+       if ( ndef > relation->rd_rel->relnatts )
+           relation->rd_att->constr->defval = (AttrDefault*) 
+                       repalloc (attrdef, ndef * sizeof (AttrDefault));
+       else
+           relation->rd_att->constr->defval = attrdef;
+       relation->rd_att->constr->num_defval = ndef;
+       AttrDefaultFetch (relation);
+    }
+    
 }
 
 /* --------------------------------
@@ -759,7 +784,6 @@ RelationBuildDesc(RelationBuildDescInfo buildinfo)
     Oid                        relid;
     Oid                        relam;
     Form_pg_class      relp;
-    AttributeTupleForm attp = NULL;
     
     MemoryContext      oldcxt;
     
@@ -834,7 +858,7 @@ RelationBuildDesc(RelationBuildDescInfo buildinfo)
      *  already allocated for it by AllocateRelationDesc.
      * ----------------
      */
-    RelationBuildTupleDesc(buildinfo, relation, attp, natts);
+    RelationBuildTupleDesc(buildinfo, relation, natts);
 
     /* ----------------
      *  initialize rules that affect this relation
@@ -1346,7 +1370,7 @@ RelationIdInvalidateRelationCacheByRelationId(Oid relationId)
     }
 }
 
-#ifdef NOT_USED                /* See comments at line 1304 */
+#if NOT_USED           /* See comments at line 1304 */
 /* --------------------------------
  *     RelationIdInvalidateRelationCacheByAccessMethodId
  *
@@ -1576,6 +1600,95 @@ RelationInitialize(void)
     MemoryContextSwitchTo(oldcxt);
 }
 
+static void
+AttrDefaultFetch (Relation relation)
+{
+    AttrDefault *attrdef = relation->rd_att->constr->defval;
+    int ndef = relation->rd_att->constr->num_defval;
+    Relation adrel;
+    Relation irel;
+    ScanKeyData skey;
+    HeapTuple tuple;
+    Form_pg_attrdef adform;
+    IndexScanDesc sd;
+    RetrieveIndexResult indexRes;
+    Buffer buffer;
+    ItemPointer iptr;
+    struct varlena *val;
+    bool isnull;
+    int found;
+    int i;
+    
+    ScanKeyEntryInitialize(&skey,
+                          (bits16)0x0,
+                          (AttrNumber)1,
+                          (RegProcedure)ObjectIdEqualRegProcedure,
+                          ObjectIdGetDatum(relation->rd_id));
+    
+    adrel = heap_openr(AttrDefaultRelationName);
+    irel = index_openr(AttrDefaultIndex);
+    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(adrel, NowTimeQual, iptr, &buffer);
+       pfree(indexRes);
+       if (!HeapTupleIsValid(tuple))
+           continue;
+       adform = (Form_pg_attrdef) GETSTRUCT(tuple);
+       for (i = 1; i <= ndef; i++)
+       {
+           if ( adform->adnum != attrdef[i].adnum )
+               continue;
+           if ( attrdef[i].adsrc != NULL )
+                   elog (WARN, "AttrDefaultFetch: second record found for attr %.*s in rel %.*s",
+                       NAMEDATALEN, relation->rd_att->attrs[adform->adnum - 1]->attname.data,
+                       NAMEDATALEN, relation->rd_rel->relname.data);
+           
+           val = (struct varlena*) fastgetattr (tuple, 
+                                               Anum_pg_attrdef_adbin,
+                                               adrel->rd_att, &isnull);
+           if ( isnull )
+               elog (WARN, "AttrDefaultFetch: adbin IS NULL for attr %.*s in rel %.*s",
+                   NAMEDATALEN, relation->rd_att->attrs[adform->adnum - 1]->attname.data,
+                   NAMEDATALEN, relation->rd_rel->relname.data);
+           attrdef[i].adbin = textout (val);
+           val = (struct varlena*) fastgetattr (tuple, 
+                                               Anum_pg_attrdef_adsrc,
+                                               adrel->rd_att, &isnull);
+           if ( isnull )
+               elog (WARN, "AttrDefaultFetch: adsrc IS NULL for attr %.*s in rel %.*s",
+                   NAMEDATALEN, relation->rd_att->attrs[adform->adnum - 1]->attname.data,
+                   NAMEDATALEN, relation->rd_rel->relname.data);
+           attrdef[i].adsrc = textout (val);
+           found++;
+       }
+       
+       if ( i > ndef )
+           elog (WARN, "AttrDefaultFetch: unexpected record found for attr %d in rel %.*s",
+                       adform->adnum,
+                       NAMEDATALEN, relation->rd_rel->relname.data);
+       ReleaseBuffer(buffer);
+    }
+    
+    if ( found < ndef )
+       elog (WARN, "AttrDefaultFetch: %d record not found for rel %.*s",
+                       ndef - found,
+                       NAMEDATALEN, relation->rd_rel->relname.data);
+    
+    index_endscan (sd);
+    pfree (sd);
+    index_close (irel);
+    heap_close (adrel);
+    
+}
+
 /*
  *  init_irels(), write_irels() -- handle special-case initialization of
  *                                index relation descriptors.