aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/catalog/heap.c8
-rw-r--r--src/backend/catalog/index.c6
-rw-r--r--src/backend/commands/command.c7
-rw-r--r--src/backend/commands/creatinh.c15
-rw-r--r--src/backend/commands/vacuum.c6
-rw-r--r--src/backend/utils/cache/relcache.c4
-rw-r--r--src/backend/utils/cache/temprel.c20
-rw-r--r--src/include/utils/temprel.h4
8 files changed, 42 insertions, 28 deletions
diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index b2d2566bf3f..174b8ca85bb 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -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;
/* ----------------
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 649e2300245..46f8abe7b31 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -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);
diff --git a/src/backend/commands/command.c b/src/backend/commands/command.c
index 78a3d5e1a75..035967f9209 100644
--- a/src/backend/commands/command.c
+++ b/src/backend/commands/command.c
@@ -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
diff --git a/src/backend/commands/creatinh.c b/src/backend/commands/creatinh.c
index 33022515cb6..38e2c3a418e 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.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);
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 0d4984cde6a..909c9cea732 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -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,
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 4e9780462a5..1b7ce6fe18c 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -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;
/* ----------------
diff --git a/src/backend/utils/cache/temprel.c b/src/backend/utils/cache/temprel.c
index 0134b47a0f9..a0066f2eaff 100644
--- a/src/backend/utils/cache/temprel.c
+++ b/src/backend/utils/cache/temprel.c
@@ -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)
diff --git a/src/include/utils/temprel.h b/src/include/utils/temprel.h
index 789d5058789..8c19c8e127d 100644
--- a/src/include/utils/temprel.h
+++ b/src/include/utils/temprel.h
@@ -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 */