8
8
*
9
9
*
10
10
* 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 $
12
12
*
13
13
*-------------------------------------------------------------------------
14
14
*/
34
34
35
35
static int checkAttrExists (const char * attributeName ,
36
36
const 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 );
38
39
static void StoreCatalogInheritance (Oid relationId , List * supers );
39
- static void
40
- setRelhassubclassInRelation (Oid relationId , bool relhassubclass );
40
+ static void setRelhassubclassInRelation (Oid relationId , bool relhassubclass );
41
41
42
42
43
43
/* ----------------------------------------------------------------
@@ -53,8 +53,8 @@ DefineRelation(CreateStmt *stmt, char relkind)
53
53
int numberOfAttributes ;
54
54
Oid relationId ;
55
55
Relation rel ;
56
- List * inheritList ;
57
56
TupleDesc descriptor ;
57
+ List * inheritOids ;
58
58
List * old_constraints ;
59
59
List * rawDefaults ;
60
60
List * listptr ;
@@ -67,24 +67,16 @@ DefineRelation(CreateStmt *stmt, char relkind)
67
67
StrNCpy (relname , stmt -> relname , NAMEDATALEN );
68
68
69
69
/* ----------------
70
- * Handle parameters
71
- * XXX parameter handling missing below .
70
+ * Look up inheritance ancestors and generate relation schema,
71
+ * including inherited attributes .
72
72
* ----------------
73
73
*/
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 );
81
76
82
77
numberOfAttributes = length (schema );
83
78
if (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" );
88
80
89
81
/* ----------------
90
82
* create a relation descriptor from the relation schema
@@ -147,7 +139,7 @@ DefineRelation(CreateStmt *stmt, char relkind)
147
139
relkind , stmt -> istemp ,
148
140
allowSystemTableMods );
149
141
150
- StoreCatalogInheritance (relationId , inheritList );
142
+ StoreCatalogInheritance (relationId , inheritOids );
151
143
152
144
/*
153
145
* 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)
286
278
* MergeAttributes
287
279
* Returns new schema given initial schema and supers.
288
280
*
281
+ * Input arguments:
289
282
*
290
283
* 'schema' is the column/attribute definition for the table. (It's a list
291
284
* 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.
293
290
*
294
291
* Notes:
295
292
* 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)
314
311
* stud_emp {7:percent}
315
312
*/
316
313
static List *
317
- MergeAttributes (List * schema , List * supers , List * * supconstr )
314
+ MergeAttributes (List * schema , List * supers ,
315
+ List * * supOids , List * * supconstr )
318
316
{
319
317
List * entry ;
320
318
List * inhSchema = NIL ;
319
+ List * parentOids = NIL ;
321
320
List * constraints = NIL ;
322
- int attnums ;
321
+ int attnums ;
323
322
324
323
/*
325
324
* Validates that there are no duplications. Validity checking of
@@ -338,7 +337,7 @@ MergeAttributes(List *schema, List *supers, List **supconstr)
338
337
*/
339
338
ColumnDef * restdef = lfirst (rest );
340
339
341
- if (! strcmp (coldef -> colname , restdef -> colname ))
340
+ if (strcmp (coldef -> colname , restdef -> colname ) == 0 )
342
341
{
343
342
elog (ERROR , "CREATE TABLE: attribute \"%s\" duplicated" ,
344
343
coldef -> colname );
@@ -351,7 +350,7 @@ MergeAttributes(List *schema, List *supers, List **supconstr)
351
350
352
351
foreach (rest , lnext (entry ))
353
352
{
354
- if (! strcmp (strVal (lfirst (entry )), strVal (lfirst (rest ))))
353
+ if (strcmp (strVal (lfirst (entry )), strVal (lfirst (rest ))) == 0 )
355
354
{
356
355
elog (ERROR , "CREATE TABLE: inherited relation \"%s\" duplicated" ,
357
356
strVal (lfirst (entry )));
@@ -376,6 +375,11 @@ MergeAttributes(List *schema, List *supers, List **supconstr)
376
375
int i , attidx , attno_exist ;
377
376
378
377
relation = 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 );
379
383
setRelhassubclassInRelation (relation -> rd_id , true);
380
384
tupleDesc = RelationGetDescr (relation );
381
385
/* allocate a new attribute number table and initialize */
@@ -391,9 +395,6 @@ MergeAttributes(List *schema, List *supers, List **supconstr)
391
395
partialAttidx [i ] = 0 ;
392
396
constr = tupleDesc -> constr ;
393
397
394
- if (relation -> rd_rel -> relkind != RELKIND_RELATION )
395
- elog (ERROR , "CREATE TABLE: inherited relation \"%s\" is not a table" , name );
396
-
397
398
attidx = 0 ;
398
399
for (attrno = relation -> rd_rel -> relnatts - 1 ; attrno >= 0 ; attrno -- )
399
400
{
@@ -519,13 +520,18 @@ MergeAttributes(List *schema, List *supers, List **supconstr)
519
520
* put the inherited schema before our the schema for this table
520
521
*/
521
522
schema = nconc (inhSchema , schema );
523
+
524
+ * supOids = parentOids ;
522
525
* supconstr = constraints ;
523
526
return schema ;
524
527
}
525
528
526
529
/*
527
530
* StoreCatalogInheritance
528
531
* 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.
529
535
*/
530
536
static void
531
537
StoreCatalogInheritance (Oid relationId , List * supers )
@@ -534,7 +540,6 @@ StoreCatalogInheritance(Oid relationId, List *supers)
534
540
TupleDesc desc ;
535
541
int16 seqNumber ;
536
542
List * entry ;
537
- List * idList ;
538
543
HeapTuple tuple ;
539
544
540
545
/* ----------------
@@ -547,32 +552,19 @@ StoreCatalogInheritance(Oid relationId, List *supers)
547
552
return ;
548
553
549
554
/* ----------------
550
- * Catalog INHERITS information.
555
+ * Catalog INHERITS information using direct ancestors only .
551
556
* ----------------
552
557
*/
553
558
relation = heap_openr (InheritsRelationName , RowExclusiveLock );
554
559
desc = RelationGetDescr (relation );
555
560
556
561
seqNumber = 1 ;
557
- idList = NIL ;
558
562
foreach (entry , supers )
559
563
{
560
- Oid entryOid ;
564
+ Oid entryOid = lfirsti ( entry ) ;
561
565
Datum datum [Natts_pg_inherits ];
562
566
char nullarr [Natts_pg_inherits ];
563
567
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
-
576
568
datum [0 ] = ObjectIdGetDatum (relationId ); /* inhrel */
577
569
datum [1 ] = ObjectIdGetDatum (entryOid ); /* inhparent */
578
570
datum [2 ] = Int16GetDatum (seqNumber ); /* inhseqno */
@@ -602,21 +594,20 @@ StoreCatalogInheritance(Oid relationId, List *supers)
602
594
heap_close (relation , RowExclusiveLock );
603
595
604
596
/* ----------------
605
- * Catalog IPL information .
597
+ * Expand supers list to include indirect ancestors as well .
606
598
*
607
599
* Algorithm:
608
- * 0. list superclasses (by Oid) in order given (see idList) .
600
+ * 0. begin with list of direct superclasses .
609
601
* 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.
612
603
* ----------------
613
604
*/
614
605
615
606
/* ----------------
616
- * 1.
607
+ * 1. append after each relationId, its superclasses, recursively.
617
608
* ----------------
618
609
*/
619
- foreach (entry , idList )
610
+ foreach (entry , supers )
620
611
{
621
612
HeapTuple tuple ;
622
613
Oid id ;
@@ -649,20 +640,21 @@ StoreCatalogInheritance(Oid relationId, List *supers)
649
640
}
650
641
651
642
/* ----------------
652
- * 2.
643
+ * 2. remove all but last of duplicates.
653
644
* ----------------
654
645
*/
655
- foreach (entry , idList )
646
+ foreach (entry , supers )
656
647
{
657
- Oid name ;
648
+ Oid thisone ;
649
+ bool found ;
658
650
List * rest ;
659
- bool found = false;
660
651
661
652
again :
662
- name = lfirsti (entry );
653
+ thisone = lfirsti (entry );
654
+ found = false;
663
655
foreach (rest , lnext (entry ))
664
656
{
665
- if (name == lfirsti (rest ))
657
+ if (thisone == lfirsti (rest ))
666
658
{
667
659
found = true;
668
660
break ;
@@ -672,28 +664,25 @@ StoreCatalogInheritance(Oid relationId, List *supers)
672
664
{
673
665
674
666
/*
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.
678
668
*/
679
- lfirst (entry ) = lfirst (lnext (entry ));
669
+ lfirsti (entry ) = lfirsti (lnext (entry ));
680
670
lnext (entry ) = lnext (lnext (entry ));
681
671
682
- found = false;
683
672
goto again ;
684
673
}
685
674
}
686
675
687
676
/* ----------------
688
- * 3 .
677
+ * Catalog IPL information using expanded list .
689
678
* ----------------
690
679
*/
691
680
relation = heap_openr (InheritancePrecidenceListRelationName , RowExclusiveLock );
692
681
desc = RelationGetDescr (relation );
693
682
694
683
seqNumber = 1 ;
695
684
696
- foreach (entry , idList )
685
+ foreach (entry , supers )
697
686
{
698
687
Datum datum [Natts_pg_ipl ];
699
688
char nullarr [Natts_pg_ipl ];
@@ -721,10 +710,12 @@ StoreCatalogInheritance(Oid relationId, List *supers)
721
710
722
711
723
712
/*
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.
725
715
*/
726
716
static int
727
- checkAttrExists (const char * attributeName , const char * attributeType , List * schema )
717
+ checkAttrExists (const char * attributeName , const char * attributeType ,
718
+ List * schema )
728
719
{
729
720
List * s ;
730
721
int i = 0 ;
0 commit comments