]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Small cleanup of temp-table handling. Disallow creation of a non-temp
authorTom Lane <tgl@sss.pgh.pa.us>
Fri, 22 Dec 2000 23:12:07 +0000 (23:12 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Fri, 22 Dec 2000 23:12:07 +0000 (23:12 +0000)
table that inherits from a temp table.  Make sure the right things happen
if one creates a temp table, creates another temp that inherits from it,
then renames the first one.  (Previously, system would end up trying to
delete the temp tables in the wrong order.)

src/backend/catalog/heap.c
src/backend/catalog/index.c
src/backend/commands/command.c
src/backend/commands/creatinh.c
src/backend/commands/vacuum.c
src/backend/utils/cache/relcache.c
src/backend/utils/cache/temprel.c
src/include/utils/temprel.h

index b2d2566bf3f290ea255c9310ac249129b9643b30..174b8ca85bb9308778ae22105451b6d453d5df1c 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.153 2000/12/22 19:21:37 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.154 2000/12/22 23:12:03 tgl Exp $
  *
  *
  * INTERFACE ROUTINES
@@ -801,7 +801,7 @@ heap_create_with_catalog(char *relname,
 
        /* temp tables can mask non-temp tables */
        if ((!istemp && RelnameFindRelid(relname)) ||
-               (istemp && get_temp_rel_by_username(relname) != NULL))
+               (istemp && is_temp_rel_name(relname)))
                elog(ERROR, "Relation '%s' already exists", relname);
 
        if (istemp)
@@ -813,7 +813,7 @@ heap_create_with_catalog(char *relname,
        }
 
        /* ----------------
-        *      get_temp_rel_by_username() couldn't check the simultaneous
+        *      RelnameFindRelid couldn't detect simultaneous
         *      creation. Uniqueness will be really checked by unique
         *      indexes of system tables but we couldn't check it here.
         *      We have to postpone creating the disk file for this
@@ -1404,7 +1404,7 @@ heap_drop_with_catalog(const char *relname,
        Relation        rel;
        Oid                     rid;
        bool            has_toasttable;
-       bool            istemp = (get_temp_rel_by_username(relname) != NULL);
+       bool            istemp = is_temp_rel_name(relname);
        int                     i;
 
        /* ----------------
index 649e2300245e47ec7c4e9c88e2eb0574db690444..46f8abe7b312a0e967f27f0e0ecdeb0eb119f602 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.132 2000/12/09 20:31:43 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.133 2000/12/22 23:12:03 tgl Exp $
  *
  *
  * INTERFACE ROUTINES
@@ -145,7 +145,7 @@ GetHeapRelationOid(char *heapRelationName, char *indexRelationName, bool istemp)
        indoid = RelnameFindRelid(indexRelationName);
 
        if ((!istemp && OidIsValid(indoid)) ||
-               (istemp && get_temp_rel_by_username(indexRelationName) != NULL))
+               (istemp && is_temp_rel_name(indexRelationName)))
                elog(ERROR, "Cannot create index: '%s' already exists",
                         indexRelationName);
 
@@ -885,7 +885,7 @@ index_create(char *heapRelationName,
        TupleDesc       indexTupDesc;
        Oid                     heapoid;
        Oid                     indexoid;
-       bool            istemp = (get_temp_rel_by_username(heapRelationName) != NULL);
+       bool            istemp = is_temp_rel_name(heapRelationName);
        char       *temp_relname = NULL;
 
        SetReindexProcessing(false);
index 78a3d5e1a75fe198f4c5b19d39cd21cb1b35ffc8..035967f920960b34fd58daa260572abd20843e0d 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.113 2000/12/05 19:57:55 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.114 2000/12/22 23:12:05 tgl Exp $
  *
  * NOTES
  *       The PerformAddAttribute() code, like most of the relation
@@ -1237,10 +1237,9 @@ AlterTableAddConstraint(char *relationName,
                        int                     i;
                        bool            found = false;
 
-                       if (get_temp_rel_by_username(fkconstraint->pktable_name)!=NULL &&
-                               get_temp_rel_by_username(relationName)==NULL) {
+                       if (is_temp_rel_name(fkconstraint->pktable_name) &&
+                               !is_temp_rel_name(relationName))
                                elog(ERROR, "ALTER TABLE / ADD CONSTRAINT: Unable to reference temporary table from permanent table constraint.");
-                       }
 
                        /*
                         * Grab an exclusive lock on the pk table, so that someone
index 33022515cb6ca331492c82ff63dc2d4f7e972dfe..38e2c3a418ed87248dd5be8a45bdf50dfbe3a8c4 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/commands/Attic/creatinh.c,v 1.68 2000/12/14 00:41:09 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/commands/Attic/creatinh.c,v 1.69 2000/12/22 23:12:05 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -24,8 +24,9 @@
 #include "catalog/pg_type.h"
 #include "commands/creatinh.h"
 #include "miscadmin.h"
-#include "utils/syscache.h"
 #include "optimizer/clauses.h"
+#include "utils/syscache.h"
+#include "utils/temprel.h"
 
 /* ----------------
  *             local stuff
@@ -34,7 +35,7 @@
 
 static int checkAttrExists(const char *attributeName,
                                const char *attributeType, List *schema);
-static List *MergeAttributes(List *schema, List *supers,
+static List *MergeAttributes(List *schema, List *supers, bool istemp,
                                                         List **supOids, List **supconstr);
 static void StoreCatalogInheritance(Oid relationId, List *supers);
 static void setRelhassubclassInRelation(Oid relationId, bool relhassubclass);
@@ -71,7 +72,7 @@ DefineRelation(CreateStmt *stmt, char relkind)
         *      including inherited attributes.
         * ----------------
         */
-       schema = MergeAttributes(schema, stmt->inhRelnames,
+       schema = MergeAttributes(schema, stmt->inhRelnames, stmt->istemp,
                                                         &inheritOids, &old_constraints);
 
        numberOfAttributes = length(schema);
@@ -283,6 +284,7 @@ change_varattnos_of_a_node(Node *node, const AttrNumber *newattno)
  * 'schema' is the column/attribute definition for the table. (It's a list
  *             of ColumnDef's.) It is destructively changed.
  * 'supers' is a list of names (as Value objects) of parent relations.
+ * 'istemp' is TRUE if we are creating a temp relation.
  *
  * Output arguments:
  * 'supOids' receives an integer list of the OIDs of the parent relations.
@@ -311,7 +313,7 @@ change_varattnos_of_a_node(Node *node, const AttrNumber *newattno)
  *                                                stud_emp {7:percent}
  */
 static List *
-MergeAttributes(List *schema, List *supers,
+MergeAttributes(List *schema, List *supers, bool istemp,
                                List **supOids, List **supconstr)
 {
        List       *entry;
@@ -378,6 +380,9 @@ MergeAttributes(List *schema, List *supers,
 
                if (relation->rd_rel->relkind != RELKIND_RELATION)
                        elog(ERROR, "CREATE TABLE: inherited relation \"%s\" is not a table", name);
+               /* Permanent rels cannot inherit from temporary ones */
+               if (!istemp && is_temp_rel_name(name))
+                       elog(ERROR, "CREATE TABLE: cannot inherit from temp relation \"%s\"", name);
 
                parentOids = lappendi(parentOids, relation->rd_id);
                setRelhassubclassInRelation(relation->rd_id, true);
index 0d4984cde6aa25b50f0180b68b59b35ea5f4d571..909c9cea732efc91959b7e47b9672fe1fa428ec4 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.178 2000/12/22 00:51:53 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.179 2000/12/22 23:12:05 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -274,8 +274,8 @@ getrels(NameData *VacRelP)
                char       *nontemp_relname;
 
                /* We must re-map temp table names bjm 2000-04-06 */
-               if ((nontemp_relname =
-                        get_temp_rel_by_username(NameStr(*VacRelP))) == NULL)
+               nontemp_relname = get_temp_rel_by_username(NameStr(*VacRelP));
+               if (nontemp_relname == NULL)
                        nontemp_relname = NameStr(*VacRelP);
 
                ScanKeyEntryInitialize(&key, 0x0, Anum_pg_class_relname,
index 4e9780462a5e619d1d03b5933287d432df43cf56..1b7ce6fe18c280f77c8b86824570dab34958cd60 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.120 2000/12/09 20:32:44 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.121 2000/12/22 23:12:06 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1526,7 +1526,7 @@ RelationNameGetRelation(const char *relationName)
         * ----------------
         */
        temprelname = get_temp_rel_by_username(relationName);
-       if (temprelname)
+       if (temprelname != NULL)
                relationName = temprelname;
 
        /* ----------------
index 0134b47a0f9d71bf45c311815e5bceee810e286d..a0066f2eaff4ed24e2027aa420f7f345755a4e65 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/utils/cache/Attic/temprel.c,v 1.31 2000/11/16 22:30:33 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/utils/cache/Attic/temprel.c,v 1.32 2000/12/22 23:12:07 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -152,13 +152,19 @@ rename_temp_relation(const char *oldname,
                        continue;                       /* ignore non-matching entries */
 
                /* We are renaming a temp table --- is it OK to do so? */
-               if (get_temp_rel_by_username(newname) != NULL)
+               if (is_temp_rel_name(newname))
                        elog(ERROR, "Cannot rename temp table \"%s\": temp table \"%s\" already exists",
                                 oldname, newname);
 
                /*
                 * Create a new mapping entry and mark the old one deleted in this
                 * xact.  One of these entries will be deleted at xact end.
+                *
+                * NOTE: the new mapping entry is inserted into the list just after
+                * the old one.  We could alternatively insert it before the old one,
+                * but that'd take more code.  It does need to be in one spot or the
+                * other, to ensure that deletion of temp rels happens in the right
+                * order during remove_all_temp_relations().
                 */
                oldcxt = MemoryContextSwitchTo(CacheMemoryContext);
 
@@ -168,7 +174,7 @@ rename_temp_relation(const char *oldname,
                StrNCpy(NameStr(new_temp_rel->user_relname), newname, NAMEDATALEN);
                new_temp_rel->created_in_cur_xact = true;
 
-               temp_rels = lcons(new_temp_rel, temp_rels);
+               lnext(l) = lcons(new_temp_rel, lnext(l));
 
                temp_rel->deleted_in_cur_xact = true;
 
@@ -178,7 +184,7 @@ rename_temp_relation(const char *oldname,
        }
 
        /* Old name does not match any temp table name, what about new? */
-       if (get_temp_rel_by_username(newname) != NULL)
+       if (is_temp_rel_name(newname))
                elog(ERROR, "Cannot rename \"%s\" to \"%s\": a temp table by that name already exists",
                         oldname, newname);
 
@@ -205,7 +211,8 @@ remove_all_temp_relations(void)
         * Scan the list and delete all entries not already deleted.
         * We need not worry about list entries getting deleted from under us,
         * because remove_temp_rel_by_relid() doesn't remove entries, only
-        * mark them dead.
+        * mark them dead.  Note that entries will be deleted in reverse order
+        * of creation --- that's critical for cases involving inheritance.
         */
        foreach(l, temp_rels)
        {
@@ -286,7 +293,8 @@ AtEOXact_temp_relations(bool isCommit)
 /*
  * Map user name to physical name --- returns NULL if no entry.
  *
- * This is the normal way to test whether a name is a temp table name.
+ * This also supports testing whether a name is a temp table name;
+ * see is_temp_rel_name() macro.
  */
 char *
 get_temp_rel_by_username(const char *user_relname)
index 789d5058789e281ea11d4e7829f1259be3f9b849..8c19c8e127dfd296d08063d4fa4bb2569acb0474 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: temprel.h,v 1.12 2000/11/08 22:10:03 tgl Exp $
+ * $Id: temprel.h,v 1.13 2000/12/22 23:12:07 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -28,4 +28,6 @@ extern void AtEOXact_temp_relations(bool isCommit);
 extern char *get_temp_rel_by_username(const char *user_relname);
 extern char *get_temp_rel_by_physicalname(const char *relname);
 
+#define is_temp_rel_name(relname) (get_temp_rel_by_username(relname) != NULL)
+
 #endif  /* TEMPREL_H */