Commit 3c4cf080 authored by Stephen Frost's avatar Stephen Frost

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.
parent f5779198
...@@ -25,6 +25,8 @@ ALTER INDEX [ IF EXISTS ] <replaceable class="PARAMETER">name</replaceable> RENA ...@@ -25,6 +25,8 @@ ALTER INDEX [ IF EXISTS ] <replaceable class="PARAMETER">name</replaceable> RENA
ALTER INDEX [ IF EXISTS ] <replaceable class="PARAMETER">name</replaceable> SET TABLESPACE <replaceable class="PARAMETER">tablespace_name</replaceable> ALTER INDEX [ IF EXISTS ] <replaceable class="PARAMETER">name</replaceable> SET TABLESPACE <replaceable class="PARAMETER">tablespace_name</replaceable>
ALTER INDEX [ IF EXISTS ] <replaceable class="PARAMETER">name</replaceable> SET ( <replaceable class="PARAMETER">storage_parameter</replaceable> = <replaceable class="PARAMETER">value</replaceable> [, ... ] ) ALTER INDEX [ IF EXISTS ] <replaceable class="PARAMETER">name</replaceable> SET ( <replaceable class="PARAMETER">storage_parameter</replaceable> = <replaceable class="PARAMETER">value</replaceable> [, ... ] )
ALTER INDEX [ IF EXISTS ] <replaceable class="PARAMETER">name</replaceable> RESET ( <replaceable class="PARAMETER">storage_parameter</replaceable> [, ... ] ) ALTER INDEX [ IF EXISTS ] <replaceable class="PARAMETER">name</replaceable> RESET ( <replaceable class="PARAMETER">storage_parameter</replaceable> [, ... ] )
ALTER INDEX ALL IN TABLESPACE <replaceable class="PARAMETER">name</replaceable> [ OWNED BY <replaceable class="PARAMETER">role_name</replaceable> [, ... ] ]
SET TABLESPACE <replaceable class="PARAMETER">new_tablespace</replaceable> [ NOWAIT ]
</synopsis> </synopsis>
</refsynopsisdiv> </refsynopsisdiv>
...@@ -63,6 +65,17 @@ ALTER INDEX [ IF EXISTS ] <replaceable class="PARAMETER">name</replaceable> RESE ...@@ -63,6 +65,17 @@ ALTER INDEX [ IF EXISTS ] <replaceable class="PARAMETER">name</replaceable> RESE
<para> <para>
This form changes the index's tablespace to the specified tablespace and 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. 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
<literal>CREATE</literal> privilege on the new tablespace.
All indexes in the current database in a tablespace can be moved by using
the <literal>ALL IN TABLESPACE</literal> form, which will lock all
indexes to be moved and then move each one. This form also supports
<literal>OWNED BY</literal>, which will only move indexes owned by the
roles specified. If the <literal>NOWAIT</literal> 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 <command>ALTER DATABASE</command> or explicit
<command>ALTER INDEX</command> invocations instead if desired.
See also See also
<xref linkend="SQL-CREATETABLESPACE">. <xref linkend="SQL-CREATETABLESPACE">.
</para> </para>
......
...@@ -29,6 +29,8 @@ ALTER MATERIALIZED VIEW [ IF EXISTS ] <replaceable class="parameter">name</repla ...@@ -29,6 +29,8 @@ ALTER MATERIALIZED VIEW [ IF EXISTS ] <replaceable class="parameter">name</repla
RENAME TO <replaceable class="parameter">new_name</replaceable> RENAME TO <replaceable class="parameter">new_name</replaceable>
ALTER MATERIALIZED VIEW [ IF EXISTS ] <replaceable class="parameter">name</replaceable> ALTER MATERIALIZED VIEW [ IF EXISTS ] <replaceable class="parameter">name</replaceable>
SET SCHEMA <replaceable class="parameter">new_schema</replaceable> SET SCHEMA <replaceable class="parameter">new_schema</replaceable>
ALTER MATERIALIZED VIEW ALL IN TABLESPACE <replaceable class="parameter">name</replaceable> [ OWNED BY <replaceable class="PARAMETER">role_name</replaceable> [, ... ] ]
SET TABLESPACE <replaceable class="PARAMETER">new_tablespace</replaceable> [ NOWAIT ]
<phrase>where <replaceable class="PARAMETER">action</replaceable> is one of:</phrase> <phrase>where <replaceable class="PARAMETER">action</replaceable> is one of:</phrase>
......
...@@ -31,6 +31,8 @@ ALTER TABLE [ IF EXISTS ] <replaceable class="PARAMETER">name</replaceable> ...@@ -31,6 +31,8 @@ ALTER TABLE [ IF EXISTS ] <replaceable class="PARAMETER">name</replaceable>
RENAME TO <replaceable class="PARAMETER">new_name</replaceable> RENAME TO <replaceable class="PARAMETER">new_name</replaceable>
ALTER TABLE [ IF EXISTS ] <replaceable class="PARAMETER">name</replaceable> ALTER TABLE [ IF EXISTS ] <replaceable class="PARAMETER">name</replaceable>
SET SCHEMA <replaceable class="PARAMETER">new_schema</replaceable> SET SCHEMA <replaceable class="PARAMETER">new_schema</replaceable>
ALTER TABLE ALL IN TABLESPACE <replaceable class="PARAMETER">name</replaceable> [ OWNED BY <replaceable class="PARAMETER">role_name</replaceable> [, ... ] ]
SET TABLESPACE <replaceable class="PARAMETER">new_tablespace</replaceable> [ NOWAIT ]
<phrase>where <replaceable class="PARAMETER">action</replaceable> is one of:</phrase> <phrase>where <replaceable class="PARAMETER">action</replaceable> is one of:</phrase>
...@@ -597,6 +599,17 @@ ALTER TABLE [ IF EXISTS ] <replaceable class="PARAMETER">name</replaceable> ...@@ -597,6 +599,17 @@ ALTER TABLE [ IF EXISTS ] <replaceable class="PARAMETER">name</replaceable>
moves the data file(s) associated with the table to the new tablespace. 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 Indexes on the table, if any, are not moved; but they can be moved
separately with additional <literal>SET TABLESPACE</literal> commands. separately with additional <literal>SET TABLESPACE</literal> commands.
All tables in the current database in a tablespace can be moved by using
the <literal>ALL IN TABLESPACE</literal> form, which will lock all tables
to be moved first and then move each one. This form also supports
<literal>OWNED BY</literal>, which will only move tables owned by the
roles specified. If the <literal>NOWAIT</literal> 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 <command>ALTER DATABASE</command> or explicit
<command>ALTER TABLE</command> invocations instead if desired. The
<literal>information_schema</literal> relations are not considered part
of the system catalogs and will be moved.
See also See also
<xref linkend="SQL-CREATETABLESPACE">. <xref linkend="SQL-CREATETABLESPACE">.
</para> </para>
...@@ -649,7 +662,8 @@ ALTER TABLE [ IF EXISTS ] <replaceable class="PARAMETER">name</replaceable> ...@@ -649,7 +662,8 @@ ALTER TABLE [ IF EXISTS ] <replaceable class="PARAMETER">name</replaceable>
</para> </para>
<para> <para>
All the actions except <literal>RENAME</literal> and <literal>SET SCHEMA</> All the actions except <literal>RENAME</literal>,
<literal>SET TABLESPACE</literal> and <literal>SET SCHEMA</literal>
can be combined into can be combined into
a list of multiple alterations to apply in parallel. For example, it 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 is possible to add several columns and/or alter the type of several
...@@ -659,8 +673,8 @@ ALTER TABLE [ IF EXISTS ] <replaceable class="PARAMETER">name</replaceable> ...@@ -659,8 +673,8 @@ ALTER TABLE [ IF EXISTS ] <replaceable class="PARAMETER">name</replaceable>
<para> <para>
You must own the table to use <command>ALTER TABLE</>. You must own the table to use <command>ALTER TABLE</>.
To change the schema of a table, you must also have To change the schema or tablespace of a table, you must also have
<literal>CREATE</literal> privilege on the new schema. <literal>CREATE</literal> privilege on the new schema or tablespace.
To add the table as a new child of a parent table, you must own the To add the table as a new child of a parent table, you must own the
parent table as well. parent table as well.
To alter the owner, you must also be a direct or indirect member of the new To alter the owner, you must also be a direct or indirect member of the new
......
...@@ -25,7 +25,6 @@ ALTER TABLESPACE <replaceable>name</replaceable> RENAME TO <replaceable>new_name ...@@ -25,7 +25,6 @@ ALTER TABLESPACE <replaceable>name</replaceable> RENAME TO <replaceable>new_name
ALTER TABLESPACE <replaceable>name</replaceable> OWNER TO <replaceable>new_owner</replaceable> ALTER TABLESPACE <replaceable>name</replaceable> OWNER TO <replaceable>new_owner</replaceable>
ALTER TABLESPACE <replaceable>name</replaceable> SET ( <replaceable class="PARAMETER">tablespace_option</replaceable> = <replaceable class="PARAMETER">value</replaceable> [, ... ] ) ALTER TABLESPACE <replaceable>name</replaceable> SET ( <replaceable class="PARAMETER">tablespace_option</replaceable> = <replaceable class="PARAMETER">value</replaceable> [, ... ] )
ALTER TABLESPACE <replaceable>name</replaceable> RESET ( <replaceable class="PARAMETER">tablespace_option</replaceable> [, ... ] ) ALTER TABLESPACE <replaceable>name</replaceable> RESET ( <replaceable class="PARAMETER">tablespace_option</replaceable> [, ... ] )
ALTER TABLESPACE <replaceable>name</replaceable> MOVE { ALL | TABLES | INDEXES | MATERIALIZED VIEWS } [ OWNED BY <replaceable class="PARAMETER">role_name</replaceable> [, ...] ] TO <replaceable>new_tablespace</replaceable> [ NOWAIT ]
</synopsis> </synopsis>
</refsynopsisdiv> </refsynopsisdiv>
...@@ -45,44 +44,6 @@ ALTER TABLESPACE <replaceable>name</replaceable> MOVE { ALL | TABLES | INDEXES | ...@@ -45,44 +44,6 @@ ALTER TABLESPACE <replaceable>name</replaceable> MOVE { ALL | TABLES | INDEXES |
(Note that superusers have these privileges automatically.) (Note that superusers have these privileges automatically.)
</para> </para>
<para>
<literal>ALTER TABLESPACE ... MOVE</literal> moves objects between
tablespaces. <literal>ALL</literal> will move all tables, indexes and
materialized views; specifying <literal>TABLES</literal> will move only
tables (but not their indexes), <literal>INDEXES</literal> will only move
indexes (including those underneath materialized views, but not tables),
and <literal>MATERIALIZED VIEWS</literal> 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
<literal>OWNED BY</literal>.
</para>
<para>
Users must have <literal>CREATE</literal> 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 <literal>ALTER TABLESPACE ... MOVE ALL</literal> 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 <literal>OWNED BY</literal> in
such cases, to restrict the set of objects moved to those with the required
rights.)
</para>
<para>
All objects to be moved will be locked immediately by the command. If the
<literal>NOWAIT</literal> is specified, it will cause the command to fail
if it is unable to acquire the locks.
</para>
<para>
System catalogs will not be moved by this command. To move a whole
database, use <command>ALTER DATABASE</command>, or call <command>ALTER
TABLE</command> on the individual system catalogs. Note that relations in
<literal>information_schema</literal> will be moved, just as any other
normal database objects, if the user is the superuser or considered an
owner of the relations in <literal>information_schema</literal>.
</para>
</refsect1> </refsect1>
<refsect1> <refsect1>
...@@ -136,38 +97,6 @@ ALTER TABLESPACE <replaceable>name</replaceable> MOVE { ALL | TABLES | INDEXES | ...@@ -136,38 +97,6 @@ ALTER TABLESPACE <replaceable>name</replaceable> MOVE { ALL | TABLES | INDEXES |
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><replaceable class="parameter">role_name</replaceable></term>
<listitem>
<para>
Role whose objects are to be moved.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><replaceable class="parameter">new_tablespace</replaceable></term>
<listitem>
<para>
The name of the tablespace to move objects into. The user must have
<literal>CREATE</literal> 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.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>NOWAIT</term>
<listitem>
<para>
The <literal>NOWAIT</literal> option causes the <command>ALTER TABLESPACE</command> command to fail immediately
if it is unable to acquire the necessary lock on all of the objects being
moved.
</para>
</listitem>
</varlistentry>
</variablelist> </variablelist>
</refsect1> </refsect1>
...@@ -185,13 +114,6 @@ ALTER TABLESPACE index_space RENAME TO fast_raid; ...@@ -185,13 +114,6 @@ ALTER TABLESPACE index_space RENAME TO fast_raid;
Change the owner of tablespace <literal>index_space</literal>: Change the owner of tablespace <literal>index_space</literal>:
<programlisting> <programlisting>
ALTER TABLESPACE index_space OWNER TO mary; ALTER TABLESPACE index_space OWNER TO mary;
</programlisting></para>
<para>
Move all of the objects from the default tablespace to
the <literal>fast_raid</literal> tablespace:
<programlisting>
ALTER TABLESPACE pg_default MOVE ALL TO fast_raid;
</programlisting></para> </programlisting></para>
</refsect1> </refsect1>
......
...@@ -1224,7 +1224,10 @@ ...@@ -1224,7 +1224,10 @@
<listitem> <listitem>
<para> <para>
Allow moving groups of objects from one tablespace to another Allow moving groups of objects from one tablespace to another
using <xref linkend="SQL-ALTERTABLESPACE"> ... <literal>MOVE</> using <literal>ALL IN TABLESPACE ... SET TABLESPACE</> with
<link linkend="SQL-ALTERTABLE"><command>ALTER TABLE</></link>
<link linkend="SQL-ALTERINDEX"><command>ALTER INDEX</></link> and
<link linkend="SQL-ALTERMATERIALIZEDVIEW"><command>ALTER MATERIALIZED VIEW</></link>
(Stephen Frost) (Stephen Frost)
</para> </para>
</listitem> </listitem>
......
...@@ -50,6 +50,7 @@ ...@@ -50,6 +50,7 @@
#include "commands/tablespace.h" #include "commands/tablespace.h"
#include "commands/trigger.h" #include "commands/trigger.h"
#include "commands/typecmds.h" #include "commands/typecmds.h"
#include "commands/user.h"
#include "executor/executor.h" #include "executor/executor.h"
#include "foreign/foreign.h" #include "foreign/foreign.h"
#include "miscadmin.h" #include "miscadmin.h"
...@@ -9203,6 +9204,176 @@ ATExecSetTableSpace(Oid tableOid, Oid newTableSpace, LOCKMODE lockmode) ...@@ -9203,6 +9204,176 @@ ATExecSetTableSpace(Oid tableOid, Oid newTableSpace, LOCKMODE lockmode)
list_free(reltoastidxids); 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 * Copy data, block by block
*/ */
......
...@@ -67,7 +67,6 @@ ...@@ -67,7 +67,6 @@
#include "commands/seclabel.h" #include "commands/seclabel.h"
#include "commands/tablecmds.h" #include "commands/tablecmds.h"
#include "commands/tablespace.h" #include "commands/tablespace.h"
#include "commands/user.h"
#include "miscadmin.h" #include "miscadmin.h"
#include "postmaster/bgwriter.h" #include "postmaster/bgwriter.h"
#include "storage/fd.h" #include "storage/fd.h"
...@@ -991,184 +990,6 @@ AlterTableSpaceOptions(AlterTableSpaceOptionsStmt *stmt) ...@@ -991,184 +990,6 @@ AlterTableSpaceOptions(AlterTableSpaceOptionsStmt *stmt)
return tablespaceoid; 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'. * Routines for handling the GUC variable 'default_tablespace'.
*/ */
......
...@@ -3415,14 +3415,13 @@ _copyAlterTableSpaceOptionsStmt(const AlterTableSpaceOptionsStmt *from) ...@@ -3415,14 +3415,13 @@ _copyAlterTableSpaceOptionsStmt(const AlterTableSpaceOptionsStmt *from)
return newnode; return newnode;
} }
static AlterTableSpaceMoveStmt * static AlterTableMoveAllStmt *
_copyAlterTableSpaceMoveStmt(const AlterTableSpaceMoveStmt *from) _copyAlterTableMoveAllStmt(const AlterTableMoveAllStmt *from)
{ {
AlterTableSpaceMoveStmt *newnode = makeNode(AlterTableSpaceMoveStmt); AlterTableMoveAllStmt *newnode = makeNode(AlterTableMoveAllStmt);
COPY_STRING_FIELD(orig_tablespacename); COPY_STRING_FIELD(orig_tablespacename);
COPY_SCALAR_FIELD(objtype); COPY_SCALAR_FIELD(objtype);
COPY_SCALAR_FIELD(move_all);
COPY_NODE_FIELD(roles); COPY_NODE_FIELD(roles);
COPY_STRING_FIELD(new_tablespacename); COPY_STRING_FIELD(new_tablespacename);
COPY_SCALAR_FIELD(nowait); COPY_SCALAR_FIELD(nowait);
...@@ -4456,8 +4455,8 @@ copyObject(const void *from) ...@@ -4456,8 +4455,8 @@ copyObject(const void *from)
case T_AlterTableSpaceOptionsStmt: case T_AlterTableSpaceOptionsStmt:
retval = _copyAlterTableSpaceOptionsStmt(from); retval = _copyAlterTableSpaceOptionsStmt(from);
break; break;
case T_AlterTableSpaceMoveStmt: case T_AlterTableMoveAllStmt:
retval = _copyAlterTableSpaceMoveStmt(from); retval = _copyAlterTableMoveAllStmt(from);
break; break;
case T_CreateExtensionStmt: case T_CreateExtensionStmt:
retval = _copyCreateExtensionStmt(from); retval = _copyCreateExtensionStmt(from);
......
...@@ -1639,12 +1639,11 @@ _equalAlterTableSpaceOptionsStmt(const AlterTableSpaceOptionsStmt *a, ...@@ -1639,12 +1639,11 @@ _equalAlterTableSpaceOptionsStmt(const AlterTableSpaceOptionsStmt *a,
} }
static bool static bool
_equalAlterTableSpaceMoveStmt(const AlterTableSpaceMoveStmt *a, _equalAlterTableMoveAllStmt(const AlterTableMoveAllStmt *a,
const AlterTableSpaceMoveStmt *b) const AlterTableMoveAllStmt *b)
{ {
COMPARE_STRING_FIELD(orig_tablespacename); COMPARE_STRING_FIELD(orig_tablespacename);
COMPARE_SCALAR_FIELD(objtype); COMPARE_SCALAR_FIELD(objtype);
COMPARE_SCALAR_FIELD(move_all);
COMPARE_NODE_FIELD(roles); COMPARE_NODE_FIELD(roles);
COMPARE_STRING_FIELD(new_tablespacename); COMPARE_STRING_FIELD(new_tablespacename);
COMPARE_SCALAR_FIELD(nowait); COMPARE_SCALAR_FIELD(nowait);
...@@ -2920,8 +2919,8 @@ equal(const void *a, const void *b) ...@@ -2920,8 +2919,8 @@ equal(const void *a, const void *b)
case T_AlterTableSpaceOptionsStmt: case T_AlterTableSpaceOptionsStmt:
retval = _equalAlterTableSpaceOptionsStmt(a, b); retval = _equalAlterTableSpaceOptionsStmt(a, b);
break; break;
case T_AlterTableSpaceMoveStmt: case T_AlterTableMoveAllStmt:
retval = _equalAlterTableSpaceMoveStmt(a, b); retval = _equalAlterTableMoveAllStmt(a, b);
break; break;
case T_CreateExtensionStmt: case T_CreateExtensionStmt:
retval = _equalCreateExtensionStmt(a, b); retval = _equalCreateExtensionStmt(a, b);
......
...@@ -1763,6 +1763,28 @@ AlterTableStmt: ...@@ -1763,6 +1763,28 @@ AlterTableStmt:
n->missing_ok = true; n->missing_ok = true;
$$ = (Node *)n; $$ = (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 | ALTER INDEX qualified_name alter_table_cmds
{ {
AlterTableStmt *n = makeNode(AlterTableStmt); AlterTableStmt *n = makeNode(AlterTableStmt);
...@@ -1781,6 +1803,28 @@ AlterTableStmt: ...@@ -1781,6 +1803,28 @@ AlterTableStmt:
n->missing_ok = true; n->missing_ok = true;
$$ = (Node *)n; $$ = (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 | ALTER SEQUENCE qualified_name alter_table_cmds
{ {
AlterTableStmt *n = makeNode(AlterTableStmt); AlterTableStmt *n = makeNode(AlterTableStmt);
...@@ -1835,6 +1879,28 @@ AlterTableStmt: ...@@ -1835,6 +1879,28 @@ AlterTableStmt:
n->missing_ok = true; n->missing_ok = true;
$$ = (Node *)n; $$ = (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: alter_table_cmds:
...@@ -7002,103 +7068,8 @@ opt_force: FORCE { $$ = TRUE; } ...@@ -7002,103 +7068,8 @@ opt_force: FORCE { $$ = TRUE; }
* *
*****************************************************************************/ *****************************************************************************/
AlterTblSpcStmt: ALTER TABLESPACE name MOVE ALL TO name opt_nowait AlterTblSpcStmt:
{ ALTER TABLESPACE name SET reloptions
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
{ {
AlterTableSpaceOptionsStmt *n = AlterTableSpaceOptionsStmt *n =
makeNode(AlterTableSpaceOptionsStmt); makeNode(AlterTableSpaceOptionsStmt);
......
...@@ -147,6 +147,7 @@ check_xact_readonly(Node *parsetree) ...@@ -147,6 +147,7 @@ check_xact_readonly(Node *parsetree)
case T_AlterObjectSchemaStmt: case T_AlterObjectSchemaStmt:
case T_AlterOwnerStmt: case T_AlterOwnerStmt:
case T_AlterSeqStmt: case T_AlterSeqStmt:
case T_AlterTableMoveAllStmt:
case T_AlterTableStmt: case T_AlterTableStmt:
case T_RenameStmt: case T_RenameStmt:
case T_CommentStmt: case T_CommentStmt:
...@@ -200,7 +201,6 @@ check_xact_readonly(Node *parsetree) ...@@ -200,7 +201,6 @@ check_xact_readonly(Node *parsetree)
case T_AlterUserMappingStmt: case T_AlterUserMappingStmt:
case T_DropUserMappingStmt: case T_DropUserMappingStmt:
case T_AlterTableSpaceOptionsStmt: case T_AlterTableSpaceOptionsStmt:
case T_AlterTableSpaceMoveStmt:
case T_CreateForeignTableStmt: case T_CreateForeignTableStmt:
case T_ImportForeignSchemaStmt: case T_ImportForeignSchemaStmt:
case T_SecLabelStmt: case T_SecLabelStmt:
...@@ -507,9 +507,8 @@ standard_ProcessUtility(Node *parsetree, ...@@ -507,9 +507,8 @@ standard_ProcessUtility(Node *parsetree,
AlterTableSpaceOptions((AlterTableSpaceOptionsStmt *) parsetree); AlterTableSpaceOptions((AlterTableSpaceOptionsStmt *) parsetree);
break; break;
case T_AlterTableSpaceMoveStmt: case T_AlterTableMoveAllStmt:
/* no event triggers for global objects */ AlterTableMoveAll((AlterTableMoveAllStmt *) parsetree);
AlterTableSpaceMove((AlterTableSpaceMoveStmt *) parsetree);
break; break;
case T_TruncateStmt: case T_TruncateStmt:
...@@ -1810,10 +1809,6 @@ CreateCommandTag(Node *parsetree) ...@@ -1810,10 +1809,6 @@ CreateCommandTag(Node *parsetree)
tag = "ALTER TABLESPACE"; tag = "ALTER TABLESPACE";
break; break;
case T_AlterTableSpaceMoveStmt:
tag = "ALTER TABLESPACE";
break;
case T_CreateExtensionStmt: case T_CreateExtensionStmt:
tag = "CREATE EXTENSION"; tag = "CREATE EXTENSION";
break; break;
...@@ -1982,6 +1977,10 @@ CreateCommandTag(Node *parsetree) ...@@ -1982,6 +1977,10 @@ CreateCommandTag(Node *parsetree)
tag = AlterObjectTypeCommandTag(((AlterOwnerStmt *) parsetree)->objectType); tag = AlterObjectTypeCommandTag(((AlterOwnerStmt *) parsetree)->objectType);
break; break;
case T_AlterTableMoveAllStmt:
tag = AlterObjectTypeCommandTag(((AlterTableMoveAllStmt *) parsetree)->objtype);
break;
case T_AlterTableStmt: case T_AlterTableStmt:
tag = AlterObjectTypeCommandTag(((AlterTableStmt *) parsetree)->relkind); tag = AlterObjectTypeCommandTag(((AlterTableStmt *) parsetree)->relkind);
break; break;
...@@ -2510,10 +2509,6 @@ GetCommandLogLevel(Node *parsetree) ...@@ -2510,10 +2509,6 @@ GetCommandLogLevel(Node *parsetree)
lev = LOGSTMT_DDL; lev = LOGSTMT_DDL;
break; break;
case T_AlterTableSpaceMoveStmt:
lev = LOGSTMT_DDL;
break;
case T_CreateExtensionStmt: case T_CreateExtensionStmt:
case T_AlterExtensionStmt: case T_AlterExtensionStmt:
case T_AlterExtensionContentsStmt: case T_AlterExtensionContentsStmt:
...@@ -2593,6 +2588,7 @@ GetCommandLogLevel(Node *parsetree) ...@@ -2593,6 +2588,7 @@ GetCommandLogLevel(Node *parsetree)
lev = LOGSTMT_DDL; lev = LOGSTMT_DDL;
break; break;
case T_AlterTableMoveAllStmt:
case T_AlterTableStmt: case T_AlterTableStmt:
lev = LOGSTMT_DDL; lev = LOGSTMT_DDL;
break; break;
......
...@@ -35,6 +35,8 @@ extern void ATExecChangeOwner(Oid relationOid, Oid newOwnerId, bool recursing, L ...@@ -35,6 +35,8 @@ extern void ATExecChangeOwner(Oid relationOid, Oid newOwnerId, bool recursing, L
extern void AlterTableInternal(Oid relid, List *cmds, bool recurse); extern void AlterTableInternal(Oid relid, List *cmds, bool recurse);
extern Oid AlterTableMoveAll(AlterTableMoveAllStmt *stmt);
extern Oid AlterTableNamespace(AlterObjectSchemaStmt *stmt); extern Oid AlterTableNamespace(AlterObjectSchemaStmt *stmt);
extern void AlterTableNamespaceInternal(Relation rel, Oid oldNspOid, extern void AlterTableNamespaceInternal(Relation rel, Oid oldNspOid,
......
...@@ -43,7 +43,6 @@ extern Oid CreateTableSpace(CreateTableSpaceStmt *stmt); ...@@ -43,7 +43,6 @@ extern Oid CreateTableSpace(CreateTableSpaceStmt *stmt);
extern void DropTableSpace(DropTableSpaceStmt *stmt); extern void DropTableSpace(DropTableSpaceStmt *stmt);
extern Oid RenameTableSpace(const char *oldname, const char *newname); extern Oid RenameTableSpace(const char *oldname, const char *newname);
extern Oid AlterTableSpaceOptions(AlterTableSpaceOptionsStmt *stmt); extern Oid AlterTableSpaceOptions(AlterTableSpaceOptionsStmt *stmt);
extern Oid AlterTableSpaceMove(AlterTableSpaceMoveStmt *stmt);
extern void TablespaceCreateDbspace(Oid spcNode, Oid dbNode, bool isRedo); extern void TablespaceCreateDbspace(Oid spcNode, Oid dbNode, bool isRedo);
......
...@@ -354,7 +354,7 @@ typedef enum NodeTag ...@@ -354,7 +354,7 @@ typedef enum NodeTag
T_AlterUserMappingStmt, T_AlterUserMappingStmt,
T_DropUserMappingStmt, T_DropUserMappingStmt,
T_AlterTableSpaceOptionsStmt, T_AlterTableSpaceOptionsStmt,
T_AlterTableSpaceMoveStmt, T_AlterTableMoveAllStmt,
T_SecLabelStmt, T_SecLabelStmt,
T_CreateForeignTableStmt, T_CreateForeignTableStmt,
T_ImportForeignSchemaStmt, T_ImportForeignSchemaStmt,
......
...@@ -1703,16 +1703,15 @@ typedef struct AlterTableSpaceOptionsStmt ...@@ -1703,16 +1703,15 @@ typedef struct AlterTableSpaceOptionsStmt
bool isReset; bool isReset;
} AlterTableSpaceOptionsStmt; } AlterTableSpaceOptionsStmt;
typedef struct AlterTableSpaceMoveStmt typedef struct AlterTableMoveAllStmt
{ {
NodeTag type; NodeTag type;
char *orig_tablespacename; char *orig_tablespacename;
ObjectType objtype; /* set to -1 if move_all is true */ ObjectType objtype; /* Object type to move */
bool move_all; /* move all, or just objtype objects? */
List *roles; /* List of roles to move objects of */ List *roles; /* List of roles to move objects of */
char *new_tablespacename; char *new_tablespacename;
bool nowait; bool nowait;
} AlterTableSpaceMoveStmt; } AlterTableMoveAllStmt;
/* ---------------------- /* ----------------------
* Create/Alter Extension Statements * Create/Alter Extension Statements
......
...@@ -76,10 +76,11 @@ CREATE TABLE tablespace_table (i int) TABLESPACE testspace; -- fail ...@@ -76,10 +76,11 @@ CREATE TABLE tablespace_table (i int) TABLESPACE testspace; -- fail
ALTER TABLESPACE testspace RENAME TO testspace_renamed; 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 -- 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 -- Should succeed
DROP TABLESPACE testspace_renamed; DROP TABLESPACE testspace_renamed;
......
...@@ -93,9 +93,10 @@ CREATE TABLE tablespace_table (i int) TABLESPACE testspace; -- fail ...@@ -93,9 +93,10 @@ CREATE TABLE tablespace_table (i int) TABLESPACE testspace; -- fail
ERROR: permission denied for tablespace testspace ERROR: permission denied for tablespace testspace
\c - \c -
ALTER TABLESPACE testspace RENAME TO testspace_renamed; 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 -- 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 NOTICE: no matching relations in tablespace "testspace_renamed" found
-- Should succeed -- Should succeed
DROP TABLESPACE testspace_renamed; DROP TABLESPACE testspace_renamed;
......
...@@ -77,7 +77,7 @@ AlterSystemStmt ...@@ -77,7 +77,7 @@ AlterSystemStmt
AlterTSConfigurationStmt AlterTSConfigurationStmt
AlterTSDictionaryStmt AlterTSDictionaryStmt
AlterTableCmd AlterTableCmd
AlterTableSpaceMoveStmt AlterTableMoveAllStmt
AlterTableSpaceOptionsStmt AlterTableSpaceOptionsStmt
AlterTableStmt AlterTableStmt
AlterTableType AlterTableType
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment