From: Vadim B. Mikheev Date: Fri, 22 Aug 1997 03:03:56 +0000 (+0000) Subject: DefineRelation: DEFAULT/CHECK handling X-Git-Tag: REL9_0_0~28536 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=b5b3e03e34cfc8c5db31b90f329924b3f5036209;p=pg-rex%2Fsyncrep.git DefineRelation: DEFAULT/CHECK handling --- diff --git a/src/backend/commands/creatinh.c b/src/backend/commands/creatinh.c index c343e07370..248aaa3e76 100644 --- a/src/backend/commands/creatinh.c +++ b/src/backend/commands/creatinh.c @@ -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; } -