77 *
88 *
99 * IDENTIFICATION
10- * $Header: /cvsroot/pgsql/src/backend/commands/Attic/creatinh.c,v 1.13 1997/08/21 04:05:22 vadim Exp $
10+ * $Header: /cvsroot/pgsql/src/backend/commands/Attic/creatinh.c,v 1.14 1997/08/22 03:03:56 vadim Exp $
1111 *
1212 *-------------------------------------------------------------------------
1313 */
3535
3636static int checkAttrExists (char * attributeName ,
3737char * attributeType ,List * schema );
38- static List * MergeAttributes (List * schema ,List * supers );
38+ static List * MergeAttributes (List * schema ,List * supers , List * * supconstr );
3939static void StoreCatalogInheritance (Oid relationId ,List * supers );
4040
4141/* ----------------------------------------------------------------
@@ -46,15 +46,16 @@ static void StoreCatalogInheritance(Oid relationId, List *supers);
4646void
4747DefineRelation (CreateStmt * stmt )
4848{
49- char * relname = palloc (NAMEDATALEN );
50- List * schema = stmt -> tableElts ;
51- int numberOfAttributes ;
52- Oid relationId ;
53- char archChar ;
54- List * inheritList = NULL ;
55- char * archiveName = NULL ;
49+ char * relname = palloc (NAMEDATALEN );
50+ List * schema = stmt -> tableElts ;
51+ int numberOfAttributes ;
52+ Oid relationId ;
53+ char archChar ;
54+ List * inheritList = NULL ;
55+ char * archiveName = NULL ;
5656TupleDesc descriptor ;
57- int heaploc ,archloc ;
57+ List * constraints ;
58+ int heaploc ,archloc ;
5859
5960char * typename = NULL ;/* the typename of this relation. not useod for now */
6061
@@ -116,7 +117,8 @@ DefineRelation(CreateStmt *stmt)
116117 *generate relation schema, including inherited attributes.
117118 * ----------------
118119 */
119- schema = MergeAttributes (schema ,inheritList );
120+ schema = MergeAttributes (schema ,inheritList ,& constraints );
121+ constraints = nconc (constraints ,stmt -> constraints );
120122
121123numberOfAttributes = length (schema );
122124if (numberOfAttributes <=0 ) {
@@ -130,6 +132,55 @@ DefineRelation(CreateStmt *stmt)
130132 * ----------------
131133 */
132134descriptor = BuildDescForRelation (schema ,relname );
135+
136+ if (constraints != NIL )
137+ {
138+ List * entry ;
139+ int nconstr = length (constraints );
140+ ConstrCheck * check = (ConstrCheck * )palloc (nconstr * sizeof (ConstrCheck ));
141+ int ncheck = 0 ;
142+ int i ;
143+
144+ foreach (entry ,constraints )
145+ {
146+ ConstraintDef * cdef = (ConstraintDef * )lfirst (entry );
147+
148+ if (cdef -> type == CONSTR_CHECK )
149+ {
150+ if (cdef -> name != NULL )
151+ {
152+ for (i = 0 ;i < ncheck ;i ++ )
153+ {
154+ if (strcmp (check [i ].ccname ,cdef -> name )== 0 )
155+ elog (WARN ,"DefineRelation: name (%s) of CHECK constraint duplicated" ,cdef -> name );
156+ }
157+ check [ncheck ].ccname = cdef -> name ;
158+ }
159+ else
160+ {
161+ check [ncheck ].ccname = (char * )palloc (NAMEDATALEN );
162+ sprintf (check [ncheck ].ccname ,"$%d" ,ncheck + 1 );
163+ }
164+ check [ncheck ].ccbin = NULL ;
165+ check [ncheck ].ccsrc = (char * )cdef -> def ;
166+ ncheck ++ ;
167+ }
168+ }
169+ if (ncheck > 0 )
170+ {
171+ if (ncheck < nconstr )
172+ check = (ConstrCheck * )repalloc (check ,ncheck * sizeof (ConstrCheck ));
173+ if (descriptor -> constr == NULL )
174+ {
175+ descriptor -> constr = (TupleConstr * )palloc (sizeof (TupleConstr ));
176+ descriptor -> constr -> num_defval = 0 ;
177+ descriptor -> constr -> has_not_null = false;
178+ }
179+ descriptor -> constr -> num_check = ncheck ;
180+ descriptor -> constr -> check = check ;
181+ }
182+ }
183+
133184relationId = heap_create (relname ,
134185typename ,
135186archChar ,
@@ -138,11 +189,12 @@ DefineRelation(CreateStmt *stmt)
138189
139190StoreCatalogInheritance (relationId ,inheritList );
140191
141- /*----------------
192+ /*
142193 *create an archive relation if necessary
143- * ----------------
144194 */
145- if (archChar != 'n' ) {
195+ if (archChar != 'n' )
196+ {
197+ TupleDesc tupdesc ;
146198/*
147199 * Need to create an archive relation for this heap relation.
148200 * We cobble up the command by hand, and increment the command
@@ -152,12 +204,15 @@ DefineRelation(CreateStmt *stmt)
152204CommandCounterIncrement ();
153205archiveName = MakeArchiveName (relationId );
154206
155- relationId = heap_create (archiveName ,
156- typename ,
157- 'n' ,/* archive isn't archived */
158- archloc ,
159- descriptor );
207+ tupdesc = CreateTupleDescCopy (descriptor );/* get rid of constraints */
208+ (void )heap_create (archiveName ,
209+ typename ,
210+ 'n' ,/* archive isn't archived */
211+ archloc ,
212+ tupdesc );
160213
214+ FreeTupleDesc (tupdesc );
215+ FreeTupleDesc (descriptor );
161216pfree (archiveName );
162217 }
163218}
@@ -213,10 +268,11 @@ RemoveRelation(char *name)
213268 * stud_emp {7:percent}
214269 */
215270static List *
216- MergeAttributes (List * schema ,List * supers )
271+ MergeAttributes (List * schema ,List * supers , List * * supconstr )
217272{
218273List * entry ;
219274List * inhSchema = NIL ;
275+ List * constraints = NIL ;
220276
221277/*
222278 * Validates that there are no duplications.
@@ -258,6 +314,7 @@ MergeAttributes(List *schema, List *supers)
258314List * partialResult = NIL ;
259315AttrNumber attrno ;
260316TupleDesc tupleDesc ;
317+ TupleConstr * constr ;
261318
262319relation = heap_openr (name );
263320if (relation == NULL ) {
@@ -271,12 +328,12 @@ MergeAttributes(List *schema, List *supers)
271328name );
272329}
273330tupleDesc = RelationGetTupleDescriptor (relation );
331+ constr = tupleDesc -> constr ;
274332
275333for (attrno = relation -> rd_rel -> relnatts - 1 ;attrno >=0 ;attrno -- ) {
276334AttributeTupleForm attribute = tupleDesc -> attrs [attrno ];
277335char * attributeName ;
278336char * attributeType ;
279- TupleConstr constraints ;
280337HeapTuple tuple ;
281338ColumnDef * def ;
282339TypeName * typename ;
@@ -285,7 +342,6 @@ MergeAttributes(List *schema, List *supers)
285342 * form name, type and constraints
286343 */
287344attributeName = (attribute -> attname ).data ;
288- constraints .has_not_null = attribute -> attnotnull ;
289345tuple =
290346SearchSysCacheTuple (TYPOID ,
291347ObjectIdGetDatum (attribute -> atttypid ),
@@ -313,10 +369,46 @@ MergeAttributes(List *schema, List *supers)
313369def -> colname = pstrdup (attributeName );
314370typename -> name = pstrdup (attributeType );
315371def -> typename = typename ;
316- def -> is_not_null = constraints .has_not_null ;
372+ def -> is_not_null = attribute -> attnotnull ;
373+ def -> defval = NULL ;
374+ if (attribute -> atthasdef )
375+ {
376+ AttrDefault * attrdef = constr -> defval ;
377+ int i ;
378+
379+ Assert (constr != NULL && constr -> num_defval > 0 );
380+
381+ for (i = 0 ;i < constr -> num_defval ;i ++ )
382+ {
383+ if (attrdef [i ].adnum != attrno + 1 )
384+ continue ;
385+ def -> defval = pstrdup (attrdef [i ].adsrc );
386+ break ;
387+ }
388+ Assert (def -> defval != NULL );
389+ }
317390partialResult = lcons (def ,partialResult );
318391}
319392
393+ if (constr && constr -> num_check > 0 )
394+ {
395+ ConstrCheck * check = constr -> check ;
396+ int i ;
397+
398+ for (i = 0 ;i < constr -> num_check ;i ++ )
399+ {
400+ ConstraintDef * cdef = (ConstraintDef * )palloc (sizeof (ConstraintDef ));
401+
402+ cdef -> type = CONSTR_CHECK ;
403+ if (check [i ].ccname [0 ]== '$' )
404+ cdef -> name = NULL ;
405+ else
406+ cdef -> name = pstrdup (check [i ].ccname );
407+ cdef -> def = (void * )pstrdup (check [i ].ccsrc );
408+ constraints = lappend (constraints ,cdef );
409+ }
410+ }
411+
320412/*
321413 * iteration cleanup and result collection
322414 */
@@ -333,7 +425,7 @@ MergeAttributes(List *schema, List *supers)
333425 * put the inherited schema before our the schema for this table
334426 */
335427schema = nconc (inhSchema ,schema );
336-
428+ * supconstr = constraints ;
337429return (schema );
338430}
339431
@@ -557,4 +649,3 @@ MakeArchiveName(Oid relationId)
557649
558650return arch ;
559651}
560-