88 *
99 *
1010 * IDENTIFICATION
11- * $Header: /cvsroot/pgsql/src/backend/commands/Attic/creatinh.c,v 1.67 2000/11/16 22:30:18 tgl Exp $
11+ * $Header: /cvsroot/pgsql/src/backend/commands/Attic/creatinh.c,v 1.68 2000/12/14 00:41:09 tgl Exp $
1212 *
1313 *-------------------------------------------------------------------------
1414 */
3434
3535static int checkAttrExists (const char * attributeName ,
3636const char * attributeType ,List * schema );
37- static List * MergeAttributes (List * schema ,List * supers ,List * * supconstr );
37+ static List * MergeAttributes (List * schema ,List * supers ,
38+ List * * supOids ,List * * supconstr );
3839static void StoreCatalogInheritance (Oid relationId ,List * supers );
39- static void
40- setRelhassubclassInRelation (Oid relationId ,bool relhassubclass );
40+ static void setRelhassubclassInRelation (Oid relationId ,bool relhassubclass );
4141
4242
4343/* ----------------------------------------------------------------
@@ -53,8 +53,8 @@ DefineRelation(CreateStmt *stmt, char relkind)
5353int numberOfAttributes ;
5454Oid relationId ;
5555Relation rel ;
56- List * inheritList ;
5756TupleDesc descriptor ;
57+ List * inheritOids ;
5858List * old_constraints ;
5959List * rawDefaults ;
6060List * listptr ;
@@ -67,24 +67,16 @@ DefineRelation(CreateStmt *stmt, char relkind)
6767StrNCpy (relname ,stmt -> relname ,NAMEDATALEN );
6868
6969/* ----------------
70- *Handle parameters
71- *XXX parameter handling missing below .
70+ *Look up inheritance ancestors and generate relation schema,
71+ *including inherited attributes .
7272 * ----------------
7373 */
74- inheritList = stmt -> inhRelnames ;
75-
76- /* ----------------
77- *generate relation schema, including inherited attributes.
78- * ----------------
79- */
80- schema = MergeAttributes (schema ,inheritList ,& old_constraints );
74+ schema = MergeAttributes (schema ,stmt -> inhRelnames ,
75+ & inheritOids ,& old_constraints );
8176
8277numberOfAttributes = length (schema );
8378if (numberOfAttributes <=0 )
84- {
85- elog (ERROR ,"DefineRelation: %s" ,
86- "please inherit from a relation or define an attribute" );
87- }
79+ elog (ERROR ,"DefineRelation: please inherit from a relation or define an attribute" );
8880
8981/* ----------------
9082 *create a relation descriptor from the relation schema
@@ -147,7 +139,7 @@ DefineRelation(CreateStmt *stmt, char relkind)
147139relkind ,stmt -> istemp ,
148140allowSystemTableMods );
149141
150- StoreCatalogInheritance (relationId ,inheritList );
142+ StoreCatalogInheritance (relationId ,inheritOids );
151143
152144/*
153145 * We must bump the command counter to make the newly-created relation
@@ -286,10 +278,15 @@ change_varattnos_of_a_node(Node *node, const AttrNumber *newattno)
286278 * MergeAttributes
287279 *Returns new schema given initial schema and supers.
288280 *
281+ * Input arguments:
289282 *
290283 * 'schema' is the column/attribute definition for the table. (It's a list
291284 *of ColumnDef's.) It is destructively changed.
292- * 'inheritList' is the list of inherited relations (a list of Value(str)'s).
285+ * 'supers' is a list of names (as Value objects) of parent relations.
286+ *
287+ * Output arguments:
288+ * 'supOids' receives an integer list of the OIDs of the parent relations.
289+ * 'supconstr' receives a list of constraints belonging to the parents.
293290 *
294291 * Notes:
295292 * The order in which the attributes are inherited is very important.
@@ -314,12 +311,14 @@ change_varattnos_of_a_node(Node *node, const AttrNumber *newattno)
314311 * stud_emp {7:percent}
315312 */
316313static List *
317- MergeAttributes (List * schema ,List * supers ,List * * supconstr )
314+ MergeAttributes (List * schema ,List * supers ,
315+ List * * supOids ,List * * supconstr )
318316{
319317List * entry ;
320318List * inhSchema = NIL ;
319+ List * parentOids = NIL ;
321320List * constraints = NIL ;
322- int attnums ;
321+ int attnums ;
323322
324323/*
325324 * Validates that there are no duplications. Validity checking of
@@ -338,7 +337,7 @@ MergeAttributes(List *schema, List *supers, List **supconstr)
338337 */
339338ColumnDef * restdef = lfirst (rest );
340339
341- if (! strcmp (coldef -> colname ,restdef -> colname ))
340+ if (strcmp (coldef -> colname ,restdef -> colname )== 0 )
342341{
343342elog (ERROR ,"CREATE TABLE: attribute \"%s\" duplicated" ,
344343coldef -> colname );
@@ -351,7 +350,7 @@ MergeAttributes(List *schema, List *supers, List **supconstr)
351350
352351foreach (rest ,lnext (entry ))
353352{
354- if (! strcmp (strVal (lfirst (entry )),strVal (lfirst (rest ))))
353+ if (strcmp (strVal (lfirst (entry )),strVal (lfirst (rest )))== 0 )
355354{
356355elog (ERROR ,"CREATE TABLE: inherited relation \"%s\" duplicated" ,
357356strVal (lfirst (entry )));
@@ -376,6 +375,11 @@ MergeAttributes(List *schema, List *supers, List **supconstr)
376375int i ,attidx ,attno_exist ;
377376
378377relation = heap_openr (name ,AccessShareLock );
378+
379+ if (relation -> rd_rel -> relkind != RELKIND_RELATION )
380+ elog (ERROR ,"CREATE TABLE: inherited relation \"%s\" is not a table" ,name );
381+
382+ parentOids = lappendi (parentOids ,relation -> rd_id );
379383setRelhassubclassInRelation (relation -> rd_id , true);
380384tupleDesc = RelationGetDescr (relation );
381385/* allocate a new attribute number table and initialize */
@@ -391,9 +395,6 @@ MergeAttributes(List *schema, List *supers, List **supconstr)
391395partialAttidx [i ]= 0 ;
392396constr = tupleDesc -> constr ;
393397
394- if (relation -> rd_rel -> relkind != RELKIND_RELATION )
395- elog (ERROR ,"CREATE TABLE: inherited relation \"%s\" is not a table" ,name );
396-
397398attidx = 0 ;
398399for (attrno = relation -> rd_rel -> relnatts - 1 ;attrno >=0 ;attrno -- )
399400{
@@ -519,13 +520,18 @@ MergeAttributes(List *schema, List *supers, List **supconstr)
519520 * put the inherited schema before our the schema for this table
520521 */
521522schema = nconc (inhSchema ,schema );
523+
524+ * supOids = parentOids ;
522525* supconstr = constraints ;
523526return schema ;
524527}
525528
526529/*
527530 * StoreCatalogInheritance
528531 *Updates the system catalogs with proper inheritance information.
532+ *
533+ * supers is an integer list of the OIDs of the new relation's direct
534+ * ancestors. NB: it is destructively changed to include indirect ancestors.
529535 */
530536static void
531537StoreCatalogInheritance (Oid relationId ,List * supers )
@@ -534,7 +540,6 @@ StoreCatalogInheritance(Oid relationId, List *supers)
534540TupleDesc desc ;
535541int16 seqNumber ;
536542List * entry ;
537- List * idList ;
538543HeapTuple tuple ;
539544
540545/* ----------------
@@ -547,32 +552,19 @@ StoreCatalogInheritance(Oid relationId, List *supers)
547552return ;
548553
549554/* ----------------
550- * Catalog INHERITS information.
555+ * Catalog INHERITS information using direct ancestors only .
551556 * ----------------
552557 */
553558relation = heap_openr (InheritsRelationName ,RowExclusiveLock );
554559desc = RelationGetDescr (relation );
555560
556561seqNumber = 1 ;
557- idList = NIL ;
558562foreach (entry ,supers )
559563{
560- Oid entryOid ;
564+ Oid entryOid = lfirsti ( entry ) ;
561565Datum datum [Natts_pg_inherits ];
562566char nullarr [Natts_pg_inherits ];
563567
564- entryOid = GetSysCacheOid (RELNAME ,
565- PointerGetDatum (strVal (lfirst (entry ))),
566- 0 ,0 ,0 );
567- if (!OidIsValid (entryOid ))
568- elog (ERROR ,"StoreCatalogInheritance: cache lookup failed for relation \"%s\"" ,
569- strVal (lfirst (entry )));
570-
571- /*
572- * build idList for use below
573- */
574- idList = lappendi (idList ,entryOid );
575-
576568datum [0 ]= ObjectIdGetDatum (relationId );/* inhrel */
577569datum [1 ]= ObjectIdGetDatum (entryOid );/* inhparent */
578570datum [2 ]= Int16GetDatum (seqNumber );/* inhseqno */
@@ -602,21 +594,20 @@ StoreCatalogInheritance(Oid relationId, List *supers)
602594heap_close (relation ,RowExclusiveLock );
603595
604596/* ----------------
605- *Catalog IPL information .
597+ *Expand supers list to include indirect ancestors as well .
606598 *
607599 * Algorithm:
608- *0.list superclasses (by Oid) in order given (see idList) .
600+ *0.begin with list of direct superclasses .
609601 *1. append after each relationId, its superclasses, recursively.
610- *3. remove all but last of duplicates.
611- *4. store result.
602+ *2. remove all but last of duplicates.
612603 * ----------------
613604 */
614605
615606/* ----------------
616- *1.
607+ *1. append after each relationId, its superclasses, recursively.
617608 * ----------------
618609 */
619- foreach (entry ,idList )
610+ foreach (entry ,supers )
620611{
621612HeapTuple tuple ;
622613Oid id ;
@@ -649,20 +640,21 @@ StoreCatalogInheritance(Oid relationId, List *supers)
649640}
650641
651642/* ----------------
652- *2.
643+ *2. remove all but last of duplicates.
653644 * ----------------
654645 */
655- foreach (entry ,idList )
646+ foreach (entry ,supers )
656647{
657- Oid name ;
648+ Oid thisone ;
649+ bool found ;
658650List * rest ;
659- bool found = false;
660651
661652again :
662- name = lfirsti (entry );
653+ thisone = lfirsti (entry );
654+ found = false;
663655foreach (rest ,lnext (entry ))
664656{
665- if (name == lfirsti (rest ))
657+ if (thisone == lfirsti (rest ))
666658{
667659found = true;
668660break ;
@@ -672,28 +664,25 @@ StoreCatalogInheritance(Oid relationId, List *supers)
672664{
673665
674666/*
675- * entry list must be of length >= 2 or else no match
676- *
677- * so, remove this entry.
667+ * found a later duplicate, so remove this entry.
678668 */
679- lfirst (entry )= lfirst (lnext (entry ));
669+ lfirsti (entry )= lfirsti (lnext (entry ));
680670lnext (entry )= lnext (lnext (entry ));
681671
682- found = false;
683672gotoagain ;
684673}
685674}
686675
687676/* ----------------
688- *3 .
677+ * Catalog IPL information using expanded list .
689678 * ----------------
690679 */
691680relation = heap_openr (InheritancePrecidenceListRelationName ,RowExclusiveLock );
692681desc = RelationGetDescr (relation );
693682
694683seqNumber = 1 ;
695684
696- foreach (entry ,idList )
685+ foreach (entry ,supers )
697686{
698687Datum datum [Natts_pg_ipl ];
699688char nullarr [Natts_pg_ipl ];
@@ -721,10 +710,12 @@ StoreCatalogInheritance(Oid relationId, List *supers)
721710
722711
723712/*
724- * returns the index(star with 1) if attribute already exists in schema, 0 otherwise.
713+ * returns the index (starting with 1) if attribute already exists in schema,
714+ * 0 if it doesn't.
725715 */
726716static int
727- checkAttrExists (const char * attributeName ,const char * attributeType ,List * schema )
717+ checkAttrExists (const char * attributeName ,const char * attributeType ,
718+ List * schema )
728719{
729720List * s ;
730721int i = 0 ;