diff options
Diffstat (limited to 'src/backend/utils')
-rw-r--r-- | src/backend/utils/adt/acl.c | 6 | ||||
-rw-r--r-- | src/backend/utils/adt/ruleutils.c | 20 | ||||
-rw-r--r-- | src/backend/utils/cache/inval.c | 27 | ||||
-rw-r--r-- | src/backend/utils/cache/lsyscache.c | 58 | ||||
-rw-r--r-- | src/backend/utils/cache/relcache.c | 73 | ||||
-rw-r--r-- | src/backend/utils/init/globals.c | 4 | ||||
-rw-r--r-- | src/backend/utils/init/miscinit.c | 11 | ||||
-rw-r--r-- | src/backend/utils/init/postinit.c | 17 | ||||
-rw-r--r-- | src/backend/utils/misc/database.c | 38 |
9 files changed, 176 insertions, 78 deletions
diff --git a/src/backend/utils/adt/acl.c b/src/backend/utils/adt/acl.c index d02683245ac..4b13e318be6 100644 --- a/src/backend/utils/adt/acl.c +++ b/src/backend/utils/adt/acl.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/adt/acl.c,v 1.105 2004/06/01 21:49:22 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/utils/adt/acl.c,v 1.106 2004/06/18 06:13:49 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -539,6 +539,10 @@ acldefault(GrantObjectType objtype, AclId ownerid) world_default = ACL_NO_RIGHTS; owner_default = ACL_ALL_RIGHTS_NAMESPACE; break; + case ACL_OBJECT_TABLESPACE: + world_default = ACL_NO_RIGHTS; + owner_default = ACL_ALL_RIGHTS_TABLESPACE; + break; default: elog(ERROR, "unrecognized objtype: %d", (int) objtype); world_default = ACL_NO_RIGHTS; /* keep compiler quiet */ diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 4caaabd62cd..1a2fe54d7ac 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -3,7 +3,7 @@ * back to source text * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.172 2004/06/16 01:26:47 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.173 2004/06/18 06:13:49 tgl Exp $ * * This software is copyrighted by Jan Wieck - Hamburg. * @@ -53,6 +53,7 @@ #include "catalog/pg_operator.h" #include "catalog/pg_shadow.h" #include "catalog/pg_trigger.h" +#include "commands/tablespace.h" #include "executor/spi.h" #include "lib/stringinfo.h" #include "nodes/makefuncs.h" @@ -768,6 +769,23 @@ pg_get_indexdef_worker(Oid indexrelid, int colno, int prettyFlags) appendStringInfoChar(&buf, ')'); /* + * If the index is in a different tablespace from its parent, + * tell about that + */ + if (OidIsValid(idxrelrec->reltablespace) && + idxrelrec->reltablespace != get_rel_tablespace(indrelid)) + { + char *spcname = get_tablespace_name(idxrelrec->reltablespace); + + if (spcname) /* just paranoia... */ + { + appendStringInfo(&buf, " TABLESPACE %s", + quote_identifier(spcname)); + pfree(spcname); + } + } + + /* * If it's a partial index, decompile and append the predicate */ if (!heap_attisnull(ht_idx, Anum_pg_index_indpred)) diff --git a/src/backend/utils/cache/inval.c b/src/backend/utils/cache/inval.c index 7b00f0531e2..ea958a27b46 100644 --- a/src/backend/utils/cache/inval.c +++ b/src/backend/utils/cache/inval.c @@ -74,7 +74,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/cache/inval.c,v 1.61 2004/05/06 16:10:57 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/utils/cache/inval.c,v 1.62 2004/06/18 06:13:52 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -308,7 +308,7 @@ AddRelcacheInvalidationMessage(InvalidationListHeader *hdr, /* We assume dbId need not be checked because it will never change */ /* relfilenode fields must be checked to support reassignment */ ProcessMessageList(hdr->rclist, - if (msg->rc.relId == relId && + if (msg->rc.relId == relId && RelFileNodeEquals(msg->rc.physId, physId)) return); /* OK, add the item */ @@ -555,14 +555,18 @@ PrepareForTupleInvalidation(Relation relation, HeapTuple tuple, databaseId = InvalidOid; else databaseId = MyDatabaseId; - rnode.tblNode = databaseId; /* XXX change for tablespaces */ + if (classtup->reltablespace) + rnode.spcNode = classtup->reltablespace; + else + rnode.spcNode = MyDatabaseTableSpace; + rnode.dbNode = databaseId; rnode.relNode = classtup->relfilenode; /* * Note: during a pg_class row update that assigns a new relfilenode - * value, we will be called on both the old and new tuples, and thus - * will broadcast invalidation messages showing both the old and new - * relfilenode values. This ensures that other backends will close - * smgr references to the old relfilenode file. + * or reltablespace value, we will be called on both the old and new + * tuples, and thus will broadcast invalidation messages showing both + * the old and new RelFileNode values. This ensures that other + * backends will close smgr references to the old file. */ } else if (tupleRelId == RelOid_pg_attribute) @@ -580,7 +584,8 @@ PrepareForTupleInvalidation(Relation relation, HeapTuple tuple, */ databaseId = MyDatabaseId; /* We assume no smgr cache flush is needed, either */ - rnode.tblNode = InvalidOid; + rnode.spcNode = InvalidOid; + rnode.dbNode = InvalidOid; rnode.relNode = InvalidOid; } else @@ -760,7 +765,11 @@ CacheInvalidateRelcacheByTuple(HeapTuple classTuple) databaseId = InvalidOid; else databaseId = MyDatabaseId; - rnode.tblNode = databaseId; /* XXX change for tablespaces */ + if (classtup->reltablespace) + rnode.spcNode = classtup->reltablespace; + else + rnode.spcNode = MyDatabaseTableSpace; + rnode.dbNode = databaseId; rnode.relNode = classtup->relfilenode; RegisterRelcacheInvalidation(databaseId, relationId, rnode); diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c index d51d1c18925..1621982502a 100644 --- a/src/backend/utils/cache/lsyscache.c +++ b/src/backend/utils/cache/lsyscache.c @@ -7,7 +7,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/cache/lsyscache.c,v 1.113 2004/06/06 00:41:27 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/utils/cache/lsyscache.c,v 1.114 2004/06/18 06:13:52 tgl Exp $ * * NOTES * Eventually, the index information should go through here, too. @@ -986,6 +986,34 @@ get_rel_namespace(Oid relid) } /* + * get_rel_tablespace + * Returns the pg_tablespace OID associated with a given relation. + * + * Note: failure return is InvalidOid, which cannot be distinguished from + * "default tablespace for this database", but that seems OK. + */ +Oid +get_rel_tablespace(Oid relid) +{ + HeapTuple tp; + + tp = SearchSysCache(RELOID, + ObjectIdGetDatum(relid), + 0, 0, 0); + if (HeapTupleIsValid(tp)) + { + Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp); + Oid result; + + result = reltup->reltablespace; + ReleaseSysCache(tp); + return result; + } + else + return InvalidOid; +} + +/* * get_rel_type_id * * Returns the pg_type OID associated with a given relation. @@ -1980,6 +2008,34 @@ get_namespace_name(Oid nspid) return NULL; } +/* + * get_namespace_tablespace + * Returns the default tablespace of a given namespace + * + * Note: failure return is InvalidOid, which cannot be distinguished from + * "default tablespace for this database", but that seems OK. + */ +Oid +get_namespace_tablespace(Oid nspid) +{ + HeapTuple tp; + + tp = SearchSysCache(NAMESPACEOID, + ObjectIdGetDatum(nspid), + 0, 0, 0); + if (HeapTupleIsValid(tp)) + { + Form_pg_namespace nsptup = (Form_pg_namespace) GETSTRUCT(tp); + Oid result; + + result = nsptup->nsptablespace; + ReleaseSysCache(tp); + return result; + } + else + return InvalidOid; +} + /* ---------- PG_SHADOW CACHE ---------- */ /* diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c index 4221976f0b1..ee8b46407e1 100644 --- a/src/backend/utils/cache/relcache.c +++ b/src/backend/utils/cache/relcache.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/cache/relcache.c,v 1.204 2004/05/30 23:40:37 neilc Exp $ + * $PostgreSQL: pgsql/src/backend/utils/cache/relcache.c,v 1.205 2004/06/18 06:13:52 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -260,6 +260,7 @@ static void RelationBuildTupleDesc(RelationBuildDescInfo buildinfo, Relation relation); static Relation RelationBuildDesc(RelationBuildDescInfo buildinfo, Relation oldrelation); +static void RelationInitPhysicalAddr(Relation relation); static void AttrDefaultFetch(Relation relation); static void CheckConstraintFetch(Relation relation); static List *insert_ordered_oid(List *list, Oid datum); @@ -873,11 +874,10 @@ RelationBuildDesc(RelationBuildDescInfo buildinfo, */ RelationInitLockInfo(relation); /* see lmgr.c */ - if (relation->rd_rel->relisshared) - relation->rd_node.tblNode = InvalidOid; - else - relation->rd_node.tblNode = MyDatabaseId; - relation->rd_node.relNode = relation->rd_rel->relfilenode; + /* + * initialize physical addressing information for the relation + */ + RelationInitPhysicalAddr(relation); /* make sure relation is marked as having no open file yet */ relation->rd_smgr = NULL; @@ -893,6 +893,23 @@ RelationBuildDesc(RelationBuildDescInfo buildinfo, } /* + * Initialize the physical addressing info (RelFileNode) for a relcache entry + */ +static void +RelationInitPhysicalAddr(Relation relation) +{ + if (relation->rd_rel->reltablespace) + relation->rd_node.spcNode = relation->rd_rel->reltablespace; + else + relation->rd_node.spcNode = MyDatabaseTableSpace; + if (relation->rd_rel->relisshared) + relation->rd_node.dbNode = InvalidOid; + else + relation->rd_node.dbNode = MyDatabaseId; + relation->rd_node.relNode = relation->rd_rel->relfilenode; +} + +/* * Initialize index-access-method support data for an index relation */ void @@ -1343,18 +1360,17 @@ formrdesc(const char *relationName, * initialize relation id from info in att array (my, this is ugly) */ RelationGetRelid(relation) = relation->rd_att->attrs[0]->attrelid; + relation->rd_rel->relfilenode = RelationGetRelid(relation); /* - * initialize the relation's lock manager and RelFileNode information + * initialize the relation lock manager information */ RelationInitLockInfo(relation); /* see lmgr.c */ - if (relation->rd_rel->relisshared) - relation->rd_node.tblNode = InvalidOid; - else - relation->rd_node.tblNode = MyDatabaseId; - relation->rd_node.relNode = - relation->rd_rel->relfilenode = RelationGetRelid(relation); + /* + * initialize physical addressing information for the relation + */ + RelationInitPhysicalAddr(relation); /* * initialize the rel-has-index flag, using hardwired knowledge @@ -1570,7 +1586,8 @@ RelationReloadClassinfo(Relation relation) relation->rd_id); relp = (Form_pg_class) GETSTRUCT(pg_class_tuple); memcpy((char *) relation->rd_rel, (char *) relp, CLASS_TUPLE_SIZE); - relation->rd_node.relNode = relp->relfilenode; + /* Now we can recalculate physical address */ + RelationInitPhysicalAddr(relation); heap_freetuple(pg_class_tuple); relation->rd_targblock = InvalidBlockNumber; /* Okay, now it's valid again */ @@ -2040,8 +2057,9 @@ Relation RelationBuildLocalRelation(const char *relname, Oid relnamespace, TupleDesc tupDesc, - Oid relid, Oid dbid, - RelFileNode rnode, + Oid relid, + Oid reltablespace, + bool shared_relation, bool nailit) { Relation rel; @@ -2125,20 +2143,23 @@ RelationBuildLocalRelation(const char *relname, /* * Insert relation physical and logical identifiers (OIDs) into the - * right places. + * right places. Note that the physical ID (relfilenode) is initially + * the same as the logical ID (OID). */ - rel->rd_rel->relisshared = (dbid == InvalidOid); + rel->rd_rel->relisshared = shared_relation; RelationGetRelid(rel) = relid; for (i = 0; i < natts; i++) rel->rd_att->attrs[i]->attrelid = relid; - rel->rd_node = rnode; - rel->rd_rel->relfilenode = rnode.relNode; + rel->rd_rel->relfilenode = relid; + rel->rd_rel->reltablespace = reltablespace; RelationInitLockInfo(rel); /* see lmgr.c */ + RelationInitPhysicalAddr(rel); + /* * Okay to insert into the relcache hash tables. */ @@ -3053,16 +3074,12 @@ load_relcache_init_file(void) MemSet(&rel->pgstat_info, 0, sizeof(rel->pgstat_info)); /* - * Make sure database ID is correct. This is needed in case the - * pg_internal.init file was copied from some other database by - * CREATE DATABASE. + * Recompute lock and physical addressing info. This is needed in + * case the pg_internal.init file was copied from some other database + * by CREATE DATABASE. */ - if (rel->rd_rel->relisshared) - rel->rd_node.tblNode = InvalidOid; - else - rel->rd_node.tblNode = MyDatabaseId; - RelationInitLockInfo(rel); + RelationInitPhysicalAddr(rel); } /* diff --git a/src/backend/utils/init/globals.c b/src/backend/utils/init/globals.c index 3a5d33724a4..4f0f8b67c24 100644 --- a/src/backend/utils/init/globals.c +++ b/src/backend/utils/init/globals.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/init/globals.c,v 1.90 2004/05/30 17:58:12 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/utils/init/globals.c,v 1.91 2004/06/18 06:13:54 tgl Exp $ * * NOTES * Globals used all over the place should be declared here and not @@ -58,6 +58,8 @@ BackendId MyBackendId = InvalidBackendId; char *DatabasePath = NULL; Oid MyDatabaseId = InvalidOid; +Oid MyDatabaseTableSpace = InvalidOid; + pid_t PostmasterPid = 0; /* diff --git a/src/backend/utils/init/miscinit.c b/src/backend/utils/init/miscinit.c index 6f9ff5aef4d..b0c5ff82e38 100644 --- a/src/backend/utils/init/miscinit.c +++ b/src/backend/utils/init/miscinit.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/init/miscinit.c,v 1.126 2004/05/30 23:40:38 neilc Exp $ + * $PostgreSQL: pgsql/src/backend/utils/init/miscinit.c,v 1.127 2004/06/18 06:13:54 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -157,7 +157,6 @@ void SetDataDir(const char *dir) { char *new; - int newlen; AssertArg(dir); @@ -212,13 +211,7 @@ SetDataDir(const char *dir) * Strip any trailing slash. Not strictly necessary, but avoids * generating funny-looking paths to individual files. */ - newlen = strlen(new); - if (newlen > 1 && (new[newlen - 1] == '/' -#ifdef WIN32 - || new[newlen - 1] == '\\' -#endif - )) - new[newlen - 1] = '\0'; + canonicalize_path(new); if (DataDir) free(DataDir); diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c index e80187d5752..48d28d429f2 100644 --- a/src/backend/utils/init/postinit.c +++ b/src/backend/utils/init/postinit.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/init/postinit.c,v 1.133 2004/05/29 22:48:21 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/utils/init/postinit.c,v 1.134 2004/06/18 06:13:54 tgl Exp $ * * *------------------------------------------------------------------------- @@ -26,6 +26,7 @@ #include "catalog/namespace.h" #include "catalog/pg_database.h" #include "catalog/pg_shadow.h" +#include "catalog/pg_tablespace.h" #include "commands/trigger.h" #include "mb/pg_wchar.h" #include "miscadmin.h" @@ -239,12 +240,12 @@ InitPostgres(const char *dbname, const char *username) if (bootstrap) { MyDatabaseId = TemplateDbOid; - SetDatabasePath(GetDatabasePath(MyDatabaseId)); + MyDatabaseTableSpace = DEFAULTTABLESPACE_OID; + SetDatabasePath(GetDatabasePath(MyDatabaseId, MyDatabaseTableSpace)); } else { - char *fullpath, - datpath[MAXPGPATH]; + char *fullpath; /* * Formerly we validated DataDir here, but now that's done @@ -252,11 +253,11 @@ InitPostgres(const char *dbname, const char *username) */ /* - * Find oid and path of the database we're about to open. Since - * we're not yet up and running we have to use the hackish + * Find oid and tablespace of the database we're about to open. + * Since we're not yet up and running we have to use the hackish * GetRawDatabaseInfo. */ - GetRawDatabaseInfo(dbname, &MyDatabaseId, datpath); + GetRawDatabaseInfo(dbname, &MyDatabaseId, &MyDatabaseTableSpace); if (!OidIsValid(MyDatabaseId)) ereport(FATAL, @@ -264,7 +265,7 @@ InitPostgres(const char *dbname, const char *username) errmsg("database \"%s\" does not exist", dbname))); - fullpath = GetDatabasePath(MyDatabaseId); + fullpath = GetDatabasePath(MyDatabaseId, MyDatabaseTableSpace); /* Verify the database path */ diff --git a/src/backend/utils/misc/database.c b/src/backend/utils/misc/database.c index 37844a03a94..1eeb5357040 100644 --- a/src/backend/utils/misc/database.c +++ b/src/backend/utils/misc/database.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/misc/database.c,v 1.60 2004/01/22 20:57:39 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/utils/misc/database.c,v 1.61 2004/06/18 06:13:56 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -21,6 +21,7 @@ #include "catalog/catname.h" #include "catalog/catalog.h" #include "catalog/pg_database.h" +#include "catalog/pg_tablespace.h" #include "miscadmin.h" #include "utils/syscache.h" @@ -29,12 +30,13 @@ static bool PhonyHeapTupleSatisfiesNow(HeapTupleHeader tuple); /* -------------------------------- - * GetRawDatabaseInfo() -- Find the OID and path of the database. + * GetRawDatabaseInfo() -- Find the OID and tablespace of the database. * - * The database's oid forms half of the unique key for the system - * caches and lock tables. We therefore want it initialized before - * we open any relations, since opening relations puts things in the - * cache. To get around this problem, this code opens and scans the + * We need both the OID and the default tablespace in order to find + * the database's system catalogs. Moreover the database's OID forms + * half of the unique key for the system caches and lock tables, so + * we must have it before we can use any of the cache mechanisms. + * To get around these problems, this code opens and scans the * pg_database relation by hand. * * This code knows way more than it should about the layout of @@ -43,19 +45,21 @@ static bool PhonyHeapTupleSatisfiesNow(HeapTupleHeader tuple); * -------------------------------- */ void -GetRawDatabaseInfo(const char *name, Oid *db_id, char *path) +GetRawDatabaseInfo(const char *name, Oid *db_id, Oid *db_tablespace) { int dbfd; int nbytes; - int pathlen; HeapTupleData tup; + Form_pg_database tup_db; Page pg; char *dbfname; - Form_pg_database tup_db; RelFileNode rnode; - rnode.tblNode = 0; + /* hard-wired path to pg_database */ + rnode.spcNode = GLOBALTABLESPACE_OID; + rnode.dbNode = 0; rnode.relNode = RelOid_pg_database; + dbfname = relpath(rnode); if ((dbfd = open(dbfname, O_RDONLY | PG_BINARY, 0)) < 0) @@ -121,7 +125,7 @@ GetRawDatabaseInfo(const char *name, Oid *db_id, char *path) * committed and dead tuples to be marked with correct states. * * XXX wouldn't it be better to let new backends read the - * database OID from a flat file, handled the same way we + * database info from a flat file, handled the same way we * handle the password relation? */ if (!PhonyHeapTupleSatisfiesNow(tup.t_data)) @@ -134,15 +138,9 @@ GetRawDatabaseInfo(const char *name, Oid *db_id, char *path) if (strcmp(name, NameStr(tup_db->datname)) == 0) { - /* Found it; extract the OID and the database path. */ + /* Found it; extract the db's OID and tablespace. */ *db_id = HeapTupleGetOid(&tup); - pathlen = VARSIZE(&(tup_db->datpath)) - VARHDRSZ; - if (pathlen < 0) - pathlen = 0; /* pure paranoia */ - if (pathlen >= MAXPGPATH) - pathlen = MAXPGPATH - 1; /* more paranoia */ - strncpy(path, VARDATA(&(tup_db->datpath)), pathlen); - path[pathlen] = '\0'; + *db_tablespace = tup_db->dattablespace; goto done; } } @@ -150,7 +148,7 @@ GetRawDatabaseInfo(const char *name, Oid *db_id, char *path) /* failed to find it... */ *db_id = InvalidOid; - *path = '\0'; + *db_tablespace = InvalidOid; done: close(dbfd); |