summaryrefslogtreecommitdiff
path: root/src/backend/commands/tablespace.c
diff options
context:
space:
mode:
authorBruce Momjian2007-01-25 04:35:11 +0000
committerBruce Momjian2007-01-25 04:35:11 +0000
commit148ea5cbeae1681ef06e7f3ccb554b8db728b45e (patch)
treeb6325d169510eb7a38f0558ef5dc301dac988c53 /src/backend/commands/tablespace.c
parent5af6b2abe90d52f7a4dee998c3a5eb24794bf0b1 (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.c143
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