Commit 90f42847 authored by Tom Lane's avatar Tom Lane

Small cleanup of temp-table handling. Disallow creation of a non-temp

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.)
parent 7558da66
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 * INTERFACE ROUTINES
...@@ -801,7 +801,7 @@ heap_create_with_catalog(char *relname, ...@@ -801,7 +801,7 @@ heap_create_with_catalog(char *relname,
/* temp tables can mask non-temp tables */ /* temp tables can mask non-temp tables */
if ((!istemp && RelnameFindRelid(relname)) || 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); elog(ERROR, "Relation '%s' already exists", relname);
if (istemp) if (istemp)
...@@ -813,7 +813,7 @@ heap_create_with_catalog(char *relname, ...@@ -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 * creation. Uniqueness will be really checked by unique
* indexes of system tables but we couldn't check it here. * indexes of system tables but we couldn't check it here.
* We have to postpone creating the disk file for this * We have to postpone creating the disk file for this
...@@ -1404,7 +1404,7 @@ heap_drop_with_catalog(const char *relname, ...@@ -1404,7 +1404,7 @@ heap_drop_with_catalog(const char *relname,
Relation rel; Relation rel;
Oid rid; Oid rid;
bool has_toasttable; bool has_toasttable;
bool istemp = (get_temp_rel_by_username(relname) != NULL); bool istemp = is_temp_rel_name(relname);
int i; int i;
/* ---------------- /* ----------------
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 * INTERFACE ROUTINES
...@@ -145,7 +145,7 @@ GetHeapRelationOid(char *heapRelationName, char *indexRelationName, bool istemp) ...@@ -145,7 +145,7 @@ GetHeapRelationOid(char *heapRelationName, char *indexRelationName, bool istemp)
indoid = RelnameFindRelid(indexRelationName); indoid = RelnameFindRelid(indexRelationName);
if ((!istemp && OidIsValid(indoid)) || 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", elog(ERROR, "Cannot create index: '%s' already exists",
indexRelationName); indexRelationName);
...@@ -885,7 +885,7 @@ index_create(char *heapRelationName, ...@@ -885,7 +885,7 @@ index_create(char *heapRelationName,
TupleDesc indexTupDesc; TupleDesc indexTupDesc;
Oid heapoid; Oid heapoid;
Oid indexoid; Oid indexoid;
bool istemp = (get_temp_rel_by_username(heapRelationName) != NULL); bool istemp = is_temp_rel_name(heapRelationName);
char *temp_relname = NULL; char *temp_relname = NULL;
SetReindexProcessing(false); SetReindexProcessing(false);
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 * NOTES
* The PerformAddAttribute() code, like most of the relation * The PerformAddAttribute() code, like most of the relation
...@@ -1237,10 +1237,9 @@ AlterTableAddConstraint(char *relationName, ...@@ -1237,10 +1237,9 @@ AlterTableAddConstraint(char *relationName,
int i; int i;
bool found = false; bool found = false;
if (get_temp_rel_by_username(fkconstraint->pktable_name)!=NULL && if (is_temp_rel_name(fkconstraint->pktable_name) &&
get_temp_rel_by_username(relationName)==NULL) { !is_temp_rel_name(relationName))
elog(ERROR, "ALTER TABLE / ADD CONSTRAINT: Unable to reference temporary table from permanent table constraint."); 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 * Grab an exclusive lock on the pk table, so that someone
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 @@ ...@@ -24,8 +24,9 @@
#include "catalog/pg_type.h" #include "catalog/pg_type.h"
#include "commands/creatinh.h" #include "commands/creatinh.h"
#include "miscadmin.h" #include "miscadmin.h"
#include "utils/syscache.h"
#include "optimizer/clauses.h" #include "optimizer/clauses.h"
#include "utils/syscache.h"
#include "utils/temprel.h"
/* ---------------- /* ----------------
* local stuff * local stuff
...@@ -34,7 +35,7 @@ ...@@ -34,7 +35,7 @@
static int checkAttrExists(const char *attributeName, static int checkAttrExists(const char *attributeName,
const char *attributeType, List *schema); 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); List **supOids, List **supconstr);
static void StoreCatalogInheritance(Oid relationId, List *supers); static void StoreCatalogInheritance(Oid relationId, List *supers);
static void setRelhassubclassInRelation(Oid relationId, bool relhassubclass); static void setRelhassubclassInRelation(Oid relationId, bool relhassubclass);
...@@ -71,7 +72,7 @@ DefineRelation(CreateStmt *stmt, char relkind) ...@@ -71,7 +72,7 @@ DefineRelation(CreateStmt *stmt, char relkind)
* including inherited attributes. * including inherited attributes.
* ---------------- * ----------------
*/ */
schema = MergeAttributes(schema, stmt->inhRelnames, schema = MergeAttributes(schema, stmt->inhRelnames, stmt->istemp,
&inheritOids, &old_constraints); &inheritOids, &old_constraints);
numberOfAttributes = length(schema); numberOfAttributes = length(schema);
...@@ -283,6 +284,7 @@ change_varattnos_of_a_node(Node *node, const AttrNumber *newattno) ...@@ -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 * 'schema' is the column/attribute definition for the table. (It's a list
* of ColumnDef's.) It is destructively changed. * of ColumnDef's.) It is destructively changed.
* 'supers' is a list of names (as Value objects) of parent relations. * 'supers' is a list of names (as Value objects) of parent relations.
* 'istemp' is TRUE if we are creating a temp relation.
* *
* Output arguments: * Output arguments:
* 'supOids' receives an integer list of the OIDs of the parent relations. * '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) ...@@ -311,7 +313,7 @@ change_varattnos_of_a_node(Node *node, const AttrNumber *newattno)
* stud_emp {7:percent} * stud_emp {7:percent}
*/ */
static List * static List *
MergeAttributes(List *schema, List *supers, MergeAttributes(List *schema, List *supers, bool istemp,
List **supOids, List **supconstr) List **supOids, List **supconstr)
{ {
List *entry; List *entry;
...@@ -378,6 +380,9 @@ MergeAttributes(List *schema, List *supers, ...@@ -378,6 +380,9 @@ MergeAttributes(List *schema, List *supers,
if (relation->rd_rel->relkind != RELKIND_RELATION) if (relation->rd_rel->relkind != RELKIND_RELATION)
elog(ERROR, "CREATE TABLE: inherited relation \"%s\" is not a table", name); 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); parentOids = lappendi(parentOids, relation->rd_id);
setRelhassubclassInRelation(relation->rd_id, true); setRelhassubclassInRelation(relation->rd_id, true);
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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) ...@@ -274,8 +274,8 @@ getrels(NameData *VacRelP)
char *nontemp_relname; char *nontemp_relname;
/* We must re-map temp table names bjm 2000-04-06 */ /* We must re-map temp table names bjm 2000-04-06 */
if ((nontemp_relname = nontemp_relname = get_temp_rel_by_username(NameStr(*VacRelP));
get_temp_rel_by_username(NameStr(*VacRelP))) == NULL) if (nontemp_relname == NULL)
nontemp_relname = NameStr(*VacRelP); nontemp_relname = NameStr(*VacRelP);
ScanKeyEntryInitialize(&key, 0x0, Anum_pg_class_relname, ScanKeyEntryInitialize(&key, 0x0, Anum_pg_class_relname,
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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) ...@@ -1526,7 +1526,7 @@ RelationNameGetRelation(const char *relationName)
* ---------------- * ----------------
*/ */
temprelname = get_temp_rel_by_username(relationName); temprelname = get_temp_rel_by_username(relationName);
if (temprelname) if (temprelname != NULL)
relationName = temprelname; relationName = temprelname;
/* ---------------- /* ----------------
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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, ...@@ -152,13 +152,19 @@ rename_temp_relation(const char *oldname,
continue; /* ignore non-matching entries */ continue; /* ignore non-matching entries */
/* We are renaming a temp table --- is it OK to do so? */ /* 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", elog(ERROR, "Cannot rename temp table \"%s\": temp table \"%s\" already exists",
oldname, newname); oldname, newname);
/* /*
* Create a new mapping entry and mark the old one deleted in this * Create a new mapping entry and mark the old one deleted in this
* xact. One of these entries will be deleted at xact end. * 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); oldcxt = MemoryContextSwitchTo(CacheMemoryContext);
...@@ -168,7 +174,7 @@ rename_temp_relation(const char *oldname, ...@@ -168,7 +174,7 @@ rename_temp_relation(const char *oldname,
StrNCpy(NameStr(new_temp_rel->user_relname), newname, NAMEDATALEN); StrNCpy(NameStr(new_temp_rel->user_relname), newname, NAMEDATALEN);
new_temp_rel->created_in_cur_xact = true; 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; temp_rel->deleted_in_cur_xact = true;
...@@ -178,7 +184,7 @@ rename_temp_relation(const char *oldname, ...@@ -178,7 +184,7 @@ rename_temp_relation(const char *oldname,
} }
/* Old name does not match any temp table name, what about new? */ /* 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", elog(ERROR, "Cannot rename \"%s\" to \"%s\": a temp table by that name already exists",
oldname, newname); oldname, newname);
...@@ -205,7 +211,8 @@ remove_all_temp_relations(void) ...@@ -205,7 +211,8 @@ remove_all_temp_relations(void)
* Scan the list and delete all entries not already deleted. * Scan the list and delete all entries not already deleted.
* We need not worry about list entries getting deleted from under us, * We need not worry about list entries getting deleted from under us,
* because remove_temp_rel_by_relid() doesn't remove entries, only * 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) foreach(l, temp_rels)
{ {
...@@ -286,7 +293,8 @@ AtEOXact_temp_relations(bool isCommit) ...@@ -286,7 +293,8 @@ AtEOXact_temp_relations(bool isCommit)
/* /*
* Map user name to physical name --- returns NULL if no entry. * 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 * char *
get_temp_rel_by_username(const char *user_relname) get_temp_rel_by_username(const char *user_relname)
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California * 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); ...@@ -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_username(const char *user_relname);
extern char *get_temp_rel_by_physicalname(const char *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 */ #endif /* TEMPREL_H */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment