diff --git a/src/backend/commands/creatinh.c b/src/backend/commands/creatinh.c index 970782d6da30b8574bf9e385272ac9c3cd758280..33022515cb6ca331492c82ff63dc2d4f7e972dfe 100644 --- a/src/backend/commands/creatinh.c +++ b/src/backend/commands/creatinh.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/Attic/creatinh.c,v 1.67 2000/11/16 22:30:18 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/Attic/creatinh.c,v 1.68 2000/12/14 00:41:09 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -34,10 +34,10 @@ static int checkAttrExists(const char *attributeName, const char *attributeType, List *schema); -static List *MergeAttributes(List *schema, List *supers, List **supconstr); +static List *MergeAttributes(List *schema, List *supers, + List **supOids, List **supconstr); static void StoreCatalogInheritance(Oid relationId, List *supers); -static void -setRelhassubclassInRelation(Oid relationId, bool relhassubclass); +static void setRelhassubclassInRelation(Oid relationId, bool relhassubclass); /* ---------------------------------------------------------------- @@ -53,8 +53,8 @@ DefineRelation(CreateStmt *stmt, char relkind) int numberOfAttributes; Oid relationId; Relation rel; - List *inheritList; TupleDesc descriptor; + List *inheritOids; List *old_constraints; List *rawDefaults; List *listptr; @@ -67,24 +67,16 @@ DefineRelation(CreateStmt *stmt, char relkind) StrNCpy(relname, stmt->relname, NAMEDATALEN); /* ---------------- - * Handle parameters - * XXX parameter handling missing below. + * Look up inheritance ancestors and generate relation schema, + * including inherited attributes. * ---------------- */ - inheritList = stmt->inhRelnames; - - /* ---------------- - * generate relation schema, including inherited attributes. - * ---------------- - */ - schema = MergeAttributes(schema, inheritList, &old_constraints); + schema = MergeAttributes(schema, stmt->inhRelnames, + &inheritOids, &old_constraints); numberOfAttributes = length(schema); if (numberOfAttributes <= 0) - { - elog(ERROR, "DefineRelation: %s", - "please inherit from a relation or define an attribute"); - } + elog(ERROR, "DefineRelation: please inherit from a relation or define an attribute"); /* ---------------- * create a relation descriptor from the relation schema @@ -147,7 +139,7 @@ DefineRelation(CreateStmt *stmt, char relkind) relkind, stmt->istemp, allowSystemTableMods); - StoreCatalogInheritance(relationId, inheritList); + StoreCatalogInheritance(relationId, inheritOids); /* * 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) * MergeAttributes * Returns new schema given initial schema and supers. * + * Input arguments: * * 'schema' is the column/attribute definition for the table. (It's a list * of ColumnDef's.) It is destructively changed. - * 'inheritList' is the list of inherited relations (a list of Value(str)'s). + * 'supers' is a list of names (as Value objects) of parent relations. + * + * Output arguments: + * 'supOids' receives an integer list of the OIDs of the parent relations. + * 'supconstr' receives a list of constraints belonging to the parents. * * Notes: * 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) * stud_emp {7:percent} */ static List * -MergeAttributes(List *schema, List *supers, List **supconstr) +MergeAttributes(List *schema, List *supers, + List **supOids, List **supconstr) { List *entry; List *inhSchema = NIL; + List *parentOids = NIL; List *constraints = NIL; - int attnums; + int attnums; /* * Validates that there are no duplications. Validity checking of @@ -338,7 +337,7 @@ MergeAttributes(List *schema, List *supers, List **supconstr) */ ColumnDef *restdef = lfirst(rest); - if (!strcmp(coldef->colname, restdef->colname)) + if (strcmp(coldef->colname, restdef->colname) == 0) { elog(ERROR, "CREATE TABLE: attribute \"%s\" duplicated", coldef->colname); @@ -351,7 +350,7 @@ MergeAttributes(List *schema, List *supers, List **supconstr) foreach(rest, lnext(entry)) { - if (!strcmp(strVal(lfirst(entry)), strVal(lfirst(rest)))) + if (strcmp(strVal(lfirst(entry)), strVal(lfirst(rest))) == 0) { elog(ERROR, "CREATE TABLE: inherited relation \"%s\" duplicated", strVal(lfirst(entry))); @@ -376,6 +375,11 @@ MergeAttributes(List *schema, List *supers, List **supconstr) int i, attidx, attno_exist; relation = heap_openr(name, AccessShareLock); + + if (relation->rd_rel->relkind != RELKIND_RELATION) + elog(ERROR, "CREATE TABLE: inherited relation \"%s\" is not a table", name); + + parentOids = lappendi(parentOids, relation->rd_id); setRelhassubclassInRelation(relation->rd_id, true); tupleDesc = RelationGetDescr(relation); /* allocate a new attribute number table and initialize */ @@ -391,9 +395,6 @@ MergeAttributes(List *schema, List *supers, List **supconstr) partialAttidx [i] = 0; constr = tupleDesc->constr; - if (relation->rd_rel->relkind != RELKIND_RELATION) - elog(ERROR, "CREATE TABLE: inherited relation \"%s\" is not a table", name); - attidx = 0; for (attrno = relation->rd_rel->relnatts - 1; attrno >= 0; attrno--) { @@ -519,6 +520,8 @@ MergeAttributes(List *schema, List *supers, List **supconstr) * put the inherited schema before our the schema for this table */ schema = nconc(inhSchema, schema); + + *supOids = parentOids; *supconstr = constraints; return schema; } @@ -526,6 +529,9 @@ MergeAttributes(List *schema, List *supers, List **supconstr) /* * StoreCatalogInheritance * Updates the system catalogs with proper inheritance information. + * + * supers is an integer list of the OIDs of the new relation's direct + * ancestors. NB: it is destructively changed to include indirect ancestors. */ static void StoreCatalogInheritance(Oid relationId, List *supers) @@ -534,7 +540,6 @@ StoreCatalogInheritance(Oid relationId, List *supers) TupleDesc desc; int16 seqNumber; List *entry; - List *idList; HeapTuple tuple; /* ---------------- @@ -547,32 +552,19 @@ StoreCatalogInheritance(Oid relationId, List *supers) return; /* ---------------- - * Catalog INHERITS information. + * Catalog INHERITS information using direct ancestors only. * ---------------- */ relation = heap_openr(InheritsRelationName, RowExclusiveLock); desc = RelationGetDescr(relation); seqNumber = 1; - idList = NIL; foreach(entry, supers) { - Oid entryOid; + Oid entryOid = lfirsti(entry); Datum datum[Natts_pg_inherits]; char nullarr[Natts_pg_inherits]; - entryOid = GetSysCacheOid(RELNAME, - PointerGetDatum(strVal(lfirst(entry))), - 0, 0, 0); - if (!OidIsValid(entryOid)) - elog(ERROR, "StoreCatalogInheritance: cache lookup failed for relation \"%s\"", - strVal(lfirst(entry))); - - /* - * build idList for use below - */ - idList = lappendi(idList, entryOid); - datum[0] = ObjectIdGetDatum(relationId); /* inhrel */ datum[1] = ObjectIdGetDatum(entryOid); /* inhparent */ datum[2] = Int16GetDatum(seqNumber); /* inhseqno */ @@ -602,21 +594,20 @@ StoreCatalogInheritance(Oid relationId, List *supers) heap_close(relation, RowExclusiveLock); /* ---------------- - * Catalog IPL information. + * Expand supers list to include indirect ancestors as well. * * Algorithm: - * 0. list superclasses (by Oid) in order given (see idList). + * 0. begin with list of direct superclasses. * 1. append after each relationId, its superclasses, recursively. - * 3. remove all but last of duplicates. - * 4. store result. + * 2. remove all but last of duplicates. * ---------------- */ /* ---------------- - * 1. + * 1. append after each relationId, its superclasses, recursively. * ---------------- */ - foreach(entry, idList) + foreach(entry, supers) { HeapTuple tuple; Oid id; @@ -649,20 +640,21 @@ StoreCatalogInheritance(Oid relationId, List *supers) } /* ---------------- - * 2. + * 2. remove all but last of duplicates. * ---------------- */ - foreach(entry, idList) + foreach(entry, supers) { - Oid name; + Oid thisone; + bool found; List *rest; - bool found = false; again: - name = lfirsti(entry); + thisone = lfirsti(entry); + found = false; foreach(rest, lnext(entry)) { - if (name == lfirsti(rest)) + if (thisone == lfirsti(rest)) { found = true; break; @@ -672,20 +664,17 @@ again: { /* - * entry list must be of length >= 2 or else no match - * - * so, remove this entry. + * found a later duplicate, so remove this entry. */ - lfirst(entry) = lfirst(lnext(entry)); + lfirsti(entry) = lfirsti(lnext(entry)); lnext(entry) = lnext(lnext(entry)); - found = false; goto again; } } /* ---------------- - * 3. + * Catalog IPL information using expanded list. * ---------------- */ relation = heap_openr(InheritancePrecidenceListRelationName, RowExclusiveLock); @@ -693,7 +682,7 @@ again: seqNumber = 1; - foreach(entry, idList) + foreach(entry, supers) { Datum datum[Natts_pg_ipl]; char nullarr[Natts_pg_ipl]; @@ -721,10 +710,12 @@ again: /* - * returns the index(star with 1) if attribute already exists in schema, 0 otherwise. + * returns the index (starting with 1) if attribute already exists in schema, + * 0 if it doesn't. */ static int -checkAttrExists(const char *attributeName, const char *attributeType, List *schema) +checkAttrExists(const char *attributeName, const char *attributeType, + List *schema) { List *s; int i = 0;