Rework 'MOVE ALL' to 'ALTER .. ALL IN TABLESPACE'
authorStephen Frost
Thu, 21 Aug 2014 23:06:17 +0000 (19:06 -0400)
committerStephen Frost
Thu, 21 Aug 2014 23:12:00 +0000 (19:12 -0400)
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.

18 files changed:
doc/src/sgml/ref/alter_index.sgml
doc/src/sgml/ref/alter_materialized_view.sgml
doc/src/sgml/ref/alter_table.sgml
doc/src/sgml/ref/alter_tablespace.sgml
doc/src/sgml/release-9.4.sgml
src/backend/commands/tablecmds.c
src/backend/commands/tablespace.c
src/backend/nodes/copyfuncs.c
src/backend/nodes/equalfuncs.c
src/backend/parser/gram.y
src/backend/tcop/utility.c
src/include/commands/tablecmds.h
src/include/commands/tablespace.h
src/include/nodes/nodes.h
src/include/nodes/parsenodes.h
src/test/regress/input/tablespace.source
src/test/regress/output/tablespace.source
src/tools/pgindent/typedefs.list

index 94a7af0429c7561e25a5e92053baefd04890336b..ee3e3de4d6fe1cc179aa37c3a3360c946877cba2 100644 (file)
@@ -25,6 +25,8 @@ ALTER INDEX [ IF EXISTS ] name RENA
 ALTER INDEX [ IF EXISTS ] name SET TABLESPACE tablespace_name
 ALTER INDEX [ IF EXISTS ] name SET ( storage_parameter = value [, ... ] )
 ALTER INDEX [ IF EXISTS ] name RESET ( storage_parameter [, ... ] )
+ALTER INDEX ALL IN TABLESPACE name [ OWNED BY role_name [, ... ] ]
+    SET TABLESPACE new_tablespace [ NOWAIT ]
 
  
 
@@ -63,6 +65,17 @@ ALTER INDEX [ IF EXISTS ] name RESE
      
       This form changes the index's tablespace to the specified tablespace and
       moves the data file(s) associated with the index to the new tablespace.
+      To change the tablespace of an index, you must own the index and have
+      CREATE privilege on the new tablespace.
+      All indexes in the current database in a tablespace can be moved by using
+      the ALL IN TABLESPACE form, which will lock all
+      indexes to be moved and then move each one.  This form also supports
+      OWNED BY, which will only move indexes owned by the
+      roles specified.  If the NOWAIT option is specified
+      then the command will fail if it is unable to acquire all of the locks
+      required immediately.  Note that system catalogs will not be moved by
+      this command, use ALTER DATABASE or explicit
+      ALTER INDEX invocations instead if desired.
       See also
       .
      
index 1932eeb84d46272273f58a686e773c175c271c59..b0759fc5dca5af497e837f203d9edc7082820f4a 100644 (file)
@@ -29,6 +29,8 @@ ALTER MATERIALIZED VIEW [ IF EXISTS ] name
     RENAME TO new_name
 ALTER MATERIALIZED VIEW [ IF EXISTS ] name
     SET SCHEMA new_schema
+ALTER MATERIALIZED VIEW ALL IN TABLESPACE name [ OWNED BY role_name [, ... ] ]
+    SET TABLESPACE new_tablespace [ NOWAIT ]
 
 where action is one of:
 
index 69a1e14bce3d9ff84b0ed44650f5d09fda59d8f4..0e7b99c934cc68db1a7251959ce2d3b9a9e08076 100644 (file)
@@ -31,6 +31,8 @@ ALTER TABLE [ IF EXISTS ] name
     RENAME TO new_name
 ALTER TABLE [ IF EXISTS ] name
     SET SCHEMA new_schema
+ALTER TABLE ALL IN TABLESPACE name [ OWNED BY role_name [, ... ] ]
+    SET TABLESPACE new_tablespace [ NOWAIT ]
 
 where action is one of:
 
@@ -597,6 +599,17 @@ ALTER TABLE [ IF EXISTS ] name
       moves the data file(s) associated with the table to the new tablespace.
       Indexes on the table, if any, are not moved; but they can be moved
       separately with additional SET TABLESPACE commands.
