summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael P2012-01-24 07:36:53 +0000
committerMichael P2012-01-24 07:36:53 +0000
commitba5f1a0be3b0688bf2a1d04eaddf714ce0e0ae50 (patch)
tree6187e857af8ee9ab1f33e3fd2eb59a54d6d34316
parent8985fe5209bf8270fed7894b8efb6dc737f0e699 (diff)
Support for TABLESPACE
TABLESPACE are re-enabled without having any modifications in its grammar. A user defining a location for tablespace needs to be sure that this location exists on all the nodes of the cluster. A suffix with node name is added on the PG_XXX folder created in tablespace to support tablespace in case several nodes are running on the same node. New tablespace folder format is PG_XXX_NodeName. As node name is unique and constant in the cluster, this insures that no conflict will appear at the creation level. For the time begin, DBA has no way to refine location of tablespace for a single node level but this will be added later with extra support of CREATE/DROP TABLESPACE through EXECUTE DIRECT.
-rw-r--r--doc-xc/src/sgml/ref/create_tablespace.sgmlin6
-rw-r--r--src/backend/catalog/catalog.c47
-rw-r--r--src/backend/commands/tablespace.c38
-rw-r--r--src/backend/pgxc/nodemgr/nodemgr.c7
-rw-r--r--src/backend/storage/file/fd.c24
-rw-r--r--src/backend/storage/file/reinit.c9
-rw-r--r--src/backend/tcop/utility.c18
-rw-r--r--src/backend/utils/adt/dbsize.c12
-rw-r--r--src/backend/utils/adt/misc.c16
-rw-r--r--src/backend/utils/cache/relcache.c6
-rw-r--r--src/include/pgxc/nodemgr.h2
-rw-r--r--src/test/regress/output/tablespace_1.source92
12 files changed, 174 insertions, 103 deletions
diff --git a/doc-xc/src/sgml/ref/create_tablespace.sgmlin b/doc-xc/src/sgml/ref/create_tablespace.sgmlin
index 91024be421..eb79ca53b9 100644
--- a/doc-xc/src/sgml/ref/create_tablespace.sgmlin
+++ b/doc-xc/src/sgml/ref/create_tablespace.sgmlin
@@ -112,9 +112,9 @@ CREATE TABLESPACE <replaceable class="parameter">tablespace_name</replaceable> [
&xconly;
<para>
<productname>Postgres-XC</> assigns the same path to a tablespace
- for all the coordinators and datanodes. If you run these
- components on the same server or VM, there could be serious
- conflict on the file names.
+ for all the coordinators and datanodes. So when creating a tablespace,
+ user needs to have permission to the same location path on all the servers
+ involved in the cluster.
</para>
<!## end>
</refsect1>
diff --git a/src/backend/catalog/catalog.c b/src/backend/catalog/catalog.c
index 68504b7929..02335b0750 100644
--- a/src/backend/catalog/catalog.c
+++ b/src/backend/catalog/catalog.c
@@ -43,6 +43,9 @@
#include "utils/fmgroids.h"
#include "utils/rel.h"
#include "utils/tqual.h"
+#ifdef PGXC
+#include "pgxc/pgxc.h"
+#endif
#define FORKNAMECHARS 4 /* max chars for a fork name */
@@ -171,8 +174,25 @@ relpathbackend(RelFileNode rnode, BackendId backend, ForkNumber forknum)
{
pathlen = 9 + 1 + OIDCHARS + 1
+ strlen(TABLESPACE_VERSION_DIRECTORY) + 1 + OIDCHARS + 1
+#ifdef PGXC
+ /* Postgres-XC tablespaces include node name */
+ + strlen(PGXCNodeName) + 1
+#endif
+ OIDCHARS + 1 + FORKNAMECHARS + 1;
path = (char *) palloc(pathlen);
+#ifdef PGXC
+ if (forknum != MAIN_FORKNUM)
+ snprintf(path, pathlen, "pg_tblspc/%u/%s_%s/%u/%u_%s",
+ rnode.spcNode, TABLESPACE_VERSION_DIRECTORY,
+ PGXCNodeName,
+ rnode.dbNode, rnode.relNode,
+ forkNames[forknum]);
+ else
+ snprintf(path, pathlen, "pg_tblspc/%u/%s_%s/%u/%u",
+ rnode.spcNode, TABLESPACE_VERSION_DIRECTORY,
+ PGXCNodeName,
+ rnode.dbNode, rnode.relNode);
+#else
if (forknum != MAIN_FORKNUM)
snprintf(path, pathlen, "pg_tblspc/%u/%s/%u/%u_%s",
rnode.spcNode, TABLESPACE_VERSION_DIRECTORY,
@@ -182,14 +202,31 @@ relpathbackend(RelFileNode rnode, BackendId backend, ForkNumber forknum)
snprintf(path, pathlen, "pg_tblspc/%u/%s/%u/%u",
rnode.spcNode, TABLESPACE_VERSION_DIRECTORY,
rnode.dbNode, rnode.relNode);
+#endif
}
else
{
/* OIDCHARS will suffice for an integer, too */
pathlen = 9 + 1 + OIDCHARS + 1
+ strlen(TABLESPACE_VERSION_DIRECTORY) + 1 + OIDCHARS + 2
+#ifdef PGXC
+ + strlen(PGXCNodeName) + 1
+#endif
+ OIDCHARS + 1 + OIDCHARS + 1 + FORKNAMECHARS + 1;
path = (char *) palloc(pathlen);
+#ifdef PGXC
+ if (forknum != MAIN_FORKNUM)
+ snprintf(path, pathlen, "pg_tblspc/%u/%s_%s/%u/t%d_%u_%s",
+ rnode.spcNode, TABLESPACE_VERSION_DIRECTORY,
+ PGXCNodeName,
+ rnode.dbNode, backend, rnode.relNode,
+ forkNames[forknum]);
+ else
+ snprintf(path, pathlen, "pg_tblspc/%u/%s_%s/%u/t%d_%u",
+ rnode.spcNode, TABLESPACE_VERSION_DIRECTORY,
+ PGXCNodeName,
+ rnode.dbNode, backend, rnode.relNode);
+#else
if (forknum != MAIN_FORKNUM)
snprintf(path, pathlen, "pg_tblspc/%u/%s/%u/t%d_%u_%s",
rnode.spcNode, TABLESPACE_VERSION_DIRECTORY,
@@ -199,6 +236,7 @@ relpathbackend(RelFileNode rnode, BackendId backend, ForkNumber forknum)
snprintf(path, pathlen, "pg_tblspc/%u/%s/%u/t%d_%u",
rnode.spcNode, TABLESPACE_VERSION_DIRECTORY,
rnode.dbNode, backend, rnode.relNode);
+#endif
}
}
return path;
@@ -237,10 +275,19 @@ GetDatabasePath(Oid dbNode, Oid spcNode)
{
/* All other tablespaces are accessed via symlinks */
pathlen = 9 + 1 + OIDCHARS + 1 + strlen(TABLESPACE_VERSION_DIRECTORY) +
+#ifdef PGXC
+ /* Postgres-XC tablespaces include node name in path */
+ strlen(PGXCNodeName) + 1 +
+#endif
1 + OIDCHARS + 1;
path = (char *) palloc(pathlen);
+#ifdef PGXC
+ snprintf(path, pathlen, "pg_tblspc/%u/%s_%s/%u",
+ spcNode, TABLESPACE_VERSION_DIRECTORY, PGXCNodeName, dbNode);
+#else
snprintf(path, pathlen, "pg_tblspc/%u/%s/%u",
spcNode, TABLESPACE_VERSION_DIRECTORY, dbNode);
+#endif
}
return path;
}
diff --git a/src/backend/commands/tablespace.c b/src/backend/commands/tablespace.c
index 3024dc4b64..4964cb749b 100644
--- a/src/backend/commands/tablespace.c
+++ b/src/backend/commands/tablespace.c
@@ -78,6 +78,10 @@
#include "utils/rel.h"
#include "utils/syscache.h"
#include "utils/tqual.h"
+#ifdef PGXC
+#include "pgxc/nodemgr.h"
+#include "pgxc/pgxc.h"
+#endif
/* GUC variables */
@@ -277,6 +281,14 @@ CreateTableSpace(CreateTableSpaceStmt *stmt)
* whole path, but mkdir() uses the first two parts.
*/
if (strlen(location) + 1 + strlen(TABLESPACE_VERSION_DIRECTORY) + 1 +
+#ifdef PGXC
+ /*
+ * In Postgres-XC, node name is added in the tablespace folder name to
+ * insure unique names for nodes sharing the same server.
+ * So real format is PG_XXX_<nodename>/<dboid>/<relid>.<nnn>''
+ */
+ strlen(PGXCNodeName) + 1 +
+#endif
OIDCHARS + 1 + OIDCHARS + 1 + OIDCHARS > MAXPGPATH)
ereport(ERROR,
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
@@ -541,12 +553,29 @@ static void
create_tablespace_directories(const char *location, const Oid tablespaceoid)
{
char *linkloc = palloc(OIDCHARS + OIDCHARS + 1);
+#ifdef PGXC
+ char *location_with_version_dir = palloc(strlen(location) + 1 +
+ strlen(TABLESPACE_VERSION_DIRECTORY) + 1 +
+ PGXC_NODENAME_LENGTH + 1);
+#else
char *location_with_version_dir = palloc(strlen(location) + 1 +
strlen(TABLESPACE_VERSION_DIRECTORY) + 1);
+#endif
sprintf(linkloc, "pg_tblspc/%u", tablespaceoid);
+#ifdef PGXC
+ /*
+ * In Postgres-XC a suffix based on node name is added at the end
+ * of TABLESPACE_VERSION_DIRECTORY. Node name unicity in Postgres-XC
+ * cluster insures unicity of tablespace.
+ */
+ sprintf(location_with_version_dir, "%s/%s_%s", location,
+ TABLESPACE_VERSION_DIRECTORY,
+ PGXCNodeName);
+#else
sprintf(location_with_version_dir, "%s/%s", location,
TABLESPACE_VERSION_DIRECTORY);
+#endif
/*
* Attempt to coerce target directory to safe permissions. If this fails,
@@ -647,10 +676,19 @@ destroy_tablespace_directories(Oid tablespaceoid, bool redo)
char *subfile;
struct stat st;
+#ifdef PGXC
+ linkloc_with_version_dir = palloc(9 + 1 + OIDCHARS + 1 +
+ strlen(PGXCNodeName) + 1 +
+ strlen(TABLESPACE_VERSION_DIRECTORY));
+ sprintf(linkloc_with_version_dir, "pg_tblspc/%u/%s_%s", tablespaceoid,
+ TABLESPACE_VERSION_DIRECTORY,
+ PGXCNodeName);
+#else
linkloc_with_version_dir = palloc(9 + 1 + OIDCHARS + 1 +
strlen(TABLESPACE_VERSION_DIRECTORY));
sprintf(linkloc_with_version_dir, "pg_tblspc/%u/%s", tablespaceoid,
TABLESPACE_VERSION_DIRECTORY);
+#endif
/*
* Check if the tablespace still contains any files. We try to rmdir each
diff --git a/src/backend/pgxc/nodemgr/nodemgr.c b/src/backend/pgxc/nodemgr/nodemgr.c
index 0345b11afc..975495838f 100644
--- a/src/backend/pgxc/nodemgr/nodemgr.c
+++ b/src/backend/pgxc/nodemgr/nodemgr.c
@@ -312,6 +312,13 @@ PgxcNodeCreate(CreateNodeStmt *stmt)
errmsg("PGXC Node %s: object already defined",
node_name)));
+ /* Check length of node name */
+ if (strlen(node_name) > PGXC_NODENAME_LENGTH)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
+ errmsg("Node name \"%s\" is too long",
+ node_name)));
+
/* Filter options */
check_options(stmt->options, &dhost,
&dport, &dtype,
diff --git a/src/backend/storage/file/fd.c b/src/backend/storage/file/fd.c
index 820e6dbfd9..e7792eac7d 100644
--- a/src/backend/storage/file/fd.c
+++ b/src/backend/storage/file/fd.c
@@ -57,7 +57,9 @@
#include "storage/ipc.h"
#include "utils/guc.h"
#include "utils/resowner.h"
-
+#ifdef PGXC
+#include "pgxc/pgxc.h"
+#endif
/*
* We must leave some file descriptors free for system(), the dynamic loader,
@@ -985,8 +987,14 @@ OpenTemporaryFileInTablespace(Oid tblspcOid, bool rejectError)
else
{
/* All other tablespaces are accessed via symlinks */
+#ifdef PGXC
+ /* Postgres-XC tablespaces include node name in path */
+ snprintf(tempdirpath, sizeof(tempdirpath), "pg_tblspc/%u/%s_%s/%s",
+ tblspcOid, TABLESPACE_VERSION_DIRECTORY, PGXCNodeName, PG_TEMP_FILES_DIR);
+#else
snprintf(tempdirpath, sizeof(tempdirpath), "pg_tblspc/%u/%s/%s",
tblspcOid, TABLESPACE_VERSION_DIRECTORY, PG_TEMP_FILES_DIR);
+#endif
}
/*
@@ -1934,12 +1942,24 @@ RemovePgTempFiles(void)
strcmp(spc_de->d_name, "..") == 0)
continue;
+#ifdef PGXC
+ /* Postgres-XC tablespaces include node name in path */
+ snprintf(temp_path, sizeof(temp_path), "pg_tblspc/%s/%s_%s/%s",
+ spc_de->d_name, TABLESPACE_VERSION_DIRECTORY, PGXCNodeName, PG_TEMP_FILES_DIR);
+#else
snprintf(temp_path, sizeof(temp_path), "pg_tblspc/%s/%s/%s",
- spc_de->d_name, TABLESPACE_VERSION_DIRECTORY, PG_TEMP_FILES_DIR);
+ spc_de->d_name, TABLESPACE_VERSION_DIRECTORY, PG_TEMP_FILES_DIR);
+#endif
RemovePgTempFilesInDir(temp_path);
+#ifdef PGXC
+ /* Postgres-XC tablespaces include node name in path */
+ snprintf(temp_path, sizeof(temp_path), "pg_tblspc/%s/%s_%s",
+ spc_de->d_name, TABLESPACE_VERSION_DIRECTORY, PGXCNodeName);
+#else
snprintf(temp_path, sizeof(temp_path), "pg_tblspc/%s/%s",
spc_de->d_name, TABLESPACE_VERSION_DIRECTORY);
+#endif
RemovePgTempRelationFiles(temp_path);
}
diff --git a/src/backend/storage/file/reinit.c b/src/backend/storage/file/reinit.c
index 837ab90c8d..9c59fd648b 100644
--- a/src/backend/storage/file/reinit.c
+++ b/src/backend/storage/file/reinit.c
@@ -22,6 +22,9 @@
#include "storage/reinit.h"
#include "utils/hsearch.h"
#include "utils/memutils.h"
+#ifdef PGXC
+#include "pgxc/pgxc.h"
+#endif
static void ResetUnloggedRelationsInTablespaceDir(const char *tsdirname,
int op);
@@ -86,8 +89,14 @@ ResetUnloggedRelations(int op)
strcmp(spc_de->d_name, "..") == 0)
continue;
+#ifdef PGXC
+ /* Postgres-XC tablespaces include the node name in path */
+ snprintf(temp_path, sizeof(temp_path), "pg_tblspc/%s/%s_%s",
+ spc_de->d_name, TABLESPACE_VERSION_DIRECTORY, PGXCNodeName);
+#else
snprintf(temp_path, sizeof(temp_path), "pg_tblspc/%s/%s",
spc_de->d_name, TABLESPACE_VERSION_DIRECTORY);
+#endif
ResetUnloggedRelationsInTablespaceDir(temp_path, op);
}
diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c
index 166f6c4757..d11ee82360 100644
--- a/src/backend/tcop/utility.c
+++ b/src/backend/tcop/utility.c
@@ -767,23 +767,29 @@ standard_ProcessUtility(Node *parsetree,
break;
case T_CreateTableSpaceStmt:
-#ifdef PGXC
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("Postgres-XC does not support TABLESPACE yet"),
- errdetail("The feature is not currently supported")));
-#endif
PreventTransactionChain(isTopLevel, "CREATE TABLESPACE");
CreateTableSpace((CreateTableSpaceStmt *) parsetree);
+#ifdef PGXC
+ if (IS_PGXC_COORDINATOR)
+ ExecUtilityStmtOnNodes(queryString, NULL, true, EXEC_ON_ALL_NODES, false);
+#endif
break;
case T_DropTableSpaceStmt:
PreventTransactionChain(isTopLevel, "DROP TABLESPACE");
DropTableSpace((DropTableSpaceStmt *) parsetree);
+#ifdef PGXC
+ if (IS_PGXC_COORDINATOR)
+ ExecUtilityStmtOnNodes(queryString, NULL, true, EXEC_ON_ALL_NODES, false);
+#endif
break;
case T_AlterTableSpaceOptionsStmt:
AlterTableSpaceOptions((AlterTableSpaceOptionsStmt *) parsetree);
+#ifdef PGXC
+ if (IS_PGXC_COORDINATOR)
+ ExecUtilityStmtOnNodes(queryString, NULL, true, EXEC_ON_ALL_NODES, false);
+#endif
break;
case T_CreateExtensionStmt:
diff --git a/src/backend/utils/adt/dbsize.c b/src/backend/utils/adt/dbsize.c
index 44ec1dea8b..f17f3f040d 100644
--- a/src/backend/utils/adt/dbsize.c
+++ b/src/backend/utils/adt/dbsize.c
@@ -136,8 +136,14 @@ calculate_database_size(Oid dbOid)
strcmp(direntry->d_name, "..") == 0)
continue;
+#ifdef PGXC
+ /* Postgres-XC tablespaces include node name in path */
+ snprintf(pathname, MAXPGPATH, "pg_tblspc/%s/%s_%s/%u",
+ direntry->d_name, TABLESPACE_VERSION_DIRECTORY, PGXCNodeName, dbOid);
+#else
snprintf(pathname, MAXPGPATH, "pg_tblspc/%s/%s/%u",
direntry->d_name, TABLESPACE_VERSION_DIRECTORY, dbOid);
+#endif
totalsize += db_dir_size(pathname);
}
@@ -211,8 +217,14 @@ calculate_tablespace_size(Oid tblspcOid)
else if (tblspcOid == GLOBALTABLESPACE_OID)
snprintf(tblspcPath, MAXPGPATH, "global");
else
+#ifdef PGXC
+ /* Postgres-XC tablespaces include node name in path */
+ snprintf(tblspcPath, MAXPGPATH, "pg_tblspc/%u/%s_%s", tblspcOid,
+ TABLESPACE_VERSION_DIRECTORY, PGXCNodeName);
+#else
snprintf(tblspcPath, MAXPGPATH, "pg_tblspc/%u/%s", tblspcOid,
TABLESPACE_VERSION_DIRECTORY);
+#endif
dirdesc = AllocateDir(tblspcPath);
diff --git a/src/backend/utils/adt/misc.c b/src/backend/utils/adt/misc.c
index 5bda4af50f..5cb83b4007 100644
--- a/src/backend/utils/adt/misc.c
+++ b/src/backend/utils/adt/misc.c
@@ -33,6 +33,9 @@
#include "storage/procarray.h"
#include "utils/builtins.h"
#include "tcop/tcopprot.h"
+#ifdef PGXC
+#include "pgxc/pgxc.h"
+#endif
#define atooid(x) ((Oid) strtoul((x), NULL, 10))
@@ -186,8 +189,15 @@ pg_tablespace_databases(PG_FUNCTION_ARGS)
/*
* size = tablespace dirname length + dir sep char + oid + terminator
*/
+#ifdef PGXC
+ /* Postgres-XC tablespaces also include node name in path */
+ fctx->location = (char *) palloc(9 + 1 + OIDCHARS + 1 +
+ strlen(PGXCNodeName) + 1 +
+ strlen(TABLESPACE_VERSION_DIRECTORY) + 1);
+#else
fctx->location = (char *) palloc(9 + 1 + OIDCHARS + 1 +
strlen(TABLESPACE_VERSION_DIRECTORY) + 1);
+#endif
if (tablespaceOid == GLOBALTABLESPACE_OID)
{
fctx->dirdesc = NULL;
@@ -199,8 +209,14 @@ pg_tablespace_databases(PG_FUNCTION_ARGS)
if (tablespaceOid == DEFAULTTABLESPACE_OID)
sprintf(fctx->location, "base");
else
+#ifdef PGXC
+ /* Postgres-XC tablespaces also include node name in path */
+ sprintf(fctx->location, "pg_tblspc/%u/%s_%s", tablespaceOid,
+ TABLESPACE_VERSION_DIRECTORY, PGXCNodeName);
+#else
sprintf(fctx->location, "pg_tblspc/%u/%s", tablespaceOid,
TABLESPACE_VERSION_DIRECTORY);
+#endif
fctx->dirdesc = AllocateDir(fctx->location);
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 9600be71d4..cdb40e3b75 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -4544,8 +4544,14 @@ RelationCacheInitFileRemove(void)
if (strspn(de->d_name, "0123456789") == strlen(de->d_name))
{
/* Scan the tablespace dir for per-database dirs */
+#ifdef PGXC
+ /* Postgres-XC tablespaces include node name in path */
+ snprintf(path, sizeof(path), "%s/%s/%s_%s",
+ tblspcdir, de->d_name, TABLESPACE_VERSION_DIRECTORY, PGXCNodeName);
+#else
snprintf(path, sizeof(path), "%s/%s/%s",
tblspcdir, de->d_name, TABLESPACE_VERSION_DIRECTORY);
+#endif
RelationCacheInitFileRemoveInDir(path);
}
}
diff --git a/src/include/pgxc/nodemgr.h b/src/include/pgxc/nodemgr.h
index 80ed4a59da..fc55c6fb06 100644
--- a/src/include/pgxc/nodemgr.h
+++ b/src/include/pgxc/nodemgr.h
@@ -19,6 +19,8 @@
#include "nodes/parsenodes.h"
+#define PGXC_NODENAME_LENGTH 64
+
/* Global number of nodes */
extern int NumDataNodes;
extern int NumCoords;
diff --git a/src/test/regress/output/tablespace_1.source b/src/test/regress/output/tablespace_1.source
deleted file mode 100644
index c7019d2ea2..0000000000
--- a/src/test/regress/output/tablespace_1.source
+++ /dev/null
@@ -1,92 +0,0 @@
--- create a tablespace we can use
-CREATE TABLESPACE testspace LOCATION '@testtablespace@';
-ERROR: Postgres-XC does not support TABLESPACE yet
-DETAIL: The feature is not currently supported
--- try setting and resetting some properties for the new tablespace
-ALTER TABLESPACE testspace SET (random_page_cost = 1.0);
-ERROR: tablespace "testspace" does not exist
-ALTER TABLESPACE testspace SET (some_nonexistent_parameter = true); -- fail
-ERROR: tablespace "testspace" does not exist
-ALTER TABLESPACE testspace RESET (random_page_cost = 2.0); -- fail
-ERROR: tablespace "testspace" does not exist
-ALTER TABLESPACE testspace RESET (random_page_cost, seq_page_cost); -- ok
-ERROR: tablespace "testspace" does not exist
--- create a schema we can use
-CREATE SCHEMA testschema;
--- try a table
-CREATE TABLE testschema.foo (i int) TABLESPACE testspace;
-ERROR: tablespace "testspace" does not exist
-SELECT relname, spcname FROM pg_catalog.pg_tablespace t, pg_catalog.pg_class c
- where c.reltablespace = t.oid AND c.relname = 'foo';
- relname | spcname
----------+---------
-(0 rows)
-
-INSERT INTO testschema.foo VALUES(1);
-ERROR: relation "testschema.foo" does not exist
-LINE 1: INSERT INTO testschema.foo VALUES(1);
- ^
-INSERT INTO testschema.foo VALUES(2);
-ERROR: relation "testschema.foo" does not exist
-LINE 1: INSERT INTO testschema.foo VALUES(2);
- ^
--- tables from dynamic sources
-CREATE TABLE testschema.asselect TABLESPACE testspace AS SELECT 1;
-ERROR: tablespace "testspace" does not exist
-SELECT relname, spcname FROM pg_catalog.pg_tablespace t, pg_catalog.pg_class c
- where c.reltablespace = t.oid AND c.relname = 'asselect';
- relname | spcname
----------+---------
-(0 rows)
-
-PREPARE selectsource(int) AS SELECT $1;
-CREATE TABLE testschema.asexecute TABLESPACE testspace
- AS EXECUTE selectsource(2);
-ERROR: tablespace "testspace" does not exist
-SELECT relname, spcname FROM pg_catalog.pg_tablespace t, pg_catalog.pg_class c
- where c.reltablespace = t.oid AND c.relname = 'asexecute';
- relname | spcname
----------+---------
-(0 rows)
-
--- index
-CREATE INDEX foo_idx on testschema.foo(i) TABLESPACE testspace;
-ERROR: relation "testschema.foo" does not exist
-SELECT relname, spcname FROM pg_catalog.pg_tablespace t, pg_catalog.pg_class c
- where c.reltablespace = t.oid AND c.relname = 'foo_idx';
- relname | spcname
----------+---------
-(0 rows)
-
--- let's try moving a table from one place to another
-CREATE TABLE testschema.atable AS VALUES (1), (2);
-CREATE UNIQUE INDEX anindex ON testschema.atable(column1);
-ALTER TABLE testschema.atable SET TABLESPACE testspace;
-ERROR: tablespace "testspace" does not exist
-ALTER INDEX testschema.anindex SET TABLESPACE testspace;
-ERROR: tablespace "testspace" does not exist
-INSERT INTO testschema.atable VALUES(3); -- ok
-INSERT INTO testschema.atable VALUES(1); -- fail (checks index)
-ERROR: duplicate key value violates unique constraint "anindex"
-DETAIL: Key (column1)=(1) already exists.
-SELECT COUNT(*) FROM testschema.atable; -- checks heap
- count
--------
- 3
-(1 row)
-
--- Will fail with bad path
-CREATE TABLESPACE badspace LOCATION '/no/such/location';
-ERROR: Postgres-XC does not support TABLESPACE yet
-DETAIL: The feature is not currently supported
--- No such tablespace
-CREATE TABLE bar (i int) TABLESPACE nosuchspace;
-ERROR: tablespace "nosuchspace" does not exist
--- Fail, not empty
-DROP TABLESPACE testspace;
-ERROR: tablespace "testspace" does not exist
-DROP SCHEMA testschema CASCADE;
-NOTICE: drop cascades to table testschema.atable
--- Should succeed
-DROP TABLESPACE testspace;
-ERROR: tablespace "testspace" does not exist