Change StoreCatalogInheritance() to work from a list of parent relation
authorTom Lane <[email protected]>
Thu, 14 Dec 2000 00:41:09 +0000 (00:41 +0000)
committerTom Lane <[email protected]>
Thu, 14 Dec 2000 00:41:09 +0000 (00:41 +0000)
OIDs rather than names.  Aside from being simpler and faster, this way
doesn't blow up in the face of 'create temp table foo () inherits (foo)'.
Which is a rather odd thing to do, but it seems some people want to.

src/backend/commands/creatinh.c

index 970782d6da30b8574bf9e385272ac9c3cd758280..33022515cb6ca331492c82ff63dc2d4f7e972dfe 100644 (file)
@@ -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 $
  *
  *-------------------------------------------------------------------------
  */
 
 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;