summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorStephen Frost <sfrost@snowman.net>2014-08-21 19:06:17 -0400
committerStephen Frost <sfrost@snowman.net>2014-08-21 19:12:00 -0400
commitd9b2bc45cf75f913490f1b3ce9b9263509b26704 (patch)
tree5245060be317d1a40da7398838b8e9bc5dd7751c /src
parent9243417801be3f1cfaa3a3c33d5a003f382bd7a4 (diff)
Rework 'MOVE ALL' to 'ALTER .. ALL IN TABLESPACE'
As 'ALTER TABLESPACE .. MOVE ALL' really didn't change the tablespace but instead changed objects inside tablespaces, it made sense to rework the syntax and supporting functions to operate under the 'ALTER (TABLE|INDEX|MATERIALIZED VIEW)' syntax and to be in tablecmds.c. Pointed out by Alvaro, who also suggested the new syntax. Back-patch to 9.4.
Diffstat (limited to 'src')
-rw-r--r--src/backend/commands/tablecmds.c171
-rw-r--r--src/backend/commands/tablespace.c179
-rw-r--r--src/backend/nodes/copyfuncs.c11
-rw-r--r--src/backend/nodes/equalfuncs.c9
-rw-r--r--src/backend/parser/gram.y165
-rw-r--r--src/backend/tcop/utility.c20
-rw-r--r--src/include/commands/tablecmds.h2
-rw-r--r--src/include/commands/tablespace.h1
-rw-r--r--src/include/nodes/nodes.h2
-rw-r--r--src/include/nodes/parsenodes.h7
-rw-r--r--src/test/regress/input/tablespace.source5
-rw-r--r--src/test/regress/output/tablespace.source5
-rw-r--r--src/tools/pgindent/typedefs.list2
13 files changed, 269 insertions, 310 deletions
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 89bd31ab93e..34c38de3fff 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -51,6 +51,7 @@
#include "commands/tablespace.h"
#include "commands/trigger.h"
#include "commands/typecmds.h"
+#include "commands/user.h"
#include "executor/executor.h"
#include "foreign/foreign.h"
#include "miscadmin.h"
@@ -9205,6 +9206,176 @@ ATExecSetTableSpace(Oid tableOid, Oid newTableSpace, LOCKMODE lockmode)
}
/*
+ * Alter Table ALL ... SET TABLESPACE
+ *
+ * Allows a user to move all objects of some type in a given tablespace in the
+ * current database to another tablespace. Objects can be chosen based on the
+ * owner of the object also, to allow users to move only their objects.
+ * The user must have CREATE rights on the new tablespace, as usual. The main
+ * permissions handling is done by the lower-level table move function.
+ *
+ * All to-be-moved objects are locked first. If NOWAIT is specified and the
+ * lock can't be acquired then we ereport(ERROR).
+ */
+Oid
+AlterTableMoveAll(AlterTableMoveAllStmt *stmt)
+{
+ List *relations = NIL;
+ ListCell *l;
+ ScanKeyData key[1];
+ Relation rel;
+ HeapScanDesc scan;
+ HeapTuple tuple;
+ Oid orig_tablespaceoid;
+ Oid new_tablespaceoid;
+ List *role_oids = roleNamesToIds(stmt->roles);
+
+ /* Ensure we were not asked to move something we can't */
+ if (stmt->objtype != OBJECT_TABLE && stmt->objtype != OBJECT_INDEX &&
+ stmt->objtype != OBJECT_MATVIEW)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("only tables, indexes, and materialized views exist in tablespaces")));
+
+ /* Get the orig and new tablespace OIDs */
+ orig_tablespaceoid = get_tablespace_oid(stmt->orig_tablespacename, false);
+ new_tablespaceoid = get_tablespace_oid(stmt->new_tablespacename, false);
+
+ /* Can't move shared relations in to or out of pg_global */
+ /* This is also checked by ATExecSetTableSpace, but nice to stop earlier */
+ if (orig_tablespaceoid == GLOBALTABLESPACE_OID ||
+ new_tablespaceoid == GLOBALTABLESPACE_OID)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("cannot move relations in to or out of pg_global tablespace")));
+
+ /*
+ * Must have CREATE rights on the new tablespace, unless it is the
+ * database default tablespace (which all users implicitly have CREATE
+ * rights on).
+ */
+ if (OidIsValid(new_tablespaceoid) && new_tablespaceoid != MyDatabaseTableSpace)
+ {
+ AclResult aclresult;
+
+ aclresult = pg_tablespace_aclcheck(new_tablespaceoid, GetUserId(),
+ ACL_CREATE);
+ if (aclresult != ACLCHECK_OK)
+ aclcheck_error(aclresult, ACL_KIND_TABLESPACE,
+ get_tablespace_name(new_tablespaceoid));
+ }
+
+ /*
+ * Now that the checks are done, check if we should set either to
+ * InvalidOid because it is our database's default tablespace.
+ */
+ if (orig_tablespaceoid == MyDatabaseTableSpace)
+ orig_tablespaceoid = InvalidOid;
+
+ if (new_tablespaceoid == MyDatabaseTableSpace)
+ new_tablespaceoid = InvalidOid;
+
+ /* no-op */
+ if (orig_tablespaceoid == new_tablespaceoid)
+ return new_tablespaceoid;
+
+ /*
+ * Walk the list of objects in the tablespace and move them. This will
+ * only find objects in our database, of course.
+ */
+ ScanKeyInit(&key[0],
+ Anum_pg_class_reltablespace,
+ BTEqualStrategyNumber, F_OIDEQ,
+ ObjectIdGetDatum(orig_tablespaceoid));
+
+ rel = heap_open(RelationRelationId, AccessShareLock);
+ scan = heap_beginscan_catalog(rel, 1, key);
+ while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
+ {
+ Oid relOid = HeapTupleGetOid(tuple);
+ Form_pg_class relForm;
+
+ relForm = (Form_pg_class) GETSTRUCT(tuple);
+
+ /*
+ * Do not move objects in pg_catalog as part of this, if an admin
+ * really wishes to do so, they can issue the individual ALTER
+ * commands directly.
+ *
+ * Also, explicitly avoid any shared tables, temp tables, or TOAST
+ * (TOAST will be moved with the main table).
+ */
+ if (IsSystemNamespace(relForm->relnamespace) || relForm->relisshared ||
+ isAnyTempNamespace(relForm->relnamespace) ||
+ relForm->relnamespace == PG_TOAST_NAMESPACE)
+ continue;
+
+ /* Only move the object type requested */
+ if ((stmt->objtype == OBJECT_TABLE &&
+ relForm->relkind != RELKIND_RELATION) ||
+ (stmt->objtype == OBJECT_INDEX &&
+ relForm->relkind != RELKIND_INDEX) ||
+ (stmt->objtype == OBJECT_MATVIEW &&
+ relForm->relkind != RELKIND_MATVIEW))
+ continue;
+
+ /* Check if we are only moving objects owned by certain roles */
+ if (role_oids != NIL && !list_member_oid(role_oids, relForm->relowner))
+ continue;
+
+ /*
+ * Handle permissions-checking here since we are locking the tables
+ * and also to avoid doing a bunch of work only to fail part-way. Note
+ * that permissions will also be checked by AlterTableInternal().
+ *
+ * Caller must be considered an owner on the table to move it.
+ */
+ if (!pg_class_ownercheck(relOid, GetUserId()))
+ aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
+ NameStr(relForm->relname));
+
+ if (stmt->nowait &&
+ !ConditionalLockRelationOid(relOid, AccessExclusiveLock))
+ ereport(ERROR,
+ (errcode(ERRCODE_OBJECT_IN_USE),
+ errmsg("aborting due to \"%s\".\"%s\" --- lock not available",
+ get_namespace_name(relForm->relnamespace),
+ NameStr(relForm->relname))));
+ else
+ LockRelationOid(relOid, AccessExclusiveLock);
+
+ /* Add to our list of objects to move */
+ relations = lappend_oid(relations, relOid);
+ }
+
+ heap_endscan(scan);
+ heap_close(rel, AccessShareLock);
+
+ if (relations == NIL)
+ ereport(NOTICE,
+ (errcode(ERRCODE_NO_DATA_FOUND),
+ errmsg("no matching relations in tablespace \"%s\" found",
+ orig_tablespaceoid == InvalidOid ? "(database default)" :
+ get_tablespace_name(orig_tablespaceoid))));
+
+ /* Everything is locked, loop through and move all of the relations. */
+ foreach(l, relations)
+ {
+ List *cmds = NIL;
+ AlterTableCmd *cmd = makeNode(AlterTableCmd);
+
+ cmd->subtype = AT_SetTableSpace;
+ cmd->name = stmt->new_tablespacename;
+
+ cmds = lappend(cmds, cmd);
+
+ AlterTableInternal(lfirst_oid(l), cmds, false);
+ }
+
+ return new_tablespaceoid;
+}
+
+/*
* Copy data, block by block
*/
static void
diff --git a/src/backend/commands/tablespace.c b/src/backend/commands/tablespace.c
index 031be37a1e7..28e69a55510 100644
--- a/src/backend/commands/tablespace.c
+++ b/src/backend/commands/tablespace.c
@@ -67,7 +67,6 @@
#include "commands/seclabel.h"
#include "commands/tablecmds.h"
#include "commands/tablespace.h"
-#include "commands/user.h"
#include "miscadmin.h"
#include "postmaster/bgwriter.h"
#include "storage/fd.h"
@@ -992,184 +991,6 @@ AlterTableSpaceOptions(AlterTableSpaceOptionsStmt *stmt)
}
/*
- * Alter table space move
- *
- * Allows a user to move all of their objects in a given tablespace in the
- * current database to another tablespace. Only objects which the user is
- * considered to be an owner of are moved and the user must have CREATE rights
- * on the new tablespace. These checks should mean that ALTER TABLE will never
- * fail due to permissions, but note that permissions will also be checked at
- * that level. Objects can be ALL, TABLES, INDEXES, or MATERIALIZED VIEWS.
- *
- * All to-be-moved objects are locked first. If NOWAIT is specified and the
- * lock can't be acquired then we ereport(ERROR).
- */
-Oid
-AlterTableSpaceMove(AlterTableSpaceMoveStmt *stmt)
-{
- List *relations = NIL;
- ListCell *l;
- ScanKeyData key[1];
- Relation rel;
- HeapScanDesc scan;
- HeapTuple tuple;
- Oid orig_tablespaceoid;
- Oid new_tablespaceoid;
- List *role_oids = roleNamesToIds(stmt->roles);
-
- /* Ensure we were not asked to move something we can't */
- if (!stmt->move_all && stmt->objtype != OBJECT_TABLE &&
- stmt->objtype != OBJECT_INDEX && stmt->objtype != OBJECT_MATVIEW)
- ereport(ERROR,
- (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
- errmsg("only tables, indexes, and materialized views exist in tablespaces")));
-
- /* Get the orig and new tablespace OIDs */
- orig_tablespaceoid = get_tablespace_oid(stmt->orig_tablespacename, false);
- new_tablespaceoid = get_tablespace_oid(stmt->new_tablespacename, false);
-
- /* Can't move shared relations in to or out of pg_global */
- /* This is also checked by ATExecSetTableSpace, but nice to stop earlier */
- if (orig_tablespaceoid == GLOBALTABLESPACE_OID ||
- new_tablespaceoid == GLOBALTABLESPACE_OID)
- ereport(ERROR,
- (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
- errmsg("cannot move relations in to or out of pg_global tablespace")));
-
- /*
- * Must have CREATE rights on the new tablespace, unless it is the
- * database default tablespace (which all users implicitly have CREATE
- * rights on).
- */
- if (OidIsValid(new_tablespaceoid) && new_tablespaceoid != MyDatabaseTableSpace)
- {
- AclResult aclresult;
-
- aclresult = pg_tablespace_aclcheck(new_tablespaceoid, GetUserId(),
- ACL_CREATE);
- if (aclresult != ACLCHECK_OK)
- aclcheck_error(aclresult, ACL_KIND_TABLESPACE,
- get_tablespace_name(new_tablespaceoid));
- }
-
- /*
- * Now that the checks are done, check if we should set either to
- * InvalidOid because it is our database's default tablespace.
- */
- if (orig_tablespaceoid == MyDatabaseTableSpace)
- orig_tablespaceoid = InvalidOid;
-
- if (new_tablespaceoid == MyDatabaseTableSpace)
- new_tablespaceoid = InvalidOid;
-
- /* no-op */
- if (orig_tablespaceoid == new_tablespaceoid)
- return new_tablespaceoid;
-
- /*
- * Walk the list of objects in the tablespace and move them. This will
- * only find objects in our database, of course.
- */
- ScanKeyInit(&key[0],
- Anum_pg_class_reltablespace,
- BTEqualStrategyNumber, F_OIDEQ,
- ObjectIdGetDatum(orig_tablespaceoid));
-
- rel = heap_open(RelationRelationId, AccessShareLock);
- scan = heap_beginscan_catalog(rel, 1, key);
- while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
- {
- Oid relOid = HeapTupleGetOid(tuple);
- Form_pg_class relForm;
-
- relForm = (Form_pg_class) GETSTRUCT(tuple);
-
- /*
- * Do not move objects in pg_catalog as part of this, if an admin
- * really wishes to do so, they can issue the individual ALTER
- * commands directly.
- *
- * Also, explicitly avoid any shared tables, temp tables, or TOAST
- * (TOAST will be moved with the main table).
- */
- if (IsSystemNamespace(relForm->relnamespace) || relForm->relisshared ||
- isAnyTempNamespace(relForm->relnamespace) ||
- relForm->relnamespace == PG_TOAST_NAMESPACE)
- continue;
-
- /* Only consider objects which live in tablespaces */
- if (relForm->relkind != RELKIND_RELATION &&
- relForm->relkind != RELKIND_INDEX &&
- relForm->relkind != RELKIND_MATVIEW)
- continue;
-
- /* Check if we were asked to only move a certain type of object */
- if (!stmt->move_all &&
- ((stmt->objtype == OBJECT_TABLE &&
- relForm->relkind != RELKIND_RELATION) ||
- (stmt->objtype == OBJECT_INDEX &&
- relForm->relkind != RELKIND_INDEX) ||
- (stmt->objtype == OBJECT_MATVIEW &&
- relForm->relkind != RELKIND_MATVIEW)))
- continue;
-
- /* Check if we are only moving objects owned by certain roles */
- if (role_oids != NIL && !list_member_oid(role_oids, relForm->relowner))
- continue;
-
- /*
- * Handle permissions-checking here since we are locking the tables
- * and also to avoid doing a bunch of work only to fail part-way. Note
- * that permissions will also be checked by AlterTableInternal().
- *
- * Caller must be considered an owner on the table to move it.
- */
- if (!pg_class_ownercheck(relOid, GetUserId()))
- aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
- NameStr(relForm->relname));
-
- if (stmt->nowait &&
- !ConditionalLockRelationOid(relOid, AccessExclusiveLock))
- ereport(ERROR,
- (errcode(ERRCODE_OBJECT_IN_USE),
- errmsg("aborting due to \"%s\".\"%s\" --- lock not available",
- get_namespace_name(relForm->relnamespace),
- NameStr(relForm->relname))));
- else
- LockRelationOid(relOid, AccessExclusiveLock);
-
- /* Add to our list of objects to move */
- relations = lappend_oid(relations, relOid);
- }
-
- heap_endscan(scan);
- heap_close(rel, AccessShareLock);
-
- if (relations == NIL)
- ereport(NOTICE,
- (errcode(ERRCODE_NO_DATA_FOUND),
- errmsg("no matching relations in tablespace \"%s\" found",
- orig_tablespaceoid == InvalidOid ? "(database default)" :
- get_tablespace_name(orig_tablespaceoid))));
-
- /* Everything is locked, loop through and move all of the relations. */
- foreach(l, relations)
- {
- List *cmds = NIL;
- AlterTableCmd *cmd = makeNode(AlterTableCmd);
-
- cmd->subtype = AT_SetTableSpace;
- cmd->name = stmt->new_tablespacename;
-
- cmds = lappend(cmds, cmd);
-
- AlterTableInternal(lfirst_oid(l), cmds, false);
- }
-
- return new_tablespaceoid;
-}
-
-/*
* Routines for handling the GUC variable 'default_tablespace'.
*/
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index 43530aa24a8..221d0fee6bb 100644
--- a/src/backend/nodes/copyfuncs.c
+++ b/src/backend/nodes/copyfuncs.c
@@ -3402,14 +3402,13 @@ _copyAlterTableSpaceOptionsStmt(const AlterTableSpaceOptionsStmt *from)
return newnode;
}
-static AlterTableSpaceMoveStmt *
-_copyAlterTableSpaceMoveStmt(const AlterTableSpaceMoveStmt *from)
+static AlterTableMoveAllStmt *
+_copyAlterTableMoveAllStmt(const AlterTableMoveAllStmt *from)
{
- AlterTableSpaceMoveStmt *newnode = makeNode(AlterTableSpaceMoveStmt);
+ AlterTableMoveAllStmt *newnode = makeNode(AlterTableMoveAllStmt);
COPY_STRING_FIELD(orig_tablespacename);
COPY_SCALAR_FIELD(objtype);
- COPY_SCALAR_FIELD(move_all);
COPY_NODE_FIELD(roles);
COPY_STRING_FIELD(new_tablespacename);
COPY_SCALAR_FIELD(nowait);
@@ -4428,8 +4427,8 @@ copyObject(const void *from)
case T_AlterTableSpaceOptionsStmt:
retval = _copyAlterTableSpaceOptionsStmt(from);
break;
- case T_AlterTableSpaceMoveStmt:
- retval = _copyAlterTableSpaceMoveStmt(from);
+ case T_AlterTableMoveAllStmt:
+ retval = _copyAlterTableMoveAllStmt(from);
break;
case T_CreateExtensionStmt:
retval = _copyCreateExtensionStmt(from);
diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c
index 2407cb73a38..7e53681e706 100644
--- a/src/backend/nodes/equalfuncs.c
+++ b/src/backend/nodes/equalfuncs.c
@@ -1638,12 +1638,11 @@ _equalAlterTableSpaceOptionsStmt(const AlterTableSpaceOptionsStmt *a,
}
static bool
-_equalAlterTableSpaceMoveStmt(const AlterTableSpaceMoveStmt *a,
- const AlterTableSpaceMoveStmt *b)
+_equalAlterTableMoveAllStmt(const AlterTableMoveAllStmt *a,
+ const AlterTableMoveAllStmt *b)
{
COMPARE_STRING_FIELD(orig_tablespacename);
COMPARE_SCALAR_FIELD(objtype);
- COMPARE_SCALAR_FIELD(move_all);
COMPARE_NODE_FIELD(roles);
COMPARE_STRING_FIELD(new_tablespacename);
COMPARE_SCALAR_FIELD(nowait);
@@ -2896,8 +2895,8 @@ equal(const void *a, const void *b)
case T_AlterTableSpaceOptionsStmt:
retval = _equalAlterTableSpaceOptionsStmt(a, b);
break;
- case T_AlterTableSpaceMoveStmt:
- retval = _equalAlterTableSpaceMoveStmt(a, b);
+ case T_AlterTableMoveAllStmt:
+ retval = _equalAlterTableMoveAllStmt(a, b);
break;
case T_CreateExtensionStmt:
retval = _equalCreateExtensionStmt(a, b);
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 7b9895d61ec..2e9bbe232f9 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -1748,6 +1748,28 @@ AlterTableStmt:
n->missing_ok = true;
$$ = (Node *)n;
}
+ | ALTER TABLE ALL IN_P TABLESPACE name SET TABLESPACE name opt_nowait
+ {
+ AlterTableMoveAllStmt *n =
+ makeNode(AlterTableMoveAllStmt);
+ n->orig_tablespacename = $6;
+ n->objtype = OBJECT_TABLE;
+ n->roles = NIL;
+ n->new_tablespacename = $9;
+ n->nowait = $10;
+ $$ = (Node *)n;
+ }
+ | ALTER TABLE ALL IN_P TABLESPACE name OWNED BY role_list SET TABLESPACE name opt_nowait
+ {
+ AlterTableMoveAllStmt *n =
+ makeNode(AlterTableMoveAllStmt);
+ n->orig_tablespacename = $6;
+ n->objtype = OBJECT_TABLE;
+ n->roles = $9;
+ n->new_tablespacename = $12;
+ n->nowait = $13;
+ $$ = (Node *)n;
+ }
| ALTER INDEX qualified_name alter_table_cmds
{
AlterTableStmt *n = makeNode(AlterTableStmt);
@@ -1766,6 +1788,28 @@ AlterTableStmt:
n->missing_ok = true;
$$ = (Node *)n;
}
+ | ALTER INDEX ALL IN_P TABLESPACE name SET TABLESPACE name opt_nowait
+ {
+ AlterTableMoveAllStmt *n =
+ makeNode(AlterTableMoveAllStmt);
+ n->orig_tablespacename = $6;
+ n->objtype = OBJECT_INDEX;
+ n->roles = NIL;
+ n->new_tablespacename = $9;
+ n->nowait = $10;
+ $$ = (Node *)n;
+ }
+ | ALTER INDEX ALL IN_P TABLESPACE name OWNED BY role_list SET TABLESPACE name opt_nowait
+ {
+ AlterTableMoveAllStmt *n =
+ makeNode(AlterTableMoveAllStmt);
+ n->orig_tablespacename = $6;
+ n->objtype = OBJECT_INDEX;
+ n->roles = $9;
+ n->new_tablespacename = $12;
+ n->nowait = $13;
+ $$ = (Node *)n;
+ }
| ALTER SEQUENCE qualified_name alter_table_cmds
{
AlterTableStmt *n = makeNode(AlterTableStmt);
@@ -1820,6 +1864,28 @@ AlterTableStmt:
n->missing_ok = true;
$$ = (Node *)n;
}
+ | ALTER MATERIALIZED VIEW ALL IN_P TABLESPACE name SET TABLESPACE name opt_nowait
+ {
+ AlterTableMoveAllStmt *n =
+ makeNode(AlterTableMoveAllStmt);
+ n->orig_tablespacename = $7;
+ n->objtype = OBJECT_MATVIEW;
+ n->roles = NIL;
+ n->new_tablespacename = $10;
+ n->nowait = $11;
+ $$ = (Node *)n;
+ }
+ | ALTER MATERIALIZED VIEW ALL IN_P TABLESPACE name OWNED BY role_list SET TABLESPACE name opt_nowait
+ {
+ AlterTableMoveAllStmt *n =
+ makeNode(AlterTableMoveAllStmt);
+ n->orig_tablespacename = $7;
+ n->objtype = OBJECT_MATVIEW;
+ n->roles = $10;
+ n->new_tablespacename = $13;
+ n->nowait = $14;
+ $$ = (Node *)n;
+ }
;
alter_table_cmds:
@@ -6941,103 +7007,8 @@ opt_force: FORCE { $$ = TRUE; }
*
*****************************************************************************/
-AlterTblSpcStmt: ALTER TABLESPACE name MOVE ALL TO name opt_nowait
- {
- AlterTableSpaceMoveStmt *n =
- makeNode(AlterTableSpaceMoveStmt);
- n->orig_tablespacename = $3;
- n->objtype = -1;
- n->move_all = true;
- n->roles = NIL;
- n->new_tablespacename = $7;
- n->nowait = $8;
- $$ = (Node *)n;
- }
- | ALTER TABLESPACE name MOVE TABLES TO name opt_nowait
- {
- AlterTableSpaceMoveStmt *n =
- makeNode(AlterTableSpaceMoveStmt);
- n->orig_tablespacename = $3;
- n->objtype = OBJECT_TABLE;
- n->move_all = false;
- n->roles = NIL;
- n->new_tablespacename = $7;
- n->nowait = $8;
- $$ = (Node *)n;
- }
- | ALTER TABLESPACE name MOVE INDEXES TO name opt_nowait
- {
- AlterTableSpaceMoveStmt *n =
- makeNode(AlterTableSpaceMoveStmt);
- n->orig_tablespacename = $3;
- n->objtype = OBJECT_INDEX;
- n->move_all = false;
- n->roles = NIL;
- n->new_tablespacename = $7;
- n->nowait = $8;
- $$ = (Node *)n;
- }
- | ALTER TABLESPACE name MOVE MATERIALIZED VIEWS TO name opt_nowait
- {
- AlterTableSpaceMoveStmt *n =
- makeNode(AlterTableSpaceMoveStmt);
- n->orig_tablespacename = $3;
- n->objtype = OBJECT_MATVIEW;
- n->move_all = false;
- n->roles = NIL;
- n->new_tablespacename = $8;
- n->nowait = $9;
- $$ = (Node *)n;
- }
- | ALTER TABLESPACE name MOVE ALL OWNED BY role_list TO name opt_nowait
- {
- AlterTableSpaceMoveStmt *n =
- makeNode(AlterTableSpaceMoveStmt);
- n->orig_tablespacename = $3;
- n->objtype = -1;
- n->move_all = true;
- n->roles = $8;
- n->new_tablespacename = $10;
- n->nowait = $11;
- $$ = (Node *)n;
- }
- | ALTER TABLESPACE name MOVE TABLES OWNED BY role_list TO name opt_nowait
- {
- AlterTableSpaceMoveStmt *n =
- makeNode(AlterTableSpaceMoveStmt);
- n->orig_tablespacename = $3;
- n->objtype = OBJECT_TABLE;
- n->move_all = false;
- n->roles = $8;
- n->new_tablespacename = $10;
- n->nowait = $11;
- $$ = (Node *)n;
- }
- | ALTER TABLESPACE name MOVE INDEXES OWNED BY role_list TO name opt_nowait
- {
- AlterTableSpaceMoveStmt *n =
- makeNode(AlterTableSpaceMoveStmt);
- n->orig_tablespacename = $3;
- n->objtype = OBJECT_INDEX;
- n->move_all = false;
- n->roles = $8;
- n->new_tablespacename = $10;
- n->nowait = $11;
- $$ = (Node *)n;
- }
- | ALTER TABLESPACE name MOVE MATERIALIZED VIEWS OWNED BY role_list TO name opt_nowait
- {
- AlterTableSpaceMoveStmt *n =
- makeNode(AlterTableSpaceMoveStmt);
- n->orig_tablespacename = $3;
- n->objtype = OBJECT_MATVIEW;
- n->move_all = false;
- n->roles = $9;
- n->new_tablespacename = $11;
- n->nowait = $12;
- $$ = (Node *)n;
- }
- | ALTER TABLESPACE name SET reloptions
+AlterTblSpcStmt:
+ ALTER TABLESPACE name SET reloptions
{
AlterTableSpaceOptionsStmt *n =
makeNode(AlterTableSpaceOptionsStmt);
diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c
index 3423898c112..0558ea34b05 100644
--- a/src/backend/tcop/utility.c
+++ b/src/backend/tcop/utility.c
@@ -147,6 +147,7 @@ check_xact_readonly(Node *parsetree)
case T_AlterObjectSchemaStmt:
case T_AlterOwnerStmt:
case T_AlterSeqStmt:
+ case T_AlterTableMoveAllStmt:
case T_AlterTableStmt:
case T_RenameStmt:
case T_CommentStmt:
@@ -200,7 +201,6 @@ check_xact_readonly(Node *parsetree)
case T_AlterUserMappingStmt:
case T_DropUserMappingStmt:
case T_AlterTableSpaceOptionsStmt:
- case T_AlterTableSpaceMoveStmt:
case T_CreateForeignTableStmt:
case T_SecLabelStmt:
PreventCommandIfReadOnly(CreateCommandTag(parsetree));
@@ -506,9 +506,8 @@ standard_ProcessUtility(Node *parsetree,
AlterTableSpaceOptions((AlterTableSpaceOptionsStmt *) parsetree);
break;
- case T_AlterTableSpaceMoveStmt:
- /* no event triggers for global objects */
- AlterTableSpaceMove((AlterTableSpaceMoveStmt *) parsetree);
+ case T_AlterTableMoveAllStmt:
+ AlterTableMoveAll((AlterTableMoveAllStmt *) parsetree);
break;
case T_TruncateStmt:
@@ -1805,10 +1804,6 @@ CreateCommandTag(Node *parsetree)
tag = "ALTER TABLESPACE";
break;
- case T_AlterTableSpaceMoveStmt:
- tag = "ALTER TABLESPACE";
- break;
-
case T_CreateExtensionStmt:
tag = "CREATE EXTENSION";
break;
@@ -1973,6 +1968,10 @@ CreateCommandTag(Node *parsetree)
tag = AlterObjectTypeCommandTag(((AlterOwnerStmt *) parsetree)->objectType);
break;
+ case T_AlterTableMoveAllStmt:
+ tag = AlterObjectTypeCommandTag(((AlterTableMoveAllStmt *) parsetree)->objtype);
+ break;
+
case T_AlterTableStmt:
tag = AlterObjectTypeCommandTag(((AlterTableStmt *) parsetree)->relkind);
break;
@@ -2501,10 +2500,6 @@ GetCommandLogLevel(Node *parsetree)
lev = LOGSTMT_DDL;
break;
- case T_AlterTableSpaceMoveStmt:
- lev = LOGSTMT_DDL;
- break;
-
case T_CreateExtensionStmt:
case T_AlterExtensionStmt:
case T_AlterExtensionContentsStmt:
@@ -2583,6 +2578,7 @@ GetCommandLogLevel(Node *parsetree)
lev = LOGSTMT_DDL;
break;
+ case T_AlterTableMoveAllStmt:
case T_AlterTableStmt:
lev = LOGSTMT_DDL;
break;
diff --git a/src/include/commands/tablecmds.h b/src/include/commands/tablecmds.h
index e55f45ab26f..932322f144c 100644
--- a/src/include/commands/tablecmds.h
+++ b/src/include/commands/tablecmds.h
@@ -35,6 +35,8 @@ extern void ATExecChangeOwner(Oid relationOid, Oid newOwnerId, bool recursing, L
extern void AlterTableInternal(Oid relid, List *cmds, bool recurse);
+extern Oid AlterTableMoveAll(AlterTableMoveAllStmt *stmt);
+
extern Oid AlterTableNamespace(AlterObjectSchemaStmt *stmt);
extern void AlterTableNamespaceInternal(Relation rel, Oid oldNspOid,
diff --git a/src/include/commands/tablespace.h b/src/include/commands/tablespace.h
index 1603f677a7d..c7af55917d7 100644
--- a/src/include/commands/tablespace.h
+++ b/src/include/commands/tablespace.h
@@ -43,7 +43,6 @@ extern Oid CreateTableSpace(CreateTableSpaceStmt *stmt);
extern void DropTableSpace(DropTableSpaceStmt *stmt);
extern Oid RenameTableSpace(const char *oldname, const char *newname);
extern Oid AlterTableSpaceOptions(AlterTableSpaceOptionsStmt *stmt);
-extern Oid AlterTableSpaceMove(AlterTableSpaceMoveStmt *stmt);
extern void TablespaceCreateDbspace(Oid spcNode, Oid dbNode, bool isRedo);
diff --git a/src/include/nodes/nodes.h b/src/include/nodes/nodes.h
index bc58e165258..5dcc66f27ff 100644
--- a/src/include/nodes/nodes.h
+++ b/src/include/nodes/nodes.h
@@ -354,7 +354,7 @@ typedef enum NodeTag
T_AlterUserMappingStmt,
T_DropUserMappingStmt,
T_AlterTableSpaceOptionsStmt,
- T_AlterTableSpaceMoveStmt,
+ T_AlterTableMoveAllStmt,
T_SecLabelStmt,
T_CreateForeignTableStmt,
T_CreateExtensionStmt,
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index 7e560a19a3b..3146aa53ed1 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -1689,16 +1689,15 @@ typedef struct AlterTableSpaceOptionsStmt
bool isReset;
} AlterTableSpaceOptionsStmt;
-typedef struct AlterTableSpaceMoveStmt
+typedef struct AlterTableMoveAllStmt
{
NodeTag type;
char *orig_tablespacename;
- ObjectType objtype; /* set to -1 if move_all is true */
- bool move_all; /* move all, or just objtype objects? */
+ ObjectType objtype; /* Object type to move */
List *roles; /* List of roles to move objects of */
char *new_tablespacename;
bool nowait;
-} AlterTableSpaceMoveStmt;
+} AlterTableMoveAllStmt;
/* ----------------------
* Create/Alter Extension Statements
diff --git a/src/test/regress/input/tablespace.source b/src/test/regress/input/tablespace.source
index 601522866d1..e259254b02c 100644
--- a/src/test/regress/input/tablespace.source
+++ b/src/test/regress/input/tablespace.source
@@ -76,10 +76,11 @@ CREATE TABLE tablespace_table (i int) TABLESPACE testspace; -- fail
ALTER TABLESPACE testspace RENAME TO testspace_renamed;
-ALTER TABLESPACE testspace_renamed MOVE ALL TO pg_default;
+ALTER TABLE ALL IN TABLESPACE testspace_renamed SET TABLESPACE pg_default;
+ALTER INDEX ALL IN TABLESPACE testspace_renamed SET TABLESPACE pg_default;
-- Should show notice that nothing was done
-ALTER TABLESPACE testspace_renamed MOVE ALL TO pg_default;
+ALTER TABLE ALL IN TABLESPACE testspace_renamed SET TABLESPACE pg_default;
-- Should succeed
DROP TABLESPACE testspace_renamed;
diff --git a/src/test/regress/output/tablespace.source b/src/test/regress/output/tablespace.source
index 27bc491e195..a30651087b9 100644
--- a/src/test/regress/output/tablespace.source
+++ b/src/test/regress/output/tablespace.source
@@ -93,9 +93,10 @@ CREATE TABLE tablespace_table (i int) TABLESPACE testspace; -- fail
ERROR: permission denied for tablespace testspace
\c -
ALTER TABLESPACE testspace RENAME TO testspace_renamed;
-ALTER TABLESPACE testspace_renamed MOVE ALL TO pg_default;
+ALTER TABLE ALL IN TABLESPACE testspace_renamed SET TABLESPACE pg_default;
+ALTER INDEX ALL IN TABLESPACE testspace_renamed SET TABLESPACE pg_default;
-- Should show notice that nothing was done
-ALTER TABLESPACE testspace_renamed MOVE ALL TO pg_default;
+ALTER TABLE ALL IN TABLESPACE testspace_renamed SET TABLESPACE pg_default;
NOTICE: no matching relations in tablespace "testspace_renamed" found
-- Should succeed
DROP TABLESPACE testspace_renamed;
diff --git a/src/tools/pgindent/typedefs.list b/src/tools/pgindent/typedefs.list
index 913d6ef6b28..ab36aa3acb6 100644
--- a/src/tools/pgindent/typedefs.list
+++ b/src/tools/pgindent/typedefs.list
@@ -77,7 +77,7 @@ AlterSystemStmt
AlterTSConfigurationStmt
AlterTSDictionaryStmt
AlterTableCmd
-AlterTableSpaceMoveStmt
+AlterTableMoveAllStmt
AlterTableSpaceOptionsStmt
AlterTableStmt
AlterTableType