diff options
author | Bruce Momjian | 2007-01-25 04:35:11 +0000 |
---|---|---|
committer | Bruce Momjian | 2007-01-25 04:35:11 +0000 |
commit | 148ea5cbeae1681ef06e7f3ccb554b8db728b45e (patch) | |
tree | b6325d169510eb7a38f0558ef5dc301dac988c53 /src/backend/commands/tablespace.c | |
parent | 5af6b2abe90d52f7a4dee998c3a5eb24794bf0b1 (diff) |
Add GUC temp_tablespaces to provide a default location for temporary
objects.
Jaime Casanova
Diffstat (limited to 'src/backend/commands/tablespace.c')
-rw-r--r-- | src/backend/commands/tablespace.c | 143 |
1 files changed, 141 insertions, 2 deletions
diff --git a/src/backend/commands/tablespace.c b/src/backend/commands/tablespace.c index cd86aef4019..d2cb245f150 100644 --- a/src/backend/commands/tablespace.c +++ b/src/backend/commands/tablespace.c @@ -37,7 +37,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/tablespace.c,v 1.40 2007/01/05 22:19:26 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/commands/tablespace.c,v 1.41 2007/01/25 04:35:10 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -65,9 +65,12 @@ #include "utils/lsyscache.h" -/* GUC variable */ +/* GUC variables */ char *default_tablespace = NULL; +char *temp_tablespaces = NULL; +int next_temp_tablespace; +int num_temp_tablespaces; static bool remove_tablespace_directories(Oid tablespaceoid, bool redo); static void set_short_version(const char *path); @@ -930,6 +933,142 @@ GetDefaultTablespace(void) return result; } +/* + * Routines for handling the GUC variable 'temp_tablespaces'. + */ + +/* assign_hook: validate new temp_tablespaces, do extra actions as needed */ +const char * +assign_temp_tablespaces(const char *newval, bool doit, GucSource source) +{ + char *rawname; + List *namelist; + ListCell *l; + + /* Need a modifiable copy of string */ + rawname = pstrdup(newval); + + /* Parse string into list of identifiers */ + if (!SplitIdentifierString(rawname, ',', &namelist)) + { + /* syntax error in name list */ + pfree(rawname); + list_free(namelist); + return NULL; + } + + num_temp_tablespaces = 0; + foreach(l, namelist) + { + char *curname = (char *) lfirst(l); + + /* + * If we aren't inside a transaction, we cannot do database access so + * cannot verify the individual names. Must accept the list on faith. + */ + if (source >= PGC_S_INTERACTIVE && IsTransactionState()) + { + /* + * Verify that all the names are valid tablspace names + * We do not check for USAGE rights should we? + */ + if (get_tablespace_oid(curname) == InvalidOid) + ereport((source == PGC_S_TEST) ? NOTICE : ERROR, + (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("tablespace \"%s\" does not exist", curname))); + } + num_temp_tablespaces++; + } + + /* + * Select the first tablespace to use + */ + next_temp_tablespace = MyProcPid % num_temp_tablespaces; + + pfree(rawname); + list_free(namelist); + return newval; +} + +/* + * GetTempTablespace -- get the OID of the tablespace for temporary objects + * + * May return InvalidOid to indicate "use the database's default tablespace" + * + * This exists to hide the temp_tablespace GUC variable. + */ +Oid +GetTempTablespace(void) +{ + Oid result; + char *curname = NULL; + char *rawname; + List *namelist; + ListCell *l; + int i = 0; + + if ( temp_tablespaces == NULL ) + return InvalidOid; + + /* Need a modifiable version of temp_tablespaces */ + rawname = pstrdup(temp_tablespaces); + + /* Parse string into list of identifiers */ + if (!SplitIdentifierString(rawname, ',', &namelist)) + { + /* syntax error in name list */ + pfree(rawname); + list_free(namelist); + return InvalidOid; + } + + /* + * Iterate through the list of namespaces until the one we need + * (next_temp_tablespace) + */ + foreach(l, namelist) + { + curname = (char *) lfirst(l); + if ( i == next_temp_tablespace ) + break; + i++; + } + + + /* Prepare for the next time the function is called */ + next_temp_tablespace++; + if (next_temp_tablespace == num_temp_tablespaces) + next_temp_tablespace = 0; + + /* Fast path for temp_tablespaces == "" */ + if ( curname == NULL || curname[0] == '\0') { + list_free(namelist); + pfree(rawname); + return InvalidOid; + } + + /* + * It is tempting to cache this lookup for more speed, but then we would + * fail to detect the case where the tablespace was dropped since the GUC + * variable was set. Note also that we don't complain if the value fails + * to refer to an existing tablespace; we just silently return InvalidOid, + * causing the new object to be created in the database's tablespace. + */ + result = get_tablespace_oid(curname); + + /* We don't free rawname before because curname points to a part of it */ + pfree(rawname); + + /* + * Allow explicit specification of database's default tablespace in + * default_tablespace without triggering permissions checks. + */ + if (result == MyDatabaseTableSpace) + result = InvalidOid; + + list_free(namelist); + return result; +} /* * get_tablespace_oid - given a tablespace name, look up the OID |