+      All tables in the current database in a tablespace can be moved by using
+      the ALL IN TABLESPACE form, which will lock all tables
+      to be moved first and then move each one.  This form also supports
+      OWNED BY, which will only move tables owned by the
+      roles specified.  If the NOWAIT option is specified
+      then the command will fail if it is unable to acquire all of the locks
+      required immediately.  Note that system catalogs are not moved by this
+      command, use ALTER DATABASE or explicit
+      ALTER TABLE invocations instead if desired.  The
+      information_schema relations are not considered part
+      of the system catalogs and will be moved.
       See also
       .
      
@@ -649,7 +662,8 @@ ALTER TABLE [ IF EXISTS ] name
   
 
   
-   All the actions except RENAME and SET SCHEMA
+   All the actions except RENAME,
+   SET TABLESPACE and SET SCHEMA
    can be combined into
    a list of multiple alterations to apply in parallel.  For example, it
    is possible to add several columns and/or alter the type of several
@@ -659,8 +673,8 @@ ALTER TABLE [ IF EXISTS ] name
 
   
    You must own the table to use ALTER TABLE.
-   To change the schema of a table, you must also have
-   CREATE privilege on the new schema.
+   To change the schema or tablespace of a table, you must also have
+   CREATE privilege on the new schema or tablespace.
    To add the table as a new child of a parent table, you must own the
    parent table as well.
    To alter the owner, you must also be a direct or indirect member of the new
index bd1afb4b727257932034faef944b17477d8172ef..7c4aabc582681828fd5b2c7d1bf227f1fc7ca737 100644 (file)
@@ -25,7 +25,6 @@ ALTER TABLESPACE name RENAME TO new_name
 ALTER TABLESPACE name OWNER TO new_owner
 ALTER TABLESPACE name SET ( tablespace_option = value [, ... ] )
 ALTER TABLESPACE name RESET ( tablespace_option [, ... ] )
-ALTER TABLESPACE name MOVE { ALL | TABLES | INDEXES | MATERIALIZED VIEWS } [ OWNED BY role_name [, ...] ] TO new_tablespace [ NOWAIT ]
 
  
 
@@ -45,44 +44,6 @@ ALTER TABLESPACE name MOVE { ALL | TABLES | INDEXES |
    (Note that superusers have these privileges automatically.)
   
 
-  
-   ALTER TABLESPACE ... MOVE moves objects between
-   tablespaces.  ALL will move all tables, indexes and
-   materialized views; specifying TABLES will move only
-   tables (but not their indexes), INDEXES will only move
-   indexes (including those underneath materialized views, but not tables),
-   and MATERIALIZED VIEWS will only move the table relation
-   of the materialized view (but no indexes associated with it).  Users can
-   also specify a list of roles whose objects are to be moved, using
-   OWNED BY.
-  
-
-  
-   Users must have CREATE rights on the new tablespace and
-   be considered an owner (either directly or indirectly) of all objects to be
-   moved.  Note that the superuser is considered an owner of all objects, and
-   therefore an ALTER TABLESPACE ... MOVE ALL issued by the
-   superuser will move all objects in the current database that are in the
-   tablespace.  (Attempting to move objects without the required rights will
-   result in an error.  Non-superusers can use OWNED BY in
-   such cases, to restrict the set of objects moved to those with the required
-   rights.)
-  
-
-  
-   All objects to be moved will be locked immediately by the command.  If the
-   NOWAIT is specified, it will cause the command to fail
-   if it is unable to acquire the locks.
-  
-
-  
-   System catalogs will not be moved by this command.  To move a whole
-   database, use ALTER DATABASE, or call ALTER
-   TABLE on the individual system catalogs.  Note that relations in
-   information_schema will be moved, just as any other
-   normal database objects, if the user is the superuser or considered an
-   owner of the relations in information_schema.
-  
  
 
  
@@ -136,38 +97,6 @@ ALTER TABLESPACE name MOVE { ALL | TABLES | INDEXES |
     
    
 
-   
-    role_name
-    
-     
-      Role whose objects are to be moved.
-     
-    
-   
-
-   
-    new_tablespace
-    
-     
-      The name of the tablespace to move objects into.  The user must have
-      CREATE rights on the new tablespace to move objects into that
-      tablespace, unless the tablespace being moved into is the default
-      tablespace for the database connected to.
-     
-    
-   
-
-   
-    NOWAIT
-    
-     
-      The NOWAIT option causes the ALTER TABLESPACE command to fail immediately
-      if it is unable to acquire the necessary lock on all of the objects being
-      moved.
-     
-    
-   
-
   
  
 
@@ -185,13 +114,6 @@ ALTER TABLESPACE index_space RENAME TO fast_raid;
    Change the owner of tablespace index_space:
 
 ALTER TABLESPACE index_space OWNER TO mary;
-
-
-  
-   Move all of the objects from the default tablespace to
-   the fast_raid tablespace:
-
-ALTER TABLESPACE pg_default MOVE ALL TO fast_raid;
 
  
 
index e338554995dfb6a93b551982e890b4a44047bce4..5233ed256aecbb9502774279abec61f3a3064a1c 100644 (file)
       
        
         Allow moving groups of objects from one tablespace to another
-        using  ... MOVE
+        using ALL IN TABLESPACE ... SET TABLESPACE with
+        ALTER TABLE
+        ALTER INDEX and
+        ALTER MATERIALIZED VIEW
         (Stephen Frost)
        
       
index 89bd31ab93e2e20ec1e0826d7c9ca9d7653bddbd..34c38de3fff2d6f819ba656daf0193dbfc596838 100644 (file)
@@ -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"
@@ -9204,6 +9205,176 @@ ATExecSetTableSpace(Oid tableOid, Oid newTableSpace, LOCKMODE lockmode)
    list_free(reltoastidxids);
 }
 
+/*
+ * 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
  */
index 031be37a1e7531dc4eecdd620d3b37d502ee1088..28e69a55510aabe246d71a41251927ce5cec55d6 100644 (file)
@@ -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"
@@ -991,184 +990,6 @@ AlterTableSpaceOptions(AlterTableSpaceOptionsStmt *stmt)
    return tablespaceoid;
 }
 
-/*
- * 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'.
  */
index 43530aa24a8e1fd6237c9bd91f36fa325419a207..221d0fee6bbd689f7c61d0f2bec5bb6e180a6c6e 100644 (file)
@@ -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);
index 2407cb73a380d15a2ab04dbc65c604aaaf3910fb..7e53681e70654668c13c287a3ff7e6bcb76561d0 100644 (file)
@@ -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);
index 7b9895d61ece74e80a863809764dfc2a7203b79c..2e9bbe232f9d2f3200a8b8077bd199ac8481987b 100644 (file)
@@ -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);
index 3423898c1125cf64e292f0c1939e023cf408c2b5..0558ea34b054db356ff081abc0b10d7bb2b0186d 100644 (file)
@@ -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;
index e55f45ab26f3e9f78af08c4c987096c629bd5e98..932322f144c476d4913bd09cef879016bd820616 100644 (file)
@@ -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,
index 1603f677a7de23b68d7e0ac6da7eeca0617a2d2f..c7af55917d77f15f75ede7254b237a150641aceb 100644 (file)
@@ -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);
 
index bc58e165258573c4ba4bc61fdee0d80cd26da907..5dcc66f27fff1f14a28064a6226ef6a3e821bd1b 100644 (file)
@@ -354,7 +354,7 @@ typedef enum NodeTag
    T_AlterUserMappingStmt,
    T_DropUserMappingStmt,
    T_AlterTableSpaceOptionsStmt,
-   T_AlterTableSpaceMoveStmt,
+   T_AlterTableMoveAllStmt,
    T_SecLabelStmt,
    T_CreateForeignTableStmt,
    T_CreateExtensionStmt,
index 7e560a19a3bd114c639bdc7edfa817e5d6fc91b7..3146aa53ed160d932d6c24df7ae705bd2d1ce3cd 100644 (file)
@@ -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
index 601522866d11a8e83a48c6153abb5cc21e051b99..e259254b02cb6bda9bf443ed6b8f0c2c7a5a91c4 100644 (file)
@@ -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;
index 27bc491e1959cfda79bc9136b0e3793321519148..a30651087b9d59c144a287c8d5a837295a406b86 100644 (file)
@@ -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;
index 913d6ef6b288778517dd180724add688272081e5..ab36aa3acb64014286a01208465beae5a6f41432 100644 (file)
@@ -77,7 +77,7 @@ AlterSystemStmt
 AlterTSConfigurationStmt
 AlterTSDictionaryStmt
 AlterTableCmd
-AlterTableSpaceMoveStmt
+AlterTableMoveAllStmt
 AlterTableSpaceOptionsStmt
 AlterTableStmt
 AlterTableType