From 31141025214e9508be5cb05b87cd63e563960925 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Sun, 31 Mar 2002 06:26:32 +0000 Subject: [PATCH] Reimplement temp tables using schemas. The temp table map is history; temp table entries in pg_class have the names the user would expect. --- src/backend/access/transam/xact.c | 7 +- src/backend/access/transam/xlogutils.c | 4 +- src/backend/bootstrap/bootparse.y | 5 +- src/backend/catalog/aclchk.c | 4 +- src/backend/catalog/heap.c | 87 +---- src/backend/catalog/index.c | 41 +- src/backend/catalog/namespace.c | 493 ++++++++++++++++++++++++- src/backend/catalog/pg_namespace.c | 7 +- src/backend/commands/cluster.c | 21 +- src/backend/commands/command.c | 30 +- src/backend/commands/creatinh.c | 10 +- src/backend/commands/indexcmds.c | 6 +- src/backend/commands/rename.c | 10 +- src/backend/commands/trigger.c | 4 +- src/backend/commands/vacuum.c | 13 +- src/backend/executor/execMain.c | 6 +- src/backend/parser/analyze.c | 6 +- src/backend/tcop/utility.c | 6 +- src/backend/utils/cache/Makefile | 4 +- src/backend/utils/cache/relcache.c | 16 +- src/backend/utils/cache/syscache.c | 27 +- src/backend/utils/cache/temprel.c | 335 ----------------- src/backend/utils/init/postinit.c | 18 +- src/include/catalog/heap.h | 13 +- src/include/catalog/index.h | 5 +- src/include/catalog/namespace.h | 4 +- src/include/catalog/pg_namespace.h | 6 +- src/include/utils/rel.h | 45 +-- src/include/utils/temprel.h | 33 -- 29 files changed, 596 insertions(+), 670 deletions(-) delete mode 100644 src/backend/utils/cache/temprel.c delete mode 100644 src/include/utils/temprel.h diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c index e18a7de2d0..046f3d52aa 100644 --- a/src/backend/access/transam/xact.c +++ b/src/backend/access/transam/xact.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.118 2002/03/15 19:20:29 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.119 2002/03/31 06:26:29 tgl Exp $ * * NOTES * Transaction aborts can now occur two ways: @@ -178,10 +178,9 @@ #include "utils/portal.h" #include "utils/catcache.h" #include "utils/relcache.h" -#include "utils/temprel.h" - #include "pgstat.h" + extern bool SharedBufferChanged; static void AbortTransaction(void); @@ -999,7 +998,6 @@ CommitTransaction(void) */ RelationPurgeLocalRelation(true); - AtEOXact_temp_relations(true); smgrDoPendingDeletes(true); AtEOXact_SPI(); @@ -1102,7 +1100,6 @@ AbortTransaction(void) } RelationPurgeLocalRelation(false); - AtEOXact_temp_relations(false); smgrDoPendingDeletes(false); AtEOXact_SPI(); diff --git a/src/backend/access/transam/xlogutils.c b/src/backend/access/transam/xlogutils.c index 8a9554b2a6..ae79ba85b1 100644 --- a/src/backend/access/transam/xlogutils.c +++ b/src/backend/access/transam/xlogutils.c @@ -6,7 +6,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Header: /cvsroot/pgsql/src/backend/access/transam/xlogutils.c,v 1.22 2002/03/02 21:39:20 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/transam/xlogutils.c,v 1.23 2002/03/31 06:26:29 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -335,7 +335,7 @@ XLogOpenRelation(bool redo, RmgrId rmid, RelFileNode rnode) { res = _xl_new_reldesc(); - sprintf(RelationGetPhysicalRelationName(&(res->reldata)), "%u", rnode.relNode); + sprintf(RelationGetRelationName(&(res->reldata)), "%u", rnode.relNode); /* unexisting DB id */ res->reldata.rd_lockInfo.lockRelId.dbId = RecoveryDb; diff --git a/src/backend/bootstrap/bootparse.y b/src/backend/bootstrap/bootparse.y index 3b0d34f9fc..33c18f3b2d 100644 --- a/src/backend/bootstrap/bootparse.y +++ b/src/backend/bootstrap/bootparse.y @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/bootstrap/bootparse.y,v 1.41 2002/03/26 19:15:16 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/bootstrap/bootparse.y,v 1.42 2002/03/31 06:26:29 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -184,7 +184,7 @@ Boot_CreateStmt: reldesc = heap_create(LexIDStr($4), PG_CATALOG_NAMESPACE, tupdesc, - false, true, true); + true, true); reldesc->rd_rel->relhasoids = ! ($3); elog(DEBUG3, "bootstrap relation created"); } @@ -199,7 +199,6 @@ Boot_CreateStmt: tupdesc, RELKIND_RELATION, ! ($3), - false, true); elog(DEBUG3, "relation created with oid %u", id); } diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c index 3269964aa0..00c52e89c4 100644 --- a/src/backend/catalog/aclchk.c +++ b/src/backend/catalog/aclchk.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/catalog/aclchk.c,v 1.60 2002/03/29 19:05:59 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/catalog/aclchk.c,v 1.61 2002/03/31 06:26:29 tgl Exp $ * * NOTES * See acl.h. @@ -40,7 +40,6 @@ #include "parser/parse_type.h" #include "utils/acl.h" #include "utils/syscache.h" -#include "utils/temprel.h" static void ExecuteGrantStmt_Table(GrantStmt *stmt); @@ -811,7 +810,6 @@ pg_class_aclcheck(Oid table_oid, Oid userid, AclMode mode) relname = NameStr(((Form_pg_class) GETSTRUCT(tuple))->relname); if ((mode & (ACL_INSERT | ACL_UPDATE | ACL_DELETE)) && !allowSystemTableMods && IsSystemRelationName(relname) && - !is_temp_relname(relname) && !usecatupd) { #ifdef ACLDEBUG diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c index fa64676e34..61688793cf 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.193 2002/03/29 19:05:59 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.194 2002/03/31 06:26:29 tgl Exp $ * * * INTERFACE ROUTINES @@ -61,14 +61,12 @@ #include "utils/lsyscache.h" #include "utils/relcache.h" #include "utils/syscache.h" -#include "utils/temprel.h" static void AddNewRelationTuple(Relation pg_class_desc, Relation new_rel_desc, Oid new_rel_oid, Oid new_type_oid, - char relkind, bool relhasoids, - char *temp_relname); + char relkind, bool relhasoids); static void DeleteAttributeTuples(Relation rel); static void DeleteRelationTuple(Relation rel); static void DeleteTypeTuple(Relation rel); @@ -205,34 +203,29 @@ SystemAttributeByName(const char *attname, bool relhasoids) * * Remove the system relation specific code to elsewhere eventually. * - * NOTE: if istemp is TRUE then heap_create will overwrite relname with - * the unique "real" name chosen for the temp relation. - * * If storage_create is TRUE then heap_storage_create is called here, * else caller must call heap_storage_create later. * ---------------------------------------------------------------- */ Relation -heap_create(char *relname, +heap_create(const char *relname, Oid relnamespace, TupleDesc tupDesc, - bool istemp, bool storage_create, bool allow_system_table_mods) { - static unsigned int uniqueId = 0; - Oid relid; Oid dbid = MyDatabaseId; - RelFileNode rnode; bool nailme = false; + RelFileNode rnode; Relation rel; /* * sanity checks */ - if (relname && !allow_system_table_mods && - IsSystemRelationName(relname) && IsNormalProcessingMode()) + if (!allow_system_table_mods && + IsSystemRelationName(relname) && + IsNormalProcessingMode()) elog(ERROR, "invalid relation name \"%s\"; " "the 'pg_' name prefix is reserved for system catalogs", relname); @@ -291,16 +284,6 @@ heap_create(char *relname, else relid = newoid(); - if (istemp) - { - /* - * replace relname of caller with a unique name for a temp - * relation - */ - snprintf(relname, NAMEDATALEN, "%s_%d_%u", - PG_TEMP_REL_PREFIX, (int) MyProcPid, uniqueId++); - } - /* * For now, the physical identifier of the relation is the same as the * logical identifier. @@ -528,8 +511,7 @@ AddNewRelationTuple(Relation pg_class_desc, Oid new_rel_oid, Oid new_type_oid, char relkind, - bool relhasoids, - char *temp_relname) + bool relhasoids) { Form_pg_class new_rel_reltup; HeapTuple tup; @@ -599,9 +581,6 @@ AddNewRelationTuple(Relation pg_class_desc, */ heap_insert(pg_class_desc, tup); - if (temp_relname) - create_temp_relation(temp_relname, tup); - if (!IsIgnoringSystemIndexes()) { /* @@ -669,19 +648,17 @@ AddNewRelationType(const char *typeName, * -------------------------------- */ Oid -heap_create_with_catalog(char *relname, +heap_create_with_catalog(const char *relname, Oid relnamespace, TupleDesc tupdesc, char relkind, bool relhasoids, - bool istemp, bool allow_system_table_mods) { Relation pg_class_desc; Relation new_rel_desc; Oid new_rel_oid; Oid new_type_oid; - char *temp_relname = NULL; /* * sanity checks @@ -693,32 +670,17 @@ heap_create_with_catalog(char *relname, CheckAttributeNames(tupdesc, relhasoids); - /* temp tables can mask non-temp tables */ - if ((!istemp && get_relname_relid(relname, relnamespace)) || - (istemp && is_temp_rel_name(relname))) + if (get_relname_relid(relname, relnamespace)) elog(ERROR, "Relation '%s' already exists", relname); - if (istemp) - { - /* save user relation name because heap_create changes it */ - temp_relname = pstrdup(relname); /* save original value */ - relname = palloc(NAMEDATALEN); - strcpy(relname, temp_relname); /* heap_create will change this */ - } - /* * Tell heap_create not to create a physical file; we'll do that below * after all our catalog updates are done. (This isn't really * necessary anymore, but we may as well avoid the cycles of creating * and deleting the file in case we fail.) - * - * Note: The call to heap_create() changes relname for temp tables; it - * becomes the true physical relname. The call to - * heap_storage_create() does all the "real" work of creating the disk - * file for the relation. */ new_rel_desc = heap_create(relname, relnamespace, tupdesc, - istemp, false, allow_system_table_mods); + false, allow_system_table_mods); /* Fetch the relation OID assigned by heap_create */ new_rel_oid = new_rel_desc->rd_att->attrs[0]->attrelid; @@ -740,8 +702,7 @@ heap_create_with_catalog(char *relname, new_rel_oid, new_type_oid, relkind, - relhasoids, - temp_relname); + relhasoids); /* * since defining a relation also defines a complex type, we add a new @@ -780,12 +741,6 @@ heap_create_with_catalog(char *relname, heap_close(new_rel_desc, NoLock); /* do not unlock till end of xact */ heap_close(pg_class_desc, RowExclusiveLock); - if (istemp) - { - pfree(relname); - pfree(temp_relname); - } - return new_rel_oid; } @@ -1226,26 +1181,19 @@ heap_drop_with_catalog(Oid rid, { Relation rel; Oid toasttableOid; - bool has_toasttable; - bool istemp; int i; /* * Open and lock the relation. */ rel = heap_open(rid, AccessExclusiveLock); - has_toasttable = rel->rd_rel->reltoastrelid != InvalidOid; toasttableOid = rel->rd_rel->reltoastrelid; - istemp = is_temp_rel_name(RelationGetRelationName(rel)); /* * prevent deletion of system relations */ - /* allow temp of pg_class? Guess so. */ - if (!istemp && - !allow_system_table_mods && - IsSystemRelationName(RelationGetRelationName(rel)) && - !is_temp_relname(RelationGetRelationName(rel))) + if (!allow_system_table_mods && + IsSystemRelationName(RelationGetRelationName(rel))) elog(ERROR, "System relation \"%s\" may not be dropped", RelationGetRelationName(rel)); @@ -1319,11 +1267,8 @@ heap_drop_with_catalog(Oid rid, */ RelationForgetRelation(rid); - /* and from the temp-table map */ - if (istemp) - remove_temp_rel_by_relid(rid); - - if (has_toasttable) + /* If it has a toast table, recurse to get rid of that too */ + if (OidIsValid(toasttableOid)) heap_drop_with_catalog(toasttableOid, true); } diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 17d290f84e..f8a1e5d4b2 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.174 2002/03/26 19:15:28 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.175 2002/03/31 06:26:29 tgl Exp $ * * * INTERFACE ROUTINES @@ -33,6 +33,7 @@ #include "catalog/index.h" #include "catalog/indexing.h" #include "catalog/pg_index.h" +#include "catalog/pg_namespace.h" #include "catalog/pg_opclass.h" #include "catalog/pg_proc.h" #include "catalog/pg_type.h" @@ -51,7 +52,6 @@ #include "utils/lsyscache.h" #include "utils/relcache.h" #include "utils/syscache.h" -#include "utils/temprel.h" /* @@ -69,7 +69,7 @@ static TupleDesc ConstructTupleDescriptor(Relation heapRelation, int numatts, AttrNumber *attNums, Oid *classObjectId); static void ConstructIndexReldesc(Relation indexRelation, Oid amoid); -static void UpdateRelationRelation(Relation indexRelation, char *temp_relname); +static void UpdateRelationRelation(Relation indexRelation); static void InitializeAttributeOids(Relation indexRelation, int numatts, Oid indexoid); static void AppendAttributeTuples(Relation indexRelation, int numatts); @@ -320,7 +320,8 @@ ConstructIndexReldesc(Relation indexRelation, Oid amoid) indexRelation->rd_rel->relowner = GetUserId(); indexRelation->rd_rel->relam = amoid; indexRelation->rd_rel->relisshared = - IsSharedSystemRelationName(RelationGetPhysicalRelationName(indexRelation)); + (RelationGetNamespace(indexRelation) == PG_CATALOG_NAMESPACE) && + IsSharedSystemRelationName(RelationGetRelationName(indexRelation)); indexRelation->rd_rel->relkind = RELKIND_INDEX; indexRelation->rd_rel->relhasoids = false; } @@ -330,7 +331,7 @@ ConstructIndexReldesc(Relation indexRelation, Oid amoid) * ---------------------------------------------------------------- */ static void -UpdateRelationRelation(Relation indexRelation, char *temp_relname) +UpdateRelationRelation(Relation indexRelation) { Relation pg_class; HeapTuple tuple; @@ -350,16 +351,12 @@ UpdateRelationRelation(Relation indexRelation, char *temp_relname) tuple->t_data->t_oid = RelationGetRelid(indexRelation); heap_insert(pg_class, tuple); - if (temp_relname) - create_temp_relation(temp_relname, tuple); - /* * During normal processing, we need to make sure that the system * catalog indices are correct. Bootstrap (initdb) time doesn't * require this, because we make sure that the indices are correct * just before exiting. */ - if (!IsIgnoringSystemIndexes()) { CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, idescs); @@ -555,11 +552,10 @@ UpdateIndexRelation(Oid indexoid, */ Oid index_create(Oid heapRelationId, - char *indexRelationName, + const char *indexRelationName, IndexInfo *indexInfo, Oid accessMethodObjectId, Oid *classObjectId, - bool istemp, bool primary, bool allow_system_table_mods) { @@ -568,7 +564,6 @@ index_create(Oid heapRelationId, TupleDesc indexTupDesc; Oid namespaceId; Oid indexoid; - char *temp_relname = NULL; SetReindexProcessing(false); @@ -591,8 +586,7 @@ index_create(Oid heapRelationId, IsNormalProcessingMode()) elog(ERROR, "User-defined indexes on system catalogs are not supported"); - if ((!istemp && get_relname_relid(indexRelationName, namespaceId)) || - (istemp && is_temp_rel_name(indexRelationName))) + if (get_relname_relid(indexRelationName, namespaceId)) elog(ERROR, "index named \"%s\" already exists", indexRelationName); @@ -608,22 +602,14 @@ index_create(Oid heapRelationId, indexInfo->ii_KeyAttrNumbers, classObjectId); - if (istemp) - { - /* save user relation name because heap_create changes it */ - temp_relname = pstrdup(indexRelationName); /* save original */ - indexRelationName = palloc(NAMEDATALEN); - strcpy(indexRelationName, temp_relname); /* heap_create will - * change this */ - } - /* - * create the index relation + * create the index relation (but don't create storage yet) */ indexRelation = heap_create(indexRelationName, namespaceId, indexTupDesc, - istemp, false, allow_system_table_mods); + false, + allow_system_table_mods); indexoid = RelationGetRelid(indexRelation); /* @@ -645,7 +631,7 @@ index_create(Oid heapRelationId, * (append RELATION tuple) * ---------------- */ - UpdateRelationRelation(indexRelation, temp_relname); + UpdateRelationRelation(indexRelation); /* * We create the disk file for this relation here @@ -835,9 +821,6 @@ index_drop(Oid indexId) heap_close(userHeapRelation, NoLock); RelationForgetRelation(indexId); - - /* if it's a temp index, clear the temp mapping table entry */ - remove_temp_rel_by_relid(indexId); } /* ---------------------------------------------------------------- diff --git a/src/backend/catalog/namespace.c b/src/backend/catalog/namespace.c index e245ae5a3e..a1be64bd80 100644 --- a/src/backend/catalog/namespace.c +++ b/src/backend/catalog/namespace.c @@ -13,20 +13,86 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/catalog/namespace.c,v 1.3 2002/03/30 01:02:41 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/catalog/namespace.c,v 1.4 2002/03/31 06:26:30 tgl Exp $ * *------------------------------------------------------------------------- */ #include "postgres.h" +#include "access/heapam.h" +#include "access/xact.h" +#include "catalog/catname.h" +#include "catalog/heap.h" #include "catalog/namespace.h" +#include "catalog/pg_inherits.h" #include "catalog/pg_namespace.h" +#include "catalog/pg_shadow.h" #include "miscadmin.h" #include "nodes/makefuncs.h" +#include "storage/backendid.h" +#include "utils/fmgroids.h" #include "utils/lsyscache.h" #include "utils/syscache.h" +/* + * The namespace search path is a possibly-empty list of namespace OIDs. + * In addition to the explicit list, the TEMP table namespace is always + * implicitly searched first (if it's been initialized). Also, the system + * catalog namespace is always searched. If the system namespace is + * explicitly present in the path then it will be searched in the specified + * order; otherwise it will be searched after TEMP tables and *before* the + * explicit list. (It might seem that the system namespace should be + * implicitly last, but this behavior appears to be required by SQL99. + * Also, this provides a way to search the system namespace first without + * thereby making it the default creation target namespace.) + * + * The default creation target namespace is kept equal to the first element + * of the explicit list, or is the system namespace if the list is empty. + * + * In bootstrap mode or a standalone backend, the default search path is + * empty, so that the system namespace is the only one searched or inserted + * into. In multiuser mode, the default search path contains the PG_PUBLIC + * namespace, preceded by the user's own namespace if one exists. + */ + +static List *namespaceSearchPath = NIL; + +/* this flag must be updated correctly when namespaceSearchPath is changed */ +static bool pathContainsSystemNamespace = false; + +/* default place to create stuff */ +static Oid defaultCreationNamespace = PG_CATALOG_NAMESPACE; + +/* + * myTempNamespace is InvalidOid until and unless a TEMP namespace is set up + * in a particular backend session (this happens when a CREATE TEMP TABLE + * command is first executed). Thereafter it's the OID of the temp namespace. + */ +static Oid myTempNamespace = InvalidOid; + + +/* + * Deletion ordering constraint item. + */ +typedef struct DelConstraint +{ + Oid referencer; /* table to delete first */ + Oid referencee; /* table to delete second */ + int pred; /* workspace for TopoSortRels */ + struct DelConstraint *link; /* workspace for TopoSortRels */ +} DelConstraint; + + +/* Local functions */ +static Oid GetTempTableNamespace(void); +static void RemoveTempRelations(Oid tempNamespaceId); +static List *FindTempRelations(Oid tempNamespaceId); +static List *FindDeletionConstraints(List *relOids); +static List *TopoSortRels(List *relOids, List *constraintList); +static void RemoveTempRelationsCallback(void); + + /* * RangeVarGetRelid * Given a RangeVar describing an existing relation, @@ -52,6 +118,7 @@ RangeVarGetRelid(const RangeVar *relation, bool failOK) if (relation->schemaname) { + /* use exact schema given */ namespaceId = GetSysCacheOid(NAMESPACENAME, CStringGetDatum(relation->schemaname), 0, 0, 0); @@ -62,6 +129,7 @@ RangeVarGetRelid(const RangeVar *relation, bool failOK) } else { + /* search the namespace path */ relId = RelnameGetRelid(relation->relname); } @@ -100,8 +168,20 @@ RangeVarGetCreationNamespace(const RangeVar *newRelation) elog(ERROR, "Cross-database references are not implemented"); } + if (newRelation->istemp) + { + /* TEMP tables are created in our backend-local temp namespace */ + if (newRelation->schemaname) + elog(ERROR, "TEMP tables may not specify a namespace"); + /* Initialize temp namespace if first time through */ + if (!OidIsValid(myTempNamespace)) + myTempNamespace = GetTempTableNamespace(); + return myTempNamespace; + } + if (newRelation->schemaname) { + /* use exact schema given */ namespaceId = GetSysCacheOid(NAMESPACENAME, CStringGetDatum(newRelation->schemaname), 0, 0, 0); @@ -111,8 +191,8 @@ RangeVarGetCreationNamespace(const RangeVar *newRelation) } else { - /* XXX Wrong! Need to get a default schema from somewhere */ - namespaceId = PG_CATALOG_NAMESPACE; + /* use the default creation namespace */ + namespaceId = defaultCreationNamespace; } return namespaceId; @@ -126,23 +206,91 @@ RangeVarGetCreationNamespace(const RangeVar *newRelation) Oid RelnameGetRelid(const char *relname) { - /* XXX Wrong! must search search path */ - return get_relname_relid(relname, PG_CATALOG_NAMESPACE); + Oid relid; + List *lptr; + + /* + * If a TEMP-table namespace has been set up, it is implicitly first + * in the search path. + */ + if (OidIsValid(myTempNamespace)) + { + relid = get_relname_relid(relname, myTempNamespace); + if (OidIsValid(relid)) + return relid; + } + + /* + * If system namespace is not in path, implicitly search it before path + */ + if (!pathContainsSystemNamespace) + { + relid = get_relname_relid(relname, PG_CATALOG_NAMESPACE); + if (OidIsValid(relid)) + return relid; + } + + /* + * Else search the path + */ + foreach(lptr, namespaceSearchPath) + { + Oid namespaceId = (Oid) lfirsti(lptr); + + relid = get_relname_relid(relname, namespaceId); + if (OidIsValid(relid)) + return relid; + } + + /* Not found in path */ + return InvalidOid; } /* * TypenameGetTypid * Try to resolve an unqualified datatype name. * Returns OID if type found in search path, else InvalidOid. + * + * This is essentially the same as RelnameGetRelid, but we never search + * the TEMP table namespace --- there is no reason to refer to the types + * of temp tables, AFAICS. */ Oid TypenameGetTypid(const char *typname) { - /* XXX wrong, should use namespace search */ - return GetSysCacheOid(TYPENAMENSP, - PointerGetDatum(typname), - ObjectIdGetDatum(PG_CATALOG_NAMESPACE), - 0, 0); + Oid typid; + List *lptr; + + /* + * If system namespace is not in path, implicitly search it before path + */ + if (!pathContainsSystemNamespace) + { + typid = GetSysCacheOid(TYPENAMENSP, + PointerGetDatum(typname), + ObjectIdGetDatum(PG_CATALOG_NAMESPACE), + 0, 0); + if (OidIsValid(typid)) + return typid; + } + + /* + * Else search the path + */ + foreach(lptr, namespaceSearchPath) + { + Oid namespaceId = (Oid) lfirsti(lptr); + + typid = GetSysCacheOid(TYPENAMENSP, + PointerGetDatum(typname), + ObjectIdGetDatum(namespaceId), + 0, 0); + if (OidIsValid(typid)) + return typid; + } + + /* Not found in path */ + return InvalidOid; } /* @@ -150,6 +298,9 @@ TypenameGetTypid(const char *typname) * Given a possibly-qualified name for an object (in List-of-Values * format), determine what namespace the object should be created in. * Also extract and return the object name (last component of list). + * + * This is *not* used for tables. Hence, the TEMP table namespace is + * never selected as the creation target. */ Oid QualifiedNameGetCreationNamespace(List *names, char **objname_p) @@ -186,6 +337,7 @@ QualifiedNameGetCreationNamespace(List *names, char **objname_p) if (schemaname) { + /* use exact schema given */ namespaceId = GetSysCacheOid(NAMESPACENAME, CStringGetDatum(schemaname), 0, 0, 0); @@ -195,8 +347,8 @@ QualifiedNameGetCreationNamespace(List *names, char **objname_p) } else { - /* XXX Wrong! Need to get a default schema from somewhere */ - namespaceId = PG_CATALOG_NAMESPACE; + /* use the default creation namespace */ + namespaceId = defaultCreationNamespace; } *objname_p = objname; @@ -233,3 +385,320 @@ makeRangeVarFromNameList(List *names) return rel; } + +/* + * isTempNamespace - is the given namespace my temporary-table namespace? + */ +bool +isTempNamespace(Oid namespaceId) +{ + if (OidIsValid(myTempNamespace) && myTempNamespace == namespaceId) + return true; + return false; +} + +/* + * GetTempTableNamespace + * Initialize temp table namespace on first use in a particular backend + */ +static Oid +GetTempTableNamespace(void) +{ + char namespaceName[NAMEDATALEN]; + Oid namespaceId; + + snprintf(namespaceName, NAMEDATALEN, "pg_temp_%d", MyBackendId); + + namespaceId = GetSysCacheOid(NAMESPACENAME, + CStringGetDatum(namespaceName), + 0, 0, 0); + if (!OidIsValid(namespaceId)) + { + /* + * First use of this temp namespace in this database; create it. + * The temp namespaces are always owned by the superuser. + */ + namespaceId = NamespaceCreate(namespaceName, BOOTSTRAP_USESYSID); + /* Advance command counter to make namespace visible */ + CommandCounterIncrement(); + } + else + { + /* + * If the namespace already exists, clean it out (in case the + * former owner crashed without doing so). + */ + RemoveTempRelations(namespaceId); + } + + /* + * Register exit callback to clean out temp tables at backend shutdown. + */ + on_shmem_exit(RemoveTempRelationsCallback, 0); + + return namespaceId; +} + +/* + * Remove all relations in the specified temp namespace. + * + * This is called at backend shutdown (if we made any temp relations). + * It is also called when we begin using a pre-existing temp namespace, + * in order to clean out any relations that might have been created by + * a crashed backend. + */ +static void +RemoveTempRelations(Oid tempNamespaceId) +{ + List *tempRelList; + List *constraintList; + List *lptr; + + /* Get a list of relations to delete */ + tempRelList = FindTempRelations(tempNamespaceId); + + if (tempRelList == NIL) + return; /* nothing to do */ + + /* If more than one, sort them to respect any deletion-order constraints */ + if (length(tempRelList) > 1) + { + constraintList = FindDeletionConstraints(tempRelList); + if (constraintList != NIL) + tempRelList = TopoSortRels(tempRelList, constraintList); + } + + /* Scan the list and delete all entries */ + foreach(lptr, tempRelList) + { + Oid reloid = (Oid) lfirsti(lptr); + + heap_drop_with_catalog(reloid, true); + /* + * Advance cmd counter to make catalog changes visible, in case + * a later entry depends on this one. + */ + CommandCounterIncrement(); + } +} + +/* + * Find all relations in the specified temp namespace. + * + * Returns a list of relation OIDs. + */ +static List * +FindTempRelations(Oid tempNamespaceId) +{ + List *tempRelList = NIL; + Relation pgclass; + HeapScanDesc scan; + HeapTuple tuple; + ScanKeyData key; + + /* + * Scan pg_class to find all the relations in the target namespace. + * Ignore indexes, though, on the assumption that they'll go away + * when their tables are deleted. + */ + ScanKeyEntryInitialize(&key, 0x0, + Anum_pg_class_relnamespace, + F_OIDEQ, + ObjectIdGetDatum(tempNamespaceId)); + + pgclass = heap_openr(RelationRelationName, AccessShareLock); + scan = heap_beginscan(pgclass, false, SnapshotNow, 1, &key); + + while (HeapTupleIsValid(tuple = heap_getnext(scan, 0))) + { + switch (((Form_pg_class) GETSTRUCT(tuple))->relkind) + { + case RELKIND_RELATION: + case RELKIND_SEQUENCE: + case RELKIND_VIEW: + tempRelList = lconsi(tuple->t_data->t_oid, tempRelList); + break; + default: + break; + } + } + + heap_endscan(scan); + heap_close(pgclass, AccessShareLock); + + return tempRelList; +} + +/* + * Find deletion-order constraints involving the given relation OIDs. + * + * Returns a list of DelConstraint objects. + */ +static List * +FindDeletionConstraints(List *relOids) +{ + List *constraintList = NIL; + Relation inheritsrel; + HeapScanDesc scan; + HeapTuple tuple; + + /* + * Scan pg_inherits to find parents and children that are in the list. + */ + inheritsrel = heap_openr(InheritsRelationName, AccessShareLock); + scan = heap_beginscan(inheritsrel, 0, SnapshotNow, 0, NULL); + + while (HeapTupleIsValid(tuple = heap_getnext(scan, 0))) + { + Oid inhrelid = ((Form_pg_inherits) GETSTRUCT(tuple))->inhrelid; + Oid inhparent = ((Form_pg_inherits) GETSTRUCT(tuple))->inhparent; + + if (intMember(inhrelid, relOids) && intMember(inhparent, relOids)) + { + DelConstraint *item; + + item = (DelConstraint *) palloc(sizeof(DelConstraint)); + item->referencer = inhrelid; + item->referencee = inhparent; + constraintList = lcons(item, constraintList); + } + } + + heap_endscan(scan); + heap_close(inheritsrel, AccessShareLock); + + return constraintList; +} + +/* + * TopoSortRels -- topological sort of a list of rels to delete + * + * This is a lot simpler and slower than, for example, the topological sort + * algorithm shown in Knuth's Volume 1. However, we are not likely to be + * working with more than a few constraints, so the apparent slowness of the + * algorithm won't really matter. + */ +static List * +TopoSortRels(List *relOids, List *constraintList) +{ + int queue_size = length(relOids); + Oid *rels; + int *beforeConstraints; + DelConstraint **afterConstraints; + List *resultList = NIL; + List *lptr; + int i, + j, + k, + last; + + /* Allocate workspace */ + rels = (Oid *) palloc(queue_size * sizeof(Oid)); + beforeConstraints = (int *) palloc(queue_size * sizeof(int)); + afterConstraints = (DelConstraint **) + palloc(queue_size * sizeof(DelConstraint*)); + + /* Build an array of the target relation OIDs */ + i = 0; + foreach(lptr, relOids) + { + rels[i++] = (Oid) lfirsti(lptr); + } + + /* + * Scan the constraints, and for each rel in the array, generate a + * count of the number of constraints that say it must be before + * something else, plus a list of the constraints that say it must be + * after something else. The count for the j'th rel is stored in + * beforeConstraints[j], and the head of its list in + * afterConstraints[j]. Each constraint stores its list link in + * its link field (note any constraint will be in just one list). + * The array index for the before-rel of each constraint is + * remembered in the constraint's pred field. + */ + MemSet(beforeConstraints, 0, queue_size * sizeof(int)); + MemSet(afterConstraints, 0, queue_size * sizeof(DelConstraint*)); + foreach(lptr, constraintList) + { + DelConstraint *constraint = (DelConstraint *) lfirst(lptr); + Oid rel; + + /* Find the referencer rel in the array */ + rel = constraint->referencer; + for (j = queue_size; --j >= 0;) + { + if (rels[j] == rel) + break; + } + Assert(j >= 0); /* should have found a match */ + /* Find the referencee rel in the array */ + rel = constraint->referencee; + for (k = queue_size; --k >= 0;) + { + if (rels[k] == rel) + break; + } + Assert(k >= 0); /* should have found a match */ + beforeConstraints[j]++; /* referencer must come before */ + /* add this constraint to list of after-constraints for referencee */ + constraint->pred = j; + constraint->link = afterConstraints[k]; + afterConstraints[k] = constraint; + } + /*-------------------- + * Now scan the rels array backwards. At each step, output the + * last rel that has no remaining before-constraints, and decrease + * the beforeConstraints count of each of the rels it was constrained + * against. (This is the right order since we are building the result + * list back-to-front.) + * i = counter for number of rels left to output + * j = search index for rels[] + * dc = temp for scanning constraint list for rel j + * last = last valid index in rels (avoid redundant searches) + *-------------------- + */ + last = queue_size - 1; + for (i = queue_size; --i >= 0;) + { + DelConstraint *dc; + + /* Find next candidate to output */ + while (rels[last] == InvalidOid) + last--; + for (j = last; j >= 0; j--) + { + if (rels[j] != InvalidOid && beforeConstraints[j] == 0) + break; + } + /* If no available candidate, topological sort fails */ + if (j < 0) + elog(ERROR, "TopoSortRels: failed to find a workable deletion ordering"); + /* Output candidate, and mark it done by zeroing rels[] entry */ + resultList = lconsi(rels[j], resultList); + rels[j] = InvalidOid; + /* Update beforeConstraints counts of its predecessors */ + for (dc = afterConstraints[j]; dc; dc = dc->link) + beforeConstraints[dc->pred]--; + } + + /* Done */ + return resultList; +} + +/* + * Callback to remove temp relations at backend exit. + */ +static void +RemoveTempRelationsCallback(void) +{ + if (OidIsValid(myTempNamespace)) /* should always be true */ + { + /* Need to ensure we have a usable transaction. */ + AbortOutOfAnyTransaction(); + StartTransactionCommand(); + + RemoveTempRelations(myTempNamespace); + + CommitTransactionCommand(); + } +} diff --git a/src/backend/catalog/pg_namespace.c b/src/backend/catalog/pg_namespace.c index c340cd02f7..e2cf0128dc 100644 --- a/src/backend/catalog/pg_namespace.c +++ b/src/backend/catalog/pg_namespace.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/catalog/pg_namespace.c,v 1.1 2002/03/22 21:34:44 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/catalog/pg_namespace.c,v 1.2 2002/03/31 06:26:30 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -18,7 +18,6 @@ #include "catalog/catname.h" #include "catalog/indexing.h" #include "catalog/pg_namespace.h" -#include "miscadmin.h" #include "utils/builtins.h" #include "utils/syscache.h" @@ -28,7 +27,7 @@ * --------------- */ Oid -NamespaceCreate(const char *nspName) +NamespaceCreate(const char *nspName, int32 ownerSysId) { Relation nspdesc; HeapTuple tup; @@ -57,7 +56,7 @@ NamespaceCreate(const char *nspName) } namestrcpy(&nname, nspName); values[Anum_pg_namespace_nspname - 1] = NameGetDatum(&nname); - values[Anum_pg_namespace_nspowner - 1] = Int32GetDatum(GetUserId()); + values[Anum_pg_namespace_nspowner - 1] = Int32GetDatum(ownerSysId); nulls[Anum_pg_namespace_nspacl - 1] = 'n'; nspdesc = heap_openr(NamespaceRelationName, RowExclusiveLock); diff --git a/src/backend/commands/cluster.c b/src/backend/commands/cluster.c index 0d0cbbe788..c801c53f40 100644 --- a/src/backend/commands/cluster.c +++ b/src/backend/commands/cluster.c @@ -15,7 +15,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/cluster.c,v 1.75 2002/03/29 22:10:33 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/cluster.c,v 1.76 2002/03/31 06:26:30 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -35,12 +35,10 @@ #include "utils/builtins.h" #include "utils/lsyscache.h" #include "utils/syscache.h" -#include "utils/temprel.h" -static Oid copy_heap(Oid OIDOldHeap, char *NewName, bool istemp); -static void copy_index(Oid OIDOldIndex, Oid OIDNewHeap, char *NewIndexName, - bool istemp); +static Oid copy_heap(Oid OIDOldHeap, char *NewName); +static void copy_index(Oid OIDOldIndex, Oid OIDNewHeap, char *NewIndexName); static void rebuildheap(Oid OIDNewHeap, Oid OIDOldHeap, Oid OIDOldIndex); /* @@ -63,7 +61,6 @@ cluster(RangeVar *oldrelation, char *oldindexname) OIDNewHeap; Relation OldHeap, OldIndex; - bool istemp; char NewHeapName[NAMEDATALEN]; char NewIndexName[NAMEDATALEN]; RangeVar *NewHeap; @@ -76,8 +73,6 @@ cluster(RangeVar *oldrelation, char *oldindexname) OldHeap = heap_openrv(oldrelation, AccessExclusiveLock); OIDOldHeap = RelationGetRelid(OldHeap); - istemp = is_temp_rel_name(oldrelation->relname); - /* * The index is expected to be in the same namespace as the relation. */ @@ -105,7 +100,7 @@ cluster(RangeVar *oldrelation, char *oldindexname) */ snprintf(NewHeapName, NAMEDATALEN, "temp_%u", OIDOldHeap); - OIDNewHeap = copy_heap(OIDOldHeap, NewHeapName, istemp); + OIDNewHeap = copy_heap(OIDOldHeap, NewHeapName); /* We do not need CommandCounterIncrement() because copy_heap did it. */ @@ -120,7 +115,7 @@ cluster(RangeVar *oldrelation, char *oldindexname) /* Create new index over the tuples of the new heap. */ snprintf(NewIndexName, NAMEDATALEN, "temp_%u", OIDOldIndex); - copy_index(OIDOldIndex, OIDNewHeap, NewIndexName, istemp); + copy_index(OIDOldIndex, OIDNewHeap, NewIndexName); CommandCounterIncrement(); @@ -145,7 +140,7 @@ cluster(RangeVar *oldrelation, char *oldindexname) } static Oid -copy_heap(Oid OIDOldHeap, char *NewName, bool istemp) +copy_heap(Oid OIDOldHeap, char *NewName) { TupleDesc OldHeapDesc, tupdesc; @@ -166,7 +161,6 @@ copy_heap(Oid OIDOldHeap, char *NewName, bool istemp) tupdesc, OldHeap->rd_rel->relkind, OldHeap->rd_rel->relhasoids, - istemp, allowSystemTableMods); /* @@ -188,7 +182,7 @@ copy_heap(Oid OIDOldHeap, char *NewName, bool istemp) } static void -copy_index(Oid OIDOldIndex, Oid OIDNewHeap, char *NewIndexName, bool istemp) +copy_index(Oid OIDOldIndex, Oid OIDNewHeap, char *NewIndexName) { Relation OldIndex, NewHeap; @@ -209,7 +203,6 @@ copy_index(Oid OIDOldIndex, Oid OIDNewHeap, char *NewIndexName, bool istemp) indexInfo, OldIndex->rd_rel->relam, OldIndex->rd_index->indclass, - istemp, OldIndex->rd_index->indisprimary, allowSystemTableMods); diff --git a/src/backend/commands/command.c b/src/backend/commands/command.c index 2c029fa2ae..b79e65960f 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.168 2002/03/30 01:02:41 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.169 2002/03/31 06:26:30 tgl Exp $ * * NOTES * The PerformAddAttribute() code, like most of the relation @@ -55,7 +55,7 @@ #include "utils/lsyscache.h" #include "utils/syscache.h" #include "utils/relcache.h" -#include "utils/temprel.h" + static void drop_default(Oid relid, int16 attnum); static bool needs_toast_table(Relation rel); @@ -1344,20 +1344,27 @@ AlterTableAddConstraint(Oid myrelid, List *list; int count; - if (is_temp_rel_name(fkconstraint->pktable->relname) && - !is_temp_rel_name(RelationGetRelationName(rel))) - 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 doesn't delete rows out from under us. + * + * XXX wouldn't a lesser lock be sufficient? */ - pkrel = heap_openrv(fkconstraint->pktable, AccessExclusiveLock); + + /* + * Validity checks + */ if (pkrel->rd_rel->relkind != RELKIND_RELATION) elog(ERROR, "referenced table \"%s\" not a relation", fkconstraint->pktable->relname); + + if (isTempNamespace(RelationGetNamespace(pkrel)) && + !isTempNamespace(RelationGetNamespace(rel))) + elog(ERROR, "ALTER TABLE / ADD CONSTRAINT: Unable to reference temporary table from permanent table constraint."); + + /* Don't need pkrel open anymore, but hold lock */ heap_close(pkrel, NoLock); /* @@ -1763,8 +1770,9 @@ AlterTableCreateToastTable(Oid relOid, bool silent) toast_relid = heap_create_with_catalog(toast_relname, PG_TOAST_NAMESPACE, tupdesc, - RELKIND_TOASTVALUE, false, - false, true); + RELKIND_TOASTVALUE, + false, + true); /* make the toast relation visible, else index creation will fail */ CommandCounterIncrement(); @@ -1794,7 +1802,7 @@ AlterTableCreateToastTable(Oid relOid, bool silent) toast_idxid = index_create(toast_relid, toast_idxname, indexInfo, BTREE_AM_OID, classObjectId, - false, true, true); + true, true); /* * Update toast rel's pg_class entry to show that it has an index. The @@ -1971,7 +1979,7 @@ CreateSchemaCommand(CreateSchemaStmt *stmt) } /* Create the schema's namespace */ - NamespaceCreate(schemaName); + NamespaceCreate(schemaName, owner_userid); /* Let commands in the schema-element-list know about the schema */ CommandCounterIncrement(); diff --git a/src/backend/commands/creatinh.c b/src/backend/commands/creatinh.c index f85814cc0f..4a76e0c11e 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.94 2002/03/29 22:10:33 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/Attic/creatinh.c,v 1.95 2002/03/31 06:26:30 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -30,7 +30,7 @@ #include "parser/parse_type.h" #include "utils/acl.h" #include "utils/syscache.h" -#include "utils/temprel.h" + /* ---------------- * local stuff @@ -157,11 +157,11 @@ DefineRelation(CreateStmt *stmt, char relkind) } } - relationId = heap_create_with_catalog(relname, namespaceId, + relationId = heap_create_with_catalog(relname, + namespaceId, descriptor, relkind, stmt->hasoids || parentHasOids, - stmt->relation->istemp, allowSystemTableMods); StoreCatalogInheritance(relationId, inheritOids); @@ -447,7 +447,7 @@ MergeAttributes(List *schema, List *supers, bool istemp, elog(ERROR, "CREATE TABLE: inherited relation \"%s\" is not a table", parent->relname); /* Permanent rels cannot inherit from temporary ones */ - if (!istemp && is_temp_rel_name(parent->relname)) + if (!istemp && isTempNamespace(RelationGetNamespace(relation))) elog(ERROR, "CREATE TABLE: cannot inherit from temp relation \"%s\"", parent->relname); diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c index ae3476efb2..c931ab1927 100644 --- a/src/backend/commands/indexcmds.c +++ b/src/backend/commands/indexcmds.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.65 2002/03/26 19:15:41 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.66 2002/03/31 06:26:30 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -33,7 +33,6 @@ #include "utils/fmgroids.h" #include "utils/lsyscache.h" #include "utils/syscache.h" -#include "utils/temprel.h" #define IsFuncIndex(ATTR_LIST) (((IndexElem*)lfirst(ATTR_LIST))->args != NIL) @@ -74,7 +73,6 @@ DefineIndex(RangeVar *heapRelation, Oid *classObjectId; Oid accessMethodId; Oid relationId; - bool istemp = is_temp_rel_name(heapRelation->relname); Relation rel; HeapTuple tuple; Form_pg_am accessMethodForm; @@ -191,7 +189,7 @@ DefineIndex(RangeVar *heapRelation, index_create(relationId, indexRelationName, indexInfo, accessMethodId, classObjectId, - istemp, primary, allowSystemTableMods); + primary, allowSystemTableMods); /* * We update the relation's pg_class tuple even if it already has diff --git a/src/backend/commands/rename.c b/src/backend/commands/rename.c index 0f4c83fbeb..7e08dade24 100644 --- a/src/backend/commands/rename.c +++ b/src/backend/commands/rename.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/Attic/rename.c,v 1.66 2002/03/29 19:06:07 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/Attic/rename.c,v 1.67 2002/03/31 06:26:30 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -39,7 +39,6 @@ #include "utils/lsyscache.h" #include "utils/relcache.h" #include "utils/syscache.h" -#include "utils/temprel.h" #define RI_TRIGGER_PK 1 /* is a trigger on the PK relation */ @@ -270,13 +269,6 @@ renamerel(const RangeVar *relation, const char *newrelname) elog(ERROR, "renamerel: Illegal class name: \"%s\" -- pg_ is reserved for system catalogs", newrelname); - /* - * Check for renaming a temp table, which only requires altering the - * temp-table mapping, not the underlying table. - */ - if (rename_temp_relation(relation->relname, newrelname)) - return; /* all done... */ - /* * Grab an exclusive lock on the target table or index, which we will * NOT release until end of transaction. diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c index 36229b158e..c20c263717 100644 --- a/src/backend/commands/trigger.c +++ b/src/backend/commands/trigger.c @@ -7,7 +7,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.109 2002/03/29 22:10:33 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.110 2002/03/31 06:26:30 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -471,7 +471,7 @@ RelationRemoveTriggers(Relation rel) Form_pg_trigger pg_trigger = (Form_pg_trigger) GETSTRUCT(tup); elog(NOTICE, "DROP TABLE implicitly drops referential integrity trigger from table \"%s\"", - get_temp_rel_by_physicalname(get_rel_name(pg_trigger->tgrelid))); + get_rel_name(pg_trigger->tgrelid)); DropTrigger(pg_trigger->tgrelid, NameStr(pg_trigger->tgname)); diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 41405f3654..6553529cdc 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -13,7 +13,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.219 2002/03/21 23:27:22 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.220 2002/03/31 06:26:30 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -42,8 +42,6 @@ #include "utils/inval.h" #include "utils/relcache.h" #include "utils/syscache.h" -#include "utils/temprel.h" - #include "pgstat.h" @@ -351,16 +349,9 @@ getrels(Name VacRelP, const char *stmttype) * we could use the cache here, but it is clearer to use scankeys * for both vacuum cases, bjm 2000/01/19 */ - char *nontemp_relname; - - /* We must re-map temp table names bjm 2000-04-06 */ - nontemp_relname = get_temp_rel_by_username(NameStr(*VacRelP)); - if (nontemp_relname == NULL) - nontemp_relname = NameStr(*VacRelP); - ScanKeyEntryInitialize(&key, 0x0, Anum_pg_class_relname, F_NAMEEQ, - PointerGetDatum(nontemp_relname)); + PointerGetDatum(NameStr(*VacRelP))); } else { diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c index ab41dd50c3..5bbcf6b8ef 100644 --- a/src/backend/executor/execMain.c +++ b/src/backend/executor/execMain.c @@ -27,7 +27,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.155 2002/03/26 19:15:54 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.156 2002/03/31 06:26:31 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -724,8 +724,8 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate) heap_create_with_catalog(intoName, namespaceId, tupdesc, - RELKIND_RELATION, true, - parseTree->into->istemp, + RELKIND_RELATION, + true, allowSystemTableMods); FreeTupleDesc(tupdesc); diff --git a/src/backend/parser/analyze.c b/src/backend/parser/analyze.c index d02b0bf58e..42e18d8ac1 100644 --- a/src/backend/parser/analyze.c +++ b/src/backend/parser/analyze.c @@ -6,7 +6,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.224 2002/03/29 19:06:10 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.225 2002/03/31 06:26:31 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -37,8 +37,6 @@ #include "utils/fmgroids.h" #include "utils/relcache.h" #include "utils/syscache.h" -#include "utils/temprel.h" - #ifdef MULTIBYTE #include "mb/pg_wchar.h" #endif @@ -2553,7 +2551,6 @@ transformAlterTableStmt(ParseState *pstate, AlterTableStmt *stmt, cxt.stmtType = "ALTER TABLE"; cxt.relation = stmt->relation; cxt.inhRelations = NIL; - cxt.relation->istemp = is_temp_rel_name(stmt->relation->relname); cxt.relOid = RangeVarGetRelid(stmt->relation, false); cxt.hasoids = SearchSysCacheExists(ATTNUM, ObjectIdGetDatum(cxt.relOid), @@ -2583,7 +2580,6 @@ transformAlterTableStmt(ParseState *pstate, AlterTableStmt *stmt, cxt.stmtType = "ALTER TABLE"; cxt.relation = stmt->relation; cxt.inhRelations = NIL; - cxt.relation->istemp = is_temp_rel_name(stmt->relation->relname); cxt.relOid = RangeVarGetRelid(stmt->relation, false); cxt.hasoids = SearchSysCacheExists(ATTNUM, ObjectIdGetDatum(cxt.relOid), diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 40795016ab..49d3c129f3 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -10,7 +10,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.142 2002/03/29 22:10:33 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.143 2002/03/31 06:26:31 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -49,7 +49,6 @@ #include "utils/acl.h" #include "utils/lsyscache.h" #include "utils/syscache.h" -#include "utils/temprel.h" #include "access/xlog.h" /* @@ -128,8 +127,7 @@ CheckDropPermissions(RangeVar *rel, char rightkind) elog(ERROR, "you do not own %s \"%s\"", rentry->name, rel->relname); - if (!allowSystemTableMods && IsSystemRelationName(rel->relname) && - !is_temp_relname(rel->relname)) + if (!allowSystemTableMods && IsSystemRelationName(rel->relname)) elog(ERROR, "%s \"%s\" is a system %s", rentry->name, rel->relname, rentry->name); diff --git a/src/backend/utils/cache/Makefile b/src/backend/utils/cache/Makefile index 5ac5a06827..eb9d3e89c0 100644 --- a/src/backend/utils/cache/Makefile +++ b/src/backend/utils/cache/Makefile @@ -4,7 +4,7 @@ # Makefile for utils/cache # # IDENTIFICATION -# $Header: /cvsroot/pgsql/src/backend/utils/cache/Makefile,v 1.15 2001/10/06 23:21:44 tgl Exp $ +# $Header: /cvsroot/pgsql/src/backend/utils/cache/Makefile,v 1.16 2002/03/31 06:26:31 tgl Exp $ # #------------------------------------------------------------------------- @@ -13,7 +13,7 @@ top_builddir = ../../../.. include $(top_builddir)/src/Makefile.global OBJS = catcache.o inval.o relcache.o syscache.o lsyscache.o \ - fcache.o temprel.o + fcache.o all: SUBSYS.o diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c index 4894cd2779..fcdffa9132 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.158 2002/03/26 19:16:10 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.159 2002/03/31 06:26:31 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -60,7 +60,6 @@ #include "utils/lsyscache.h" #include "utils/relcache.h" #include "utils/syscache.h" -#include "utils/temprel.h" /* @@ -186,7 +185,7 @@ do { \ nodentry->reldesc = RELATION; \ if (RelationGetNamespace(RELATION) == PG_CATALOG_NAMESPACE) \ { \ - char *relname = RelationGetPhysicalRelationName(RELATION); \ + char *relname = RelationGetRelationName(RELATION); \ RelNameCacheEnt *namehentry; \ namehentry = (RelNameCacheEnt*)hash_search(RelationSysNameCache, \ relname, \ @@ -247,7 +246,7 @@ do { \ elog(WARNING, "trying to delete a reldesc that does not exist."); \ if (RelationGetNamespace(RELATION) == PG_CATALOG_NAMESPACE) \ { \ - char *relname = RelationGetPhysicalRelationName(RELATION); \ + char *relname = RelationGetRelationName(RELATION); \ RelNameCacheEnt *namehentry; \ namehentry = (RelNameCacheEnt*)hash_search(RelationSysNameCache, \ relname, \ @@ -1571,18 +1570,9 @@ RelationIdGetRelation(Oid relationId) Relation RelationSysNameGetRelation(const char *relationName) { - char *temprelname; Relation rd; RelationBuildDescInfo buildinfo; - /* - * if caller is looking for a temp relation, substitute its real name; - * we only index temp rels by their real names. - */ - temprelname = get_temp_rel_by_username(relationName); - if (temprelname != NULL) - relationName = temprelname; - /* * first try and get a reldesc from the cache */ diff --git a/src/backend/utils/cache/syscache.c b/src/backend/utils/cache/syscache.c index a160e4fb1b..7f988782c7 100644 --- a/src/backend/utils/cache/syscache.c +++ b/src/backend/utils/cache/syscache.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/cache/syscache.c,v 1.71 2002/03/29 19:06:15 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/cache/syscache.c,v 1.72 2002/03/31 06:26:32 tgl Exp $ * * NOTES * These routines allow the parser/planner/executor to perform @@ -42,7 +42,6 @@ #include "catalog/pg_type.h" #include "utils/catcache.h" #include "utils/syscache.h" -#include "utils/temprel.h" #include "miscadmin.h" @@ -500,29 +499,9 @@ SearchSysCache(int cacheId, Datum key3, Datum key4) { - if (cacheId < 0 || cacheId >= SysCacheSize) - { + if (cacheId < 0 || cacheId >= SysCacheSize || + ! PointerIsValid(SysCache[cacheId])) elog(ERROR, "SearchSysCache: Bad cache id %d", cacheId); - return (HeapTuple) NULL; - } - - Assert(PointerIsValid(SysCache[cacheId])); - - /* - * If someone tries to look up a relname, translate temp relation - * names to real names. Less obviously, apply the same translation to - * type names, so that the type tuple of a temp table will be found - * when sought. This is a kluge ... temp table substitution should be - * happening at a higher level ... - */ - if (cacheId == RELNAMENSP || cacheId == TYPENAMENSP) - { - char *nontemp_relname; - - nontemp_relname = get_temp_rel_by_username(DatumGetCString(key1)); - if (nontemp_relname != NULL) - key1 = CStringGetDatum(nontemp_relname); - } return SearchCatCache(SysCache[cacheId], key1, key2, key3, key4); } diff --git a/src/backend/utils/cache/temprel.c b/src/backend/utils/cache/temprel.c deleted file mode 100644 index 7ab609eaf3..0000000000 --- a/src/backend/utils/cache/temprel.c +++ /dev/null @@ -1,335 +0,0 @@ -/*------------------------------------------------------------------------- - * - * temprel.c - * POSTGRES temporary relation handling - * - * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * - * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/cache/Attic/temprel.c,v 1.36 2002/03/29 19:06:16 tgl Exp $ - * - *------------------------------------------------------------------------- - */ - -/* - * This implements temp tables by modifying the relname cache lookups - * of pg_class. - * - * When a temp table is created, normal entries are made for it in pg_class, - * pg_type, etc using a unique "physical" relation name. We also make an - * entry in the temp table list maintained by this module. Subsequently, - * relname lookups are filtered through the temp table list, and attempts - * to look up a temp table name are changed to look up the physical name. - * This allows temp table names to mask a regular table of the same name - * for the duration of the session. The temp table list is also used - * to drop the underlying physical relations at session shutdown. - */ - -#include "postgres.h" - -#include - -#include "catalog/heap.h" -#include "catalog/index.h" -#include "miscadmin.h" -#include "utils/temprel.h" - - -/* ---------------- - * global variables - * ---------------- - */ - -static List *temp_rels = NIL; - -typedef struct TempTable -{ - NameData user_relname; /* logical name of temp table */ - NameData relname; /* underlying unique name */ - Oid relid; /* needed properties of rel */ - char relkind; - - /* - * If this entry was created during this xact, it should be deleted at - * xact abort. Conversely, if this entry was deleted during this - * xact, it should be removed at xact commit. We leave deleted - * entries in the list until commit so that we can roll back if needed - * --- but we ignore them for purposes of lookup! - */ - bool created_in_cur_xact; - bool deleted_in_cur_xact; -} TempTable; - - -/* - * Create a temp-relation list entry given the logical temp table name - * and the already-created pg_class tuple for the underlying relation. - * - * NB: we assume a check has already been made for a duplicate logical name. - */ -void -create_temp_relation(const char *relname, HeapTuple pg_class_tuple) -{ - Form_pg_class pg_class_form = (Form_pg_class) GETSTRUCT(pg_class_tuple); - MemoryContext oldcxt; - TempTable *temp_rel; - - oldcxt = MemoryContextSwitchTo(CacheMemoryContext); - - temp_rel = (TempTable *) palloc(sizeof(TempTable)); - - StrNCpy(NameStr(temp_rel->user_relname), relname, - NAMEDATALEN); - StrNCpy(NameStr(temp_rel->relname), NameStr(pg_class_form->relname), - NAMEDATALEN); - temp_rel->relid = pg_class_tuple->t_data->t_oid; - temp_rel->relkind = pg_class_form->relkind; - temp_rel->created_in_cur_xact = true; - temp_rel->deleted_in_cur_xact = false; - - temp_rels = lcons(temp_rel, temp_rels); - - MemoryContextSwitchTo(oldcxt); -} - -/* - * Remove a temp relation map entry (part of DROP TABLE on a temp table). - * We don't actually remove the entry, just mark it dead. - * - * We don't have the relname for indexes, so we just pass the oid. - */ -void -remove_temp_rel_by_relid(Oid relid) -{ - List *l; - - foreach(l, temp_rels) - { - TempTable *temp_rel = (TempTable *) lfirst(l); - - if (temp_rel->relid == relid) - temp_rel->deleted_in_cur_xact = true; - - /* - * Keep scanning 'cause there could be multiple matches; see - * RENAME - */ - } -} - -/* - * To implement ALTER TABLE RENAME on a temp table, we shouldn't touch - * the underlying physical table at all, just change the map entry! - * - * This routine is invoked early in ALTER TABLE RENAME to check for - * the temp-table case. If oldname matches a temp table name, change - * the mapping to the new logical name and return TRUE (or elog if - * there is a conflict with another temp table name). If there is - * no match, return FALSE indicating that normal rename should proceed. - * - * We also reject an attempt to rename a normal table to a name in use - * as a temp table name. That would fail later on anyway when rename.c - * looks for a rename conflict, but we can give a more specific error - * message for the problem here. - * - * It might seem that we need to check for attempts to rename the physical - * file underlying a temp table, but that'll be rejected anyway because - * pg_tempXXX looks like a system table name. - */ -bool -rename_temp_relation(const char *oldname, - const char *newname) -{ - List *l; - - foreach(l, temp_rels) - { - TempTable *temp_rel = (TempTable *) lfirst(l); - MemoryContext oldcxt; - TempTable *new_temp_rel; - - if (temp_rel->deleted_in_cur_xact) - continue; /* ignore it if logically deleted */ - - if (strcmp(NameStr(temp_rel->user_relname), oldname) != 0) - continue; /* ignore non-matching entries */ - - /* We are renaming a temp table --- is it OK to do so? */ - 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); - - new_temp_rel = (TempTable *) palloc(sizeof(TempTable)); - memcpy(new_temp_rel, temp_rel, sizeof(TempTable)); - - StrNCpy(NameStr(new_temp_rel->user_relname), newname, NAMEDATALEN); - new_temp_rel->created_in_cur_xact = true; - - lnext(l) = lcons(new_temp_rel, lnext(l)); - - temp_rel->deleted_in_cur_xact = true; - - MemoryContextSwitchTo(oldcxt); - - return true; - } - - /* Old name does not match any temp table name, what about new? */ - if (is_temp_rel_name(newname)) - elog(ERROR, "Cannot rename \"%s\" to \"%s\": a temp table by that name already exists", - oldname, newname); - - return false; -} - - -/* - * Remove underlying relations for all temp rels at backend shutdown. - */ -void -remove_all_temp_relations(void) -{ - List *l; - - /* skip xact start overhead if nothing to do */ - if (temp_rels == NIL) - return; - - AbortOutOfAnyTransaction(); - StartTransactionCommand(); - - /* - * 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. Note that entries will be deleted in reverse order of - * creation --- that's critical for cases involving inheritance. - */ - foreach(l, temp_rels) - { - TempTable *temp_rel = (TempTable *) lfirst(l); - - if (temp_rel->deleted_in_cur_xact) - continue; /* ignore it if deleted already */ - - if (temp_rel->relkind != RELKIND_INDEX) - heap_drop_with_catalog(temp_rel->relid, allowSystemTableMods); - else - index_drop(temp_rel->relid); - /* advance cmd counter to make catalog changes visible */ - CommandCounterIncrement(); - } - - CommitTransactionCommand(); -} - -/* - * Clean up temprel mapping entries during transaction commit or abort. - * - * During commit, remove entries that were deleted during this transaction; - * during abort, remove those created during this transaction. - * - * We do not need to worry about removing the underlying physical relation; - * that's someone else's job. - */ -void -AtEOXact_temp_relations(bool isCommit) -{ - List *l, - *prev; - - prev = NIL; - l = temp_rels; - while (l != NIL) - { - TempTable *temp_rel = (TempTable *) lfirst(l); - - if (isCommit ? temp_rel->deleted_in_cur_xact : - temp_rel->created_in_cur_xact) - { - /* This entry must be removed */ - if (prev != NIL) - { - lnext(prev) = lnext(l); - pfree(l); - l = lnext(prev); - } - else - { - temp_rels = lnext(l); - pfree(l); - l = temp_rels; - } - pfree(temp_rel); - } - else - { - /* This entry must be preserved */ - temp_rel->created_in_cur_xact = false; - temp_rel->deleted_in_cur_xact = false; - prev = l; - l = lnext(l); - } - } -} - - -/* - * Map user name to physical name --- returns NULL if no entry. - * - * 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) -{ - List *l; - - foreach(l, temp_rels) - { - TempTable *temp_rel = (TempTable *) lfirst(l); - - if (temp_rel->deleted_in_cur_xact) - continue; /* ignore it if logically deleted */ - - if (strcmp(NameStr(temp_rel->user_relname), user_relname) == 0) - return NameStr(temp_rel->relname); - } - return NULL; -} - -/* - * Map physical name to user name --- returns pstrdup'd input if no match. - */ -char * -get_temp_rel_by_physicalname(const char *relname) -{ - List *l; - - foreach(l, temp_rels) - { - TempTable *temp_rel = (TempTable *) lfirst(l); - - if (temp_rel->deleted_in_cur_xact) - continue; /* ignore it if logically deleted */ - - if (strcmp(NameStr(temp_rel->relname), relname) == 0) - return NameStr(temp_rel->user_relname); - } - /* needed for bootstrapping temp tables */ - return pstrdup(relname); -} diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c index 3ffb8af054..9cd5b194d9 100644 --- a/src/backend/utils/init/postinit.c +++ b/src/backend/utils/init/postinit.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/init/postinit.c,v 1.100 2002/03/06 06:10:25 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/init/postinit.c,v 1.101 2002/03/31 06:26:32 tgl Exp $ * * *------------------------------------------------------------------------- @@ -39,7 +39,6 @@ #include "utils/portal.h" #include "utils/relcache.h" #include "utils/syscache.h" -#include "utils/temprel.h" static void ReverifyMyDatabase(const char *name); @@ -386,20 +385,13 @@ InitPostgres(const char *dbname, const char *username) RelationCacheInitializePhase3(); /* - * Set up process-exit callbacks to remove temp relations and then do - * pre-shutdown cleanup. This should be last because we want - * shmem_exit to call these routines before the exit callbacks that - * are registered by buffer manager, lock manager, etc. We need to - * run this code before we close down database access! + * Set up process-exit callback to do pre-shutdown cleanup. This should + * be last because we want shmem_exit to call this routine before the exit + * callbacks that are registered by buffer manager, lock manager, etc. + * We need to run this code before we close down database access! */ on_shmem_exit(ShutdownPostgres, 0); - /* - * because callbacks are called in reverse order, this gets done - * first: - */ - on_shmem_exit(remove_all_temp_relations, 0); - /* close the transaction we started above */ if (!bootstrap) CommitTransactionCommand(); diff --git a/src/include/catalog/heap.h b/src/include/catalog/heap.h index b7313c6425..a0ab4c708a 100644 --- a/src/include/catalog/heap.h +++ b/src/include/catalog/heap.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: heap.h,v 1.48 2002/03/29 19:06:17 tgl Exp $ + * $Id: heap.h,v 1.49 2002/03/31 06:26:32 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -27,16 +27,19 @@ typedef struct RawColumnDefault * tree) */ } RawColumnDefault; -extern Relation heap_create(char *relname, Oid relnamespace, +extern Relation heap_create(const char *relname, + Oid relnamespace, TupleDesc tupDesc, - bool istemp, bool storage_create, + bool storage_create, bool allow_system_table_mods); extern void heap_storage_create(Relation rel); -extern Oid heap_create_with_catalog(char *relname, Oid relnamespace, +extern Oid heap_create_with_catalog(const char *relname, + Oid relnamespace, TupleDesc tupdesc, - char relkind, bool relhasoids, bool istemp, + char relkind, + bool relhasoids, bool allow_system_table_mods); extern void heap_drop_with_catalog(Oid rid, bool allow_system_table_mods); diff --git a/src/include/catalog/index.h b/src/include/catalog/index.h index 86f0824e84..70e33f88fd 100644 --- a/src/include/catalog/index.h +++ b/src/include/catalog/index.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: index.h,v 1.46 2002/03/26 19:16:25 tgl Exp $ + * $Id: index.h,v 1.47 2002/03/31 06:26:32 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -30,11 +30,10 @@ typedef void (*IndexBuildCallback) (Relation index, extern Oid index_create(Oid heapRelationId, - char *indexRelationName, + const char *indexRelationName, IndexInfo *indexInfo, Oid accessMethodObjectId, Oid *classObjectId, - bool istemp, bool primary, bool allow_system_table_mods); diff --git a/src/include/catalog/namespace.h b/src/include/catalog/namespace.h index 242050de49..aed33a10b3 100644 --- a/src/include/catalog/namespace.h +++ b/src/include/catalog/namespace.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: namespace.h,v 1.3 2002/03/30 01:02:42 tgl Exp $ + * $Id: namespace.h,v 1.4 2002/03/31 06:26:32 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -29,4 +29,6 @@ extern Oid QualifiedNameGetCreationNamespace(List *names, char **objname_p); extern RangeVar *makeRangeVarFromNameList(List *names); +extern bool isTempNamespace(Oid namespaceId); + #endif /* NAMESPACE_H */ diff --git a/src/include/catalog/pg_namespace.h b/src/include/catalog/pg_namespace.h index 607b74132e..fceee09fcb 100644 --- a/src/include/catalog/pg_namespace.h +++ b/src/include/catalog/pg_namespace.h @@ -8,7 +8,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: pg_namespace.h,v 1.2 2002/03/30 01:02:42 tgl Exp $ + * $Id: pg_namespace.h,v 1.3 2002/03/31 06:26:32 tgl Exp $ * * NOTES * the genbki.sh script reads this file and generates .bki @@ -69,7 +69,7 @@ typedef FormData_pg_namespace *Form_pg_namespace; DATA(insert OID = 11 ( "pg_catalog" PGUID "{=r}" )); DESCR("System catalog namespace"); #define PG_CATALOG_NAMESPACE 11 -DATA(insert OID = 99 ( "pg_toast" PGUID "{=r}" )); +DATA(insert OID = 99 ( "pg_toast" PGUID "{=}" )); DESCR("Reserved namespace for TOAST tables"); #define PG_TOAST_NAMESPACE 99 DATA(insert OID = 2071 ( "pg_public" PGUID "{=rw}" )); @@ -80,6 +80,6 @@ DESCR("Standard public namespace"); /* * prototypes for functions in pg_namespace.c */ -extern Oid NamespaceCreate(const char *nspName); +extern Oid NamespaceCreate(const char *nspName, int32 ownerSysId); #endif /* PG_NAMESPACE_H */ diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h index 16398b4c08..4a3fbd1eb1 100644 --- a/src/include/utils/rel.h +++ b/src/include/utils/rel.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: rel.h,v 1.57 2002/03/26 19:16:58 tgl Exp $ + * $Id: rel.h,v 1.58 2002/03/31 06:26:32 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -238,49 +238,15 @@ typedef Relation *RelationPtr; */ #define RelationGetIndexStrategy(relation) ((relation)->rd_istrat) -/* - * Handle temp relations - */ -#define PG_TEMP_REL_PREFIX "pg_temp" -#define PG_TEMP_REL_PREFIX_LEN 7 - -#define is_temp_relname(relname) \ - (strncmp(relname, PG_TEMP_REL_PREFIX, PG_TEMP_REL_PREFIX_LEN) == 0) - -/* - * RelationGetPhysicalRelationName - * - * Returns the rel's physical name, ie, the name appearing in pg_class. - * - * While this name is unique across all rels in the database, it is not - * necessarily useful for accessing the rel, since a temp table of the - * same name might mask the rel. It is useful mainly for determining if - * the rel is a shared system rel or not. - * - * The macro is rather unfortunately named, since the pg_class name no longer - * has anything to do with the file name used for physical storage of the rel. - */ -#define RelationGetPhysicalRelationName(relation) \ - (NameStr((relation)->rd_rel->relname)) - /* * RelationGetRelationName * - * Returns the relation's logical name (as seen by the user). + * Returns the rel's name. * - * If the rel is a temp rel, the temp name will be returned. Therefore, - * this name is not unique. But it is the name to use in heap_openr(), - * for example. + * Note that the name is only unique within the containing namespace. */ #define RelationGetRelationName(relation) \ -(\ - is_temp_relname(RelationGetPhysicalRelationName(relation)) \ - ? \ - get_temp_rel_by_physicalname( \ - RelationGetPhysicalRelationName(relation)) \ - : \ - RelationGetPhysicalRelationName(relation) \ -) + (NameStr((relation)->rd_rel->relname)) /* * RelationGetNamespace @@ -290,7 +256,4 @@ typedef Relation *RelationPtr; #define RelationGetNamespace(relation) \ ((relation)->rd_rel->relnamespace) -/* added to prevent circular dependency. bjm 1999/11/15 */ -extern char *get_temp_rel_by_physicalname(const char *relname); - #endif /* REL_H */ diff --git a/src/include/utils/temprel.h b/src/include/utils/temprel.h deleted file mode 100644 index a8a6a00568..0000000000 --- a/src/include/utils/temprel.h +++ /dev/null @@ -1,33 +0,0 @@ -/*------------------------------------------------------------------------- - * - * temprel.h - * Temporary relation functions - * - * - * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * $Id: temprel.h,v 1.20 2001/11/05 17:46:36 momjian Exp $ - * - *------------------------------------------------------------------------- - */ -#ifndef TEMPREL_H -#define TEMPREL_H - -#include "access/htup.h" - -extern void create_temp_relation(const char *relname, - HeapTuple pg_class_tuple); -extern void remove_temp_rel_by_relid(Oid relid); -extern bool rename_temp_relation(const char *oldname, - const char *newname); - -extern void remove_all_temp_relations(void); -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 */ -- GitLab