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.)
REL7_1_STABLE
Tom Lane 25 years ago
parent 7558da669f
commit 90f42847b5
  1. 8
      src/backend/catalog/heap.c
  2. 6
      src/backend/catalog/index.c
  3. 7
      src/backend/commands/command.c
  4. 15
      src/backend/commands/creatinh.c
  5. 6
      src/backend/commands/vacuum.c
  6. 4
      src/backend/utils/cache/relcache.c
  7. 20
      src/backend/utils/cache/temprel.c
  8. 4
      src/include/utils/temprel.h

@ -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;
/* ----------------

@ -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);

@ -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

@ -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);

@ -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,

@ -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;
/* ----------------

@ -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)

@ -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 */

Loading…
Cancel
Save