aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/utils')
-rw-r--r--src/backend/utils/adt/acl.c6
-rw-r--r--src/backend/utils/adt/ruleutils.c20
-rw-r--r--src/backend/utils/cache/inval.c27
-rw-r--r--src/backend/utils/cache/lsyscache.c58
-rw-r--r--src/backend/utils/cache/relcache.c73
-rw-r--r--src/backend/utils/init/globals.c4
-rw-r--r--src/backend/utils/init/miscinit.c11
-rw-r--r--src/backend/utils/init/postinit.c17
-rw-r--r--src/backend/utils/misc/database.c38
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);