DefineRelation: DEFAULT/CHECK handling
authorVadim B. Mikheev
Fri, 22 Aug 1997 03:03:56 +0000 (03:03 +0000)
committerVadim B. Mikheev
Fri, 22 Aug 1997 03:03:56 +0000 (03:03 +0000)
src/backend/commands/creatinh.c

index c343e073703a4629d2c7b9f73d5391e4747d4949..248aaa3e768e1160c695132450cc205fecbaf725 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *    $Header: /cvsroot/pgsql/src/backend/commands/Attic/creatinh.c,v 1.13 1997/08/21 04:05:22 vadim Exp $
+ *    $Header: /cvsroot/pgsql/src/backend/commands/Attic/creatinh.c,v 1.14 1997/08/22 03:03:56 vadim Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -35,7 +35,7 @@
 
 static int checkAttrExists(char *attributeName, 
               char *attributeType, List *schema);
-static List *MergeAttributes(List *schema, List *supers);
+static List *MergeAttributes(List *schema, List *supers, List **supconstr);
 static void StoreCatalogInheritance(Oid relationId, List *supers);
 
 /* ----------------------------------------------------------------
@@ -46,15 +46,16 @@ static void StoreCatalogInheritance(Oid relationId, List *supers);
 void
 DefineRelation(CreateStmt *stmt)
 {
-    char *relname = palloc(NAMEDATALEN);
-    List *schema = stmt->tableElts;
-    int            numberOfAttributes;
-    Oid            relationId;
-    char       archChar;
-    List       *inheritList    = NULL;
-    char *archiveName  = NULL;
+    char   *relname = palloc(NAMEDATALEN);
+    List   *schema = stmt->tableElts;
+    int        numberOfAttributes;
+    Oid        relationId;
+    char   archChar;
+    List   *inheritList    = NULL;
+    char   *archiveName    = NULL;
     TupleDesc  descriptor;
-    int            heaploc, archloc;
+    List   *constraints;
+    int        heaploc, archloc;
     
     char*   typename = NULL;  /* the typename of this relation. not useod for now */
 
@@ -116,7 +117,8 @@ DefineRelation(CreateStmt *stmt)
      * generate relation schema, including inherited attributes.
      * ----------------
      */
-    schema = MergeAttributes(schema, inheritList);
+    schema = MergeAttributes(schema, inheritList, &constraints);
+    constraints = nconc (constraints, stmt->constraints);
     
     numberOfAttributes = length(schema);
     if (numberOfAttributes <= 0) {
@@ -130,6 +132,55 @@ DefineRelation(CreateStmt *stmt)
      * ----------------
      */
     descriptor = BuildDescForRelation(schema, relname);
+    
+    if ( constraints != NIL )
+    {
+       List *entry;
+       int nconstr = length (constraints);
+       ConstrCheck *check = (ConstrCheck *) palloc (nconstr * sizeof (ConstrCheck));
+       int ncheck = 0;
+       int i;
+       
+       foreach (entry, constraints)
+       {
+           ConstraintDef *cdef = (ConstraintDef *) lfirst (entry);
+           
+           if ( cdef->type == CONSTR_CHECK )
+           {
+               if ( cdef->name != NULL )
+               {
+                   for (i = 0; i < ncheck; i++)
+                   {
+                       if ( strcmp (check[i].ccname, cdef->name) == 0 )
+                           elog (WARN, "DefineRelation: name (%s) of CHECK constraint duplicated", cdef->name);
+                   }
+                   check[ncheck].ccname = cdef->name;
+               }
+               else
+               {
+                   check[ncheck].ccname = (char*) palloc (NAMEDATALEN);
+                   sprintf (check[ncheck].ccname, "$%d", ncheck + 1);
+               }
+               check[ncheck].ccbin = NULL;
+               check[ncheck].ccsrc = (char*) cdef->def;
+               ncheck++;
+           }
+       }
+       if ( ncheck > 0 )
+       {
+           if ( ncheck < nconstr )
+               check = (ConstrCheck *) repalloc (check, ncheck * sizeof (ConstrCheck));
+           if ( descriptor->constr == NULL )
+           {
+               descriptor->constr = (TupleConstr *) palloc(sizeof(TupleConstr));
+               descriptor->constr->num_defval = 0;
+               descriptor->constr->has_not_null = false;
+           }
+           descriptor->constr->num_check = ncheck;
+           descriptor->constr->check = check;
+       }
+    }
+    
     relationId = heap_create(relname,
                 typename,
                 archChar,
@@ -138,11 +189,12 @@ DefineRelation(CreateStmt *stmt)
     
     StoreCatalogInheritance(relationId, inheritList);
     
-    /* ----------------
+    /* 
      * create an archive relation if necessary
-     * ----------------
      */
-    if (archChar != 'n') {
+    if (archChar != 'n')
+    {
+       TupleDesc tupdesc;
    /*
     *  Need to create an archive relation for this heap relation.
     *  We cobble up the command by hand, and increment the command
@@ -152,12 +204,15 @@ DefineRelation(CreateStmt *stmt)
    CommandCounterIncrement();
    archiveName = MakeArchiveName(relationId);
    
-   relationId = heap_create(archiveName,
-                typename,
-                'n',       /* archive isn't archived */
-                archloc,
-                descriptor);
+   tupdesc = CreateTupleDescCopy (descriptor); /* get rid of constraints */
+   (void) heap_create(archiveName,
+              typename,
+              'n',     /* archive isn't archived */
+               archloc,
+               tupdesc);
    
+   FreeTupleDesc (tupdesc);
+   FreeTupleDesc (descriptor);
    pfree(archiveName);
     }
 }
@@ -213,10 +268,11 @@ RemoveRelation(char *name)
  *                         stud_emp {7:percent}
  */
 static List *
-MergeAttributes(List *schema, List *supers)
+MergeAttributes(List *schema, List *supers, List **supconstr)
 {
     List *entry;
     List *inhSchema = NIL;
+    List *constraints = NIL;
     
     /*
      * Validates that there are no duplications.
@@ -258,6 +314,7 @@ MergeAttributes(List *schema, List *supers)
    List        *partialResult = NIL;
    AttrNumber  attrno;
    TupleDesc   tupleDesc;
+   TupleConstr     *constr;
    
    relation =  heap_openr(name);
    if (relation==NULL) {
@@ -271,12 +328,12 @@ MergeAttributes(List *schema, List *supers)
         name);
    }
    tupleDesc = RelationGetTupleDescriptor(relation);
+   constr = tupleDesc->constr;
    
    for (attrno = relation->rd_rel->relnatts - 1; attrno >= 0; attrno--) {
        AttributeTupleForm  attribute = tupleDesc->attrs[attrno];
        char *attributeName;
        char *attributeType;
-       TupleConstr  constraints;
        HeapTuple   tuple;
        ColumnDef   *def;
        TypeName    *typename;
@@ -285,7 +342,6 @@ MergeAttributes(List *schema, List *supers)
         * form name, type and constraints
         */
        attributeName = (attribute->attname).data;
-            constraints.has_not_null = attribute->attnotnull;
        tuple =
        SearchSysCacheTuple(TYPOID,
                    ObjectIdGetDatum(attribute->atttypid),
@@ -313,10 +369,46 @@ MergeAttributes(List *schema, List *supers)
        def->colname = pstrdup(attributeName);
        typename->name = pstrdup(attributeType); 
        def->typename = typename;
-       def->is_not_null = constraints.has_not_null;
+       def->is_not_null = attribute->attnotnull;
+       def->defval = NULL;
+       if ( attribute->atthasdef )
+       {
+           AttrDefault *attrdef = constr->defval;
+           int i;
+           
+           Assert ( constr != NULL && constr->num_defval > 0 );
+           
+           for (i = 0; i < constr->num_defval; i++)
+           {
+               if ( attrdef[i].adnum != attrno + 1 )
+                   continue;
+               def->defval = pstrdup (attrdef[i].adsrc);
+               break;
+           }
+           Assert ( def->defval != NULL );
+       }
             partialResult = lcons(def, partialResult);
    }
    
+   if ( constr && constr->num_check > 0 )
+   {
+       ConstrCheck *check = constr->check;
+       int i;
+       
+       for (i = 0; i < constr->num_check; i++)
+       {
+           ConstraintDef *cdef = (ConstraintDef *) palloc (sizeof (ConstraintDef));
+           
+           cdef->type = CONSTR_CHECK;
+           if ( check[i].ccname[0] == '$' )
+               cdef->name = NULL;
+           else
+               cdef->name = pstrdup (check[i].ccname);
+           cdef->def = (void*) pstrdup (check[i].ccsrc);
+           constraints = lappend (constraints, cdef);
+       }
+   }
+   
    /*
     * iteration cleanup and result collection
     */
@@ -333,7 +425,7 @@ MergeAttributes(List *schema, List *supers)
      * put the inherited schema before our the schema for this table
      */
     schema = nconc(inhSchema, schema);
-    
+    *supconstr = constraints;
     return (schema);
 }
 
@@ -557,4 +649,3 @@ MakeArchiveName(Oid relationId)
 
     return arch;
 }
-