ALTER TABLESPACE MOVE command tag tweak
The ALTER TABLESPACE MOVE command affects tables, not tablespaces; and
as such, I think event triggers should support that command. I'm not
proposing to change event triggers at this stage, but since IMO we will
want to do that in 9.5, we need it to have a different command tag than
plain ALTER TABLESPACE. This is so that check_ddl_tag() can compare
the tag with ALTER TABLESPACE and say "unsupported", and ALTER
TABLESPACE MOVE and say "supported". Both are currently spelled the
same, which will be a problem.
Therefore I propose the attached patch for 9.4.
--
�lvaro Herrera http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services
Attachments:
tblspc-move-tag.patchtext/x-diff; charset=us-asciiDownload
diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c
index 3423898..5553221 100644
--- a/src/backend/tcop/utility.c
+++ b/src/backend/tcop/utility.c
@@ -1806,7 +1805,7 @@ CreateCommandTag(Node *parsetree)
break;
case T_AlterTableSpaceMoveStmt:
- tag = "ALTER TABLESPACE";
+ tag = "ALTER TABLESPACE MOVE";
break;
case T_CreateExtensionStmt:
Alvaro Herrera <alvherre@2ndquadrant.com> writes:
The ALTER TABLESPACE MOVE command affects tables, not tablespaces; and
as such, I think event triggers should support that command. I'm not
proposing to change event triggers at this stage, but since IMO we will
want to do that in 9.5, we need it to have a different command tag than
plain ALTER TABLESPACE. This is so that check_ddl_tag() can compare
the tag with ALTER TABLESPACE and say "unsupported", and ALTER
TABLESPACE MOVE and say "supported". Both are currently spelled the
same, which will be a problem.
Therefore I propose the attached patch for 9.4.
Hm. While the specific change here seems harmless enough, the argument
for it seems to me to indicate that the very design is broken. Do you
expect event triggers to distinguish all the different subflavors of
ALTER TABLE, for example, on the basis of the command tag? Backwards
compatibility is going to prevent us from refining the tag strings
that much. So ISTM this concern means what we'd better be thinking
about is some other way for event triggers to find out what they're
dealing with.
A different thought is that what event triggers would probably like
is for this command to be reported to them as a series of
ALTER TABLE SET TABLESPACE events, one per moved table. If it's
done like that then the tag for the outer ALTER TABLESPACE may not
be so important.
regards, tom lane
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
Tom Lane wrote:
Alvaro Herrera <alvherre@2ndquadrant.com> writes:
The ALTER TABLESPACE MOVE command affects tables, not tablespaces; and
as such, I think event triggers should support that command. I'm not
proposing to change event triggers at this stage, but since IMO we will
want to do that in 9.5, we need it to have a different command tag than
plain ALTER TABLESPACE. This is so that check_ddl_tag() can compare
the tag with ALTER TABLESPACE and say "unsupported", and ALTER
TABLESPACE MOVE and say "supported". Both are currently spelled the
same, which will be a problem.Therefore I propose the attached patch for 9.4.
Hm. While the specific change here seems harmless enough, the argument
for it seems to me to indicate that the very design is broken. Do you
expect event triggers to distinguish all the different subflavors of
ALTER TABLE, for example, on the basis of the command tag? Backwards
compatibility is going to prevent us from refining the tag strings
that much.
Actually, I don't -- I have already implemented ALTER TABLE for event
triggers, and there wasn't any need to tweak the command tags there.
The problem in this particular case is that TABLESPACE is a "global"
object, thus not supported; but ALTER TABLESPACE MOVE is a command that
modifies tables (which *are* supported), not tablespaces.
ALTER TABLESPACE MOVE is a glorified ALTER TABLE. If ALTER TABLESPACE
MOVE returned ALTER TABLE as a tag, I think it'd work well too; but not
ALTER TABLESPACE. Individually, since the implementation works by
calling AlterTableInternal(), it already works.
Now if you state that the current design in event_triggers that works by
slicing CommandTag and comparing the pieces is broken, I don't disagree
and I think I have now (in the patch posted in a nearby thread) some
more infrastructure to do it differently. But even if we do that, I
think we're going to need a way to differentiate ALTER TABLESPACE MOVE
from other forms of ALTER TABLESPACE. I haven't given this much
thought, though.
--
�lvaro Herrera http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
Alvaro Herrera <alvherre@2ndquadrant.com> writes:
The problem in this particular case is that TABLESPACE is a "global"
object, thus not supported; but ALTER TABLESPACE MOVE is a command that
modifies tables (which *are* supported), not tablespaces.
ALTER TABLESPACE MOVE is a glorified ALTER TABLE. If ALTER TABLESPACE
MOVE returned ALTER TABLE as a tag, I think it'd work well too; but not
ALTER TABLESPACE. Individually, since the implementation works by
calling AlterTableInternal(), it already works.
Now if you state that the current design in event_triggers that works by
slicing CommandTag and comparing the pieces is broken, I don't disagree
and I think I have now (in the patch posted in a nearby thread) some
more infrastructure to do it differently. But even if we do that, I
think we're going to need a way to differentiate ALTER TABLESPACE MOVE
from other forms of ALTER TABLESPACE. I haven't given this much
thought, though.
Yeah, I'd not paid much attention to it either. Now that I look at it,
ALTER TABLESPACE MOVE seems like a pretty unfortunate choice of naming
all around, because (unless I'm misunderstanding) it doesn't actually
alter any property of the tablespace itself. It might be a bit late
to propose this, but I wonder if some syntax along the lines of
MOVE ALL [ TABLES | INDEXES | ... ] IN TABLESPACE foo TO bar
wouldn't be less confusing. Not sure what we'd use as command tag
for it though (not MOVE, since that's taken).
regards, tom lane
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
* Tom Lane (tgl@sss.pgh.pa.us) wrote:
Alvaro Herrera <alvherre@2ndquadrant.com> writes:
ALTER TABLESPACE MOVE is a glorified ALTER TABLE. If ALTER TABLESPACE
MOVE returned ALTER TABLE as a tag, I think it'd work well too; but not
ALTER TABLESPACE. Individually, since the implementation works by
calling AlterTableInternal(), it already works.Now if you state that the current design in event_triggers that works by
slicing CommandTag and comparing the pieces is broken, I don't disagree
and I think I have now (in the patch posted in a nearby thread) some
more infrastructure to do it differently. But even if we do that, I
think we're going to need a way to differentiate ALTER TABLESPACE MOVE
from other forms of ALTER TABLESPACE. I haven't given this much
thought, though.Yeah, I'd not paid much attention to it either. Now that I look at it,
ALTER TABLESPACE MOVE seems like a pretty unfortunate choice of naming
all around, because (unless I'm misunderstanding) it doesn't actually
alter any property of the tablespace itself. It might be a bit late
to propose this, but I wonder if some syntax along the lines of
I'm not against changing it- doing operations on a whole tablespace felt
like it would make sense under 'ALTER TABLESPACE' to me (hence the
implementation) but you're right, it's not actually changing properties
of the tablespaces themselves.
MOVE ALL [ TABLES | INDEXES | ... ] IN TABLESPACE foo TO bar
I'm not a huge fan of new top-level constructs and re-using MOVE feels
completely wrong to me as that's used for cursors..
wouldn't be less confusing. Not sure what we'd use as command tag
for it though (not MOVE, since that's taken).
I would have thought something under ALTER TABLE would make more sense,
if we're going to change it, eg:
ALTER TABLE ALL [ TABLES | INDEXES | ... ] IN TABLESPACE SET TABLESPACE ...
or perhaps something like
ALTER TABLES IN TABLESPACE ...
Thanks,
Stephen
All,
* Stephen Frost (sfrost@snowman.net) wrote:
* Tom Lane (tgl@sss.pgh.pa.us) wrote:
Alvaro Herrera <alvherre@2ndquadrant.com> writes:
ALTER TABLESPACE MOVE is a glorified ALTER TABLE. If ALTER TABLESPACE
MOVE returned ALTER TABLE as a tag, I think it'd work well too; but not
ALTER TABLESPACE. Individually, since the implementation works by
calling AlterTableInternal(), it already works.Now if you state that the current design in event_triggers that works by
slicing CommandTag and comparing the pieces is broken, I don't disagree
and I think I have now (in the patch posted in a nearby thread) some
more infrastructure to do it differently. But even if we do that, I
think we're going to need a way to differentiate ALTER TABLESPACE MOVE
from other forms of ALTER TABLESPACE. I haven't given this much
thought, though.Yeah, I'd not paid much attention to it either. Now that I look at it,
ALTER TABLESPACE MOVE seems like a pretty unfortunate choice of naming
all around, because (unless I'm misunderstanding) it doesn't actually
alter any property of the tablespace itself. It might be a bit late
to propose this, but I wonder if some syntax along the lines ofI'm not against changing it- doing operations on a whole tablespace felt
like it would make sense under 'ALTER TABLESPACE' to me (hence the
implementation) but you're right, it's not actually changing properties
of the tablespaces themselves.MOVE ALL [ TABLES | INDEXES | ... ] IN TABLESPACE foo TO bar
I'm not a huge fan of new top-level constructs and re-using MOVE feels
completely wrong to me as that's used for cursors..wouldn't be less confusing. Not sure what we'd use as command tag
for it though (not MOVE, since that's taken).I would have thought something under ALTER TABLE would make more sense,
if we're going to change it, eg:ALTER TABLE ALL [ TABLES | INDEXES | ... ] IN TABLESPACE SET TABLESPACE ...
or perhaps something like
ALTER TABLES IN TABLESPACE ...
Any further thoughts on this? I haven't tried to go implement anything
yet but I'm definitely concerned that we may run into a keyword issue
with ALTER TABLE, but I don't really want to add 'TABLES' either.
Anyone have any other suggestions or ideas?
Thanks,
Stephen
Stephen Frost wrote:
Any further thoughts on this? I haven't tried to go implement anything
yet but I'm definitely concerned that we may run into a keyword issue
with ALTER TABLE, but I don't really want to add 'TABLES' either.
Anyone have any other suggestions or ideas?
I thought that the suggestion to use MOVE was the most appropriate.
However I also concur that re-using MOVE from its current cursor-related
meaning would be troublesome from several PoVs, so if there's a synonym
of MOVE that we can use, that'd probably be better. I don't like ALTER
TABLES myself; and having an ALTER TABLE command that affects several
tables seems counterintuitive as well.
How about
RELOCATE ALL [ TABLES | INDEXES | ... ] IN TABLESPACE foo TO bar
?
--
�lvaro Herrera http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
* Alvaro Herrera (alvherre@2ndquadrant.com) wrote:
Stephen Frost wrote:
Any further thoughts on this? I haven't tried to go implement anything
yet but I'm definitely concerned that we may run into a keyword issue
with ALTER TABLE, but I don't really want to add 'TABLES' either.
Anyone have any other suggestions or ideas?I thought that the suggestion to use MOVE was the most appropriate.
However I also concur that re-using MOVE from its current cursor-related
meaning would be troublesome from several PoVs, so if there's a synonym
of MOVE that we can use, that'd probably be better. I don't like ALTER
TABLES myself; and having an ALTER TABLE command that affects several
tables seems counterintuitive as well.How about
RELOCATE ALL [ TABLES | INDEXES | ... ] IN TABLESPACE foo TO bar
?
The original call for this change was to have it return the command tag
of ALTER TABLE, wasn't it? Would inventing a new command tag like
RELOCATE actually improve the situation..? Or is the thought that it'd
still be ALTER TABLE?
That it's more-or-less a bulk 'ALTER TABLE' operation is why I had been
trying to think of a way to put it under that command. What if we had a
more general way to reference 'all objects in a tablespace'?
"tablespace.*" or "ALL:TABLESAPCE"? Are there other places which might
benefit from being able to take and operate on all objects in a
tablespace?
Of course, we handle this in 'GRANT' with 'GRANT ON ALL TABLES', so why
not 'ALTER TABLE ON ALL TABLES IN TABLESPACE <blah>'? that does get
pretty darn verbose but is at least a bit more in-line with what we have
done before..
Thanks,
Stephen
Stephen Frost <sfrost@snowman.net> writes:
That it's more-or-less a bulk 'ALTER TABLE' operation is why I had been
trying to think of a way to put it under that command. What if we had a
more general way to reference 'all objects in a tablespace'?
"tablespace.*" or "ALL:TABLESAPCE"? Are there other places which might
benefit from being able to take and operate on all objects in a
tablespace?
Of course, we handle this in 'GRANT' with 'GRANT ON ALL TABLES', so why
not 'ALTER TABLE ON ALL TABLES IN TABLESPACE <blah>'? that does get
pretty darn verbose but is at least a bit more in-line with what we have
done before..
That's not a bad line of thought --- I doubt that verbosity is critical
here.
regards, tom lane
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
Tom Lane wrote:
Stephen Frost <sfrost@snowman.net> writes:
That it's more-or-less a bulk 'ALTER TABLE' operation is why I had been
trying to think of a way to put it under that command. What if we had a
more general way to reference 'all objects in a tablespace'?
"tablespace.*" or "ALL:TABLESAPCE"? Are there other places which might
benefit from being able to take and operate on all objects in a
tablespace?Of course, we handle this in 'GRANT' with 'GRANT ON ALL TABLES', so why
not 'ALTER TABLE ON ALL TABLES IN TABLESPACE <blah>'? that does get
pretty darn verbose but is at least a bit more in-line with what we have
done before..That's not a bad line of thought --- I doubt that verbosity is critical
here.
Yep, that works for my purposes. Also, it seems there should be no
parse conflict because ON is already a reserved keyword ..
--
�lvaro Herrera http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On Mon, Jun 23, 2014 at 05:10:02PM -0400, Stephen Frost wrote:
* Stephen Frost (sfrost@snowman.net) wrote:
* Tom Lane (tgl@sss.pgh.pa.us) wrote:
I'm not against changing it- doing operations on a whole tablespace felt
like it would make sense under 'ALTER TABLESPACE' to me (hence the
implementation) but you're right, it's not actually changing properties
of the tablespaces themselves.MOVE ALL [ TABLES | INDEXES | ... ] IN TABLESPACE foo TO bar
I'm not a huge fan of new top-level constructs and re-using MOVE feels
completely wrong to me as that's used for cursors..wouldn't be less confusing. Not sure what we'd use as command tag
for it though (not MOVE, since that's taken).I would have thought something under ALTER TABLE would make more sense,
if we're going to change it, eg:ALTER TABLE ALL [ TABLES | INDEXES | ... ] IN TABLESPACE SET TABLESPACE ...
or perhaps something like
ALTER TABLES IN TABLESPACE ...
Any further thoughts on this? I haven't tried to go implement anything
yet but I'm definitely concerned that we may run into a keyword issue
with ALTER TABLE, but I don't really want to add 'TABLES' either.
Anyone have any other suggestions or ideas?
I recommend:
SELECT tablespace_move(old_tablespace name, new_tablespace name);
SELECT tablespace_move(old_tablespace name, new_tablespace name, relkind "char");
Concerning the problem that started this thread, I would raise one ALTER TABLE
event per table and not fire an event for the bulk request as a whole.
--
Noah Misch
EnterpriseDB http://www.enterprisedb.com
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
Noah Misch wrote:
Concerning the problem that started this thread, I would raise one ALTER TABLE
event per table and not fire an event for the bulk request as a whole.
Yes, that's how it already works. Essentially, ALTER TABLESPACE MOVE
calls AlterTableInternal, and that function calls one ATExecFoo() for
each table to be moved. What my code does is set up "AT event
collection" when ALTER TABLESPACE MOVE is called, and then for each
ATExecFoo() is executed, one event is added to a queue. When ALTER
TABLESPACE MOVE finishes, all those events are reported together. This
part is not a problem. The only part that is a problem is that the
CommandTag comparison in event_trigger.c wasn't happy that a command was
being passed with the ALTER TABLESPACE command tag, because tablespaces
are not supported by that module --- and I think the unhappiness was
only in an assert-only block (but I'm not 100% sure about that last bit,
because I didn't try removing that test.)
--
�lvaro Herrera http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
* Tom Lane (tgl@sss.pgh.pa.us) wrote:
Stephen Frost <sfrost@snowman.net> writes:
That it's more-or-less a bulk 'ALTER TABLE' operation is why I had been
trying to think of a way to put it under that command. What if we had a
more general way to reference 'all objects in a tablespace'?
"tablespace.*" or "ALL:TABLESAPCE"? Are there other places which might
benefit from being able to take and operate on all objects in a
tablespace?Of course, we handle this in 'GRANT' with 'GRANT ON ALL TABLES', so why
not 'ALTER TABLE ON ALL TABLES IN TABLESPACE <blah>'? that does get
pretty darn verbose but is at least a bit more in-line with what we have
done before..That's not a bad line of thought --- I doubt that verbosity is critical
here.
Alright, sounds like this is more-or-less the concensus. I'll see about
making it happen shortly.
Thanks!
Stephen
Stephen Frost wrote:
* Tom Lane (tgl@sss.pgh.pa.us) wrote:
Stephen Frost <sfrost@snowman.net> writes:
That it's more-or-less a bulk 'ALTER TABLE' operation is why I had been
trying to think of a way to put it under that command. What if we had a
more general way to reference 'all objects in a tablespace'?
"tablespace.*" or "ALL:TABLESAPCE"? Are there other places which might
benefit from being able to take and operate on all objects in a
tablespace?Of course, we handle this in 'GRANT' with 'GRANT ON ALL TABLES', so why
not 'ALTER TABLE ON ALL TABLES IN TABLESPACE <blah>'? that does get
pretty darn verbose but is at least a bit more in-line with what we have
done before..That's not a bad line of thought --- I doubt that verbosity is critical
here.Alright, sounds like this is more-or-less the concensus. I'll see about
making it happen shortly.
Stephen,
Were you able to work on this?
Can you be more specific on the exact grammar you're considering? The
proposal above,
ALTER TABLE ON ALL TABLES IN TABLESPACE xyz
doesn't seem very good to me. I would think it'd be more like
ALTER ALL TABLES IN TABLESPACE xyz
but then if you return ALTER TABLE as a command tag that might be a bit
strange. Maybe
ALTER TABLE ALL IN TABLESPACE xyz
which AFAICS should work since ALL is already a reserved keyword.
Also, how would we document this? Would we have it in the same page as
all the ALTER TABLE variants, or would we create a separate page for
ALTER TABLE ALL? Keeping in mind that in the future we might want to
allow things such as ALTER TABLE ALL IN SCHEMA xyz it might be better to
have the selection logic documented neatly in its own little page
instead of together with the ALTER TABLE mess which is already rather
large.
--
�lvaro Herrera http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
Alvaro,
* Alvaro Herrera (alvherre@2ndquadrant.com) wrote:
Stephen Frost wrote:
Of course, we handle this in 'GRANT' with 'GRANT ON ALL TABLES', so why
not 'ALTER TABLE ON ALL TABLES IN TABLESPACE <blah>'? that does get
pretty darn verbose but is at least a bit more in-line with what we have
done before..That's not a bad line of thought --- I doubt that verbosity is critical
here.Alright, sounds like this is more-or-less the concensus. I'll see about
making it happen shortly.Were you able to work on this?
Apologies, I've been gone more-or-less all of July. I'm back now and
have time to spend on this.
Can you be more specific on the exact grammar you're considering? The
proposal above,
ALTER TABLE ON ALL TABLES IN TABLESPACE xyz
doesn't seem very good to me. I would think it'd be more like
ALTER ALL TABLES IN TABLESPACE xyz
but then if you return ALTER TABLE as a command tag that might be a bit
strange. Maybe
ALTER TABLE ALL IN TABLESPACE xyz
which AFAICS should work since ALL is already a reserved keyword.
Interesting idea. I wonder if we might apply that to other capabilities
of ALTER TABLE too.. That is, make it a generic way to specify that all
tables in the tablespace (or schema..?) should be modified in a certain
way. We'd have to consider which of the ALTER TABLE operations this
would work for, of course. I don't believe it'd make sense for any of
the 'ADD/DROP COLUMN' or similar commands, but 'OWNER TO' would make
sense...
I'm not sure how much we want to work this over during beta though.. My
original thought was just to adjust the grammar and hopefully minimize
the other changes in this area, but it'd be good to have an idea about
where we want to take this, so the grammar can support the future
capabilities while not actually adding them at this time.
Also, how would we document this? Would we have it in the same page as
all the ALTER TABLE variants, or would we create a separate page for
ALTER TABLE ALL? Keeping in mind that in the future we might want to
allow things such as ALTER TABLE ALL IN SCHEMA xyz it might be better to
have the selection logic documented neatly in its own little page
instead of together with the ALTER TABLE mess which is already rather
large.
I would think we'd simply use the ALTER TABLE page as I don't think the
documentation of this would be all that difficult to describe in a
reasonable paragraph. A page dedicated to it feels like overkill, but
perhaps that might change as we add more.
Other thoughts on this? We should really get any of the changes we're
doing here done soon.
Thanks,
Stephen
Stephen Frost wrote:
* Alvaro Herrera (alvherre@2ndquadrant.com) wrote:
Stephen Frost wrote:
Alright, sounds like this is more-or-less the concensus. I'll see about
making it happen shortly.Were you able to work on this?
Apologies, I've been gone more-or-less all of July. I'm back now and
have time to spend on this.
Ping?
--
�lvaro Herrera http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On Wed, Aug 13, 2014 at 9:33 AM, Alvaro Herrera
<alvherre@2ndquadrant.com> wrote:
Stephen Frost wrote:
* Alvaro Herrera (alvherre@2ndquadrant.com) wrote:
Stephen Frost wrote:
Alright, sounds like this is more-or-less the concensus. I'll see about
making it happen shortly.Were you able to work on this?
Apologies, I've been gone more-or-less all of July. I'm back now and
have time to spend on this.Ping?
Seriously!
We really should not be making changes of this type less than a month
from our ostensible release date. That is not enough time for us to
notice if the changes turn out to be not as good as we think they are.
The whole point of beta is to fix things while there's still enough
time for further course correction if needed; if we say, oh, beta's
not totally over yet, I don't have to get my changes in, then it
completely defeats the purpose of having a beta in the first place.
</rant>
--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
Robert Haas <robertmhaas@gmail.com> writes:
We really should not be making changes of this type less than a month
from our ostensible release date. That is not enough time for us to
notice if the changes turn out to be not as good as we think they are.
If it weren't for the fact that we'll be wedded forevermore to a bad
choice of syntax, I might agree with you. But at this point, the
alternatives we have are to fix it now, or fix it never. I don't
like #2.
regards, tom lane
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
* Tom Lane (tgl@sss.pgh.pa.us) wrote:
Robert Haas <robertmhaas@gmail.com> writes:
We really should not be making changes of this type less than a month
from our ostensible release date. That is not enough time for us to
notice if the changes turn out to be not as good as we think they are.If it weren't for the fact that we'll be wedded forevermore to a bad
choice of syntax, I might agree with you. But at this point, the
alternatives we have are to fix it now, or fix it never. I don't
like #2.
I'm planning to fix it shortly, as I mentioned to Alvaro on IRC when I
saw his note.
Thanks,
Stephen
On Thu, Aug 14, 2014 at 6:12 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote:
Robert Haas <robertmhaas@gmail.com> writes:
We really should not be making changes of this type less than a month
from our ostensible release date. That is not enough time for us to
notice if the changes turn out to be not as good as we think they are.If it weren't for the fact that we'll be wedded forevermore to a bad
choice of syntax, I might agree with you. But at this point, the
alternatives we have are to fix it now, or fix it never. I don't
like #2.
Or postpone the release for another month or two. There's still a few
other unresolved issues, too, like the problems with psql and expanded
mode; and the JSONB toast problems. The latter is relatively new, but
we don't have a proposed patch for it yet unless there's on in an
email I haven't read yet, and the former has been lingering for many
months without getting appreciably closer to a resolution.
I like releasing in September as much as anyone, but that contemplates
people taking care to get known issues fixed before the second half of
August.
--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
Robert Haas <robertmhaas@gmail.com> writes:
On Thu, Aug 14, 2014 at 6:12 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote:
If it weren't for the fact that we'll be wedded forevermore to a bad
choice of syntax, I might agree with you. But at this point, the
alternatives we have are to fix it now, or fix it never. I don't
like #2.
Or postpone the release for another month or two. There's still a few
other unresolved issues, too, like the problems with psql and expanded
mode; and the JSONB toast problems. The latter is relatively new, but
we don't have a proposed patch for it yet unless there's on in an
email I haven't read yet, and the former has been lingering for many
months without getting appreciably closer to a resolution.
Yeah, if we do anything about JSONB we are certainly going to need another
beta release, which means final couldn't be before end of Sept. at the
very earliest. Still, it's always been project policy that we ship when
it's ready, not when the calendar hits some particular point.
As for the expanded-mode changes, I thought there was consensus to
revert that from 9.4.
regards, tom lane
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On Fri, Aug 15, 2014 at 9:57 AM, Tom Lane <tgl@sss.pgh.pa.us> wrote:
Robert Haas <robertmhaas@gmail.com> writes:
On Thu, Aug 14, 2014 at 6:12 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote:
If it weren't for the fact that we'll be wedded forevermore to a bad
choice of syntax, I might agree with you. But at this point, the
alternatives we have are to fix it now, or fix it never. I don't
like #2.Or postpone the release for another month or two. There's still a few
other unresolved issues, too, like the problems with psql and expanded
mode; and the JSONB toast problems. The latter is relatively new, but
we don't have a proposed patch for it yet unless there's on in an
email I haven't read yet, and the former has been lingering for many
months without getting appreciably closer to a resolution.Yeah, if we do anything about JSONB we are certainly going to need another
beta release, which means final couldn't be before end of Sept. at the
very earliest. Still, it's always been project policy that we ship when
it's ready, not when the calendar hits some particular point.
Absolutely.
As for the expanded-mode changes, I thought there was consensus to
revert that from 9.4.
Me too. In fact, I think that's been the consensus for many months,
but unless I'm mistaken it ain't done.
--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
Alvaro, all,
* Alvaro Herrera (alvherre@2ndquadrant.com) wrote:
Can you be more specific on the exact grammar you're considering? The
proposal above,
ALTER TABLE ON ALL TABLES IN TABLESPACE xyz
doesn't seem very good to me. I would think it'd be more like
ALTER ALL TABLES IN TABLESPACE xyz
but then if you return ALTER TABLE as a command tag that might be a bit
strange. Maybe
ALTER TABLE ALL IN TABLESPACE xyz
which AFAICS should work since ALL is already a reserved keyword.
I've implemented the 'ALTER TABLE ALL IN TABLESPACE ...' appproach, as
discussed. Patch attached.
Also, how would we document this? Would we have it in the same page as
all the ALTER TABLE variants, or would we create a separate page for
ALTER TABLE ALL? Keeping in mind that in the future we might want to
allow things such as ALTER TABLE ALL IN SCHEMA xyz it might be better to
have the selection logic documented neatly in its own little page
instead of together with the ALTER TABLE mess which is already rather
large.
As mentioned, I'll add this to the ALTER TABLE documentation and remove
it from the TABLESPACE docs. That's not done yet but I should have time
in the next few days to get that done also and will then commit it all
to master and back-patch to 9.4, barring objections.
Thanks,
Stephen
Attachments:
atm_change.patchtext/x-diff; charset=us-asciiDownload
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index c86b999..feceed7 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -50,6 +50,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)
}
/*
+ * 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 031be37..28e69a5 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 3088578..f5ddc1c 100644
--- a/src/backend/nodes/copyfuncs.c
+++ b/src/backend/nodes/copyfuncs.c
@@ -3415,14 +3415,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);
@@ -4456,8 +4455,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 1b07db6..ccd6064 100644
--- a/src/backend/nodes/equalfuncs.c
+++ b/src/backend/nodes/equalfuncs.c
@@ -1639,12 +1639,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);
@@ -2920,8 +2919,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 a113809..4950943 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -1763,6 +1763,28 @@ AlterTableStmt:
n->missing_ok = true;
$$ = (Node *)n;
}
+ | ALTER TABLE ALL IN_P TABLESPACE name SET TABLESPACE TO name opt_nowait
+ {
+ AlterTableMoveAllStmt *n =
+ makeNode(AlterTableMoveAllStmt);
+ n->orig_tablespacename = $6;
+ n->objtype = OBJECT_TABLE;
+ n->roles = NIL;
+ n->new_tablespacename = $10;
+ n->nowait = $11;
+ $$ = (Node *)n;
+ }
+ | ALTER TABLE ALL IN_P TABLESPACE name OWNED BY role_list SET TABLESPACE TO name opt_nowait
+ {
+ AlterTableMoveAllStmt *n =
+ makeNode(AlterTableMoveAllStmt);
+ n->orig_tablespacename = $6;
+ n->objtype = OBJECT_TABLE;
+ n->roles = $9;
+ n->new_tablespacename = $13;
+ n->nowait = $14;
+ $$ = (Node *)n;
+ }
| ALTER INDEX qualified_name alter_table_cmds
{
AlterTableStmt *n = makeNode(AlterTableStmt);
@@ -1781,6 +1803,28 @@ AlterTableStmt:
n->missing_ok = true;
$$ = (Node *)n;
}
+ | ALTER INDEX ALL IN_P TABLESPACE name SET TABLESPACE TO name opt_nowait
+ {
+ AlterTableMoveAllStmt *n =
+ makeNode(AlterTableMoveAllStmt);
+ n->orig_tablespacename = $6;
+ n->objtype = OBJECT_INDEX;
+ n->roles = NIL;
+ n->new_tablespacename = $10;
+ n->nowait = $11;
+ $$ = (Node *)n;
+ }
+ | ALTER INDEX ALL IN_P TABLESPACE name OWNED BY role_list SET TABLESPACE TO name opt_nowait
+ {
+ AlterTableMoveAllStmt *n =
+ makeNode(AlterTableMoveAllStmt);
+ n->orig_tablespacename = $6;
+ n->objtype = OBJECT_INDEX;
+ n->roles = $9;
+ n->new_tablespacename = $13;
+ n->nowait = $14;
+ $$ = (Node *)n;
+ }
| ALTER SEQUENCE qualified_name alter_table_cmds
{
AlterTableStmt *n = makeNode(AlterTableStmt);
@@ -1835,6 +1879,28 @@ AlterTableStmt:
n->missing_ok = true;
$$ = (Node *)n;
}
+ | ALTER MATERIALIZED VIEW ALL IN_P TABLESPACE name SET TABLESPACE TO name opt_nowait
+ {
+ AlterTableMoveAllStmt *n =
+ makeNode(AlterTableMoveAllStmt);
+ n->orig_tablespacename = $7;
+ n->objtype = OBJECT_MATVIEW;
+ n->roles = NIL;
+ n->new_tablespacename = $11;
+ n->nowait = $12;
+ $$ = (Node *)n;
+ }
+ | ALTER MATERIALIZED VIEW ALL IN_P TABLESPACE name OWNED BY role_list SET TABLESPACE TO name opt_nowait
+ {
+ AlterTableMoveAllStmt *n =
+ makeNode(AlterTableMoveAllStmt);
+ n->orig_tablespacename = $7;
+ n->objtype = OBJECT_MATVIEW;
+ n->roles = $10;
+ n->new_tablespacename = $14;
+ n->nowait = $15;
+ $$ = (Node *)n;
+ }
;
alter_table_cmds:
@@ -7002,103 +7068,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 07e0b98..f648945 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_ImportForeignSchemaStmt:
case T_SecLabelStmt:
@@ -507,9 +507,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:
@@ -1810,10 +1809,6 @@ CreateCommandTag(Node *parsetree)
tag = "ALTER TABLESPACE";
break;
- case T_AlterTableSpaceMoveStmt:
- tag = "ALTER TABLESPACE";
- break;
-
case T_CreateExtensionStmt:
tag = "CREATE EXTENSION";
break;
@@ -1982,6 +1977,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;
@@ -2510,10 +2509,6 @@ GetCommandLogLevel(Node *parsetree)
lev = LOGSTMT_DDL;
break;
- case T_AlterTableSpaceMoveStmt:
- lev = LOGSTMT_DDL;
- break;
-
case T_CreateExtensionStmt:
case T_AlterExtensionStmt:
case T_AlterExtensionContentsStmt:
@@ -2593,6 +2588,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 e55f45a..932322f 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 073cb0d..d01ae8b 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 067c768..a031b88 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_ImportForeignSchemaStmt,
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index 8364bef..f6ccdcd 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -1703,16 +1703,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 6015228..975a95b 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 TO pg_default;
+ALTER INDEX ALL IN TABLESPACE testspace_renamed SET TABLESPACE TO 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 TO 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 27bc491..3995ee9 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 TO pg_default;
+ALTER INDEX ALL IN TABLESPACE testspace_renamed SET TABLESPACE TO 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 TO 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 913d6ef..ab36aa3 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
Alvaro, all,
* Stephen Frost (sfrost@snowman.net) wrote:
As mentioned, I'll add this to the ALTER TABLE documentation and remove
it from the TABLESPACE docs. That's not done yet but I should have time
in the next few days to get that done also and will then commit it all
to master and back-patch to 9.4, barring objections.
Here's a first pass with the documentation changes included. Feedback
welcome, and I'll review it again and plan to commit it on Tuesday.
Thanks,
Stephen
Attachments:
atm_change_with_doc.patchtext/x-diff; charset=us-asciiDownload
diff --git a/doc/src/sgml/ref/alter_index.sgml b/doc/src/sgml/ref/alter_index.sgml
index 94a7af0..85159a0 100644
--- a/doc/src/sgml/ref/alter_index.sgml
+++ b/doc/src/sgml/ref/alter_index.sgml
@@ -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 ( <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 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>
</refsynopsisdiv>
@@ -63,6 +65,17 @@ ALTER INDEX [ IF EXISTS ] <replaceable class="PARAMETER">name</replaceable> RESE
<para>
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
+ <literal>CREATE</literal> privilege on the new tablespace.
+ All indexes 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
<xref linkend="SQL-CREATETABLESPACE">.
</para>
diff --git a/doc/src/sgml/ref/alter_materialized_view.sgml b/doc/src/sgml/ref/alter_materialized_view.sgml
index 1932eeb..b0759fc 100644
--- a/doc/src/sgml/ref/alter_materialized_view.sgml
+++ b/doc/src/sgml/ref/alter_materialized_view.sgml
@@ -29,6 +29,8 @@ ALTER MATERIALIZED VIEW [ IF EXISTS ] <replaceable class="parameter">name</repla
RENAME TO <replaceable class="parameter">new_name</replaceable>
ALTER MATERIALIZED VIEW [ IF EXISTS ] <replaceable class="parameter">name</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>
diff --git a/doc/src/sgml/ref/alter_table.sgml b/doc/src/sgml/ref/alter_table.sgml
index 69a1e14..83d230c 100644
--- a/doc/src/sgml/ref/alter_table.sgml
+++ b/doc/src/sgml/ref/alter_table.sgml
@@ -31,6 +31,8 @@ ALTER TABLE [ IF EXISTS ] <replaceable class="PARAMETER">name</replaceable>
RENAME TO <replaceable class="PARAMETER">new_name</replaceable>
ALTER TABLE [ IF EXISTS ] <replaceable class="PARAMETER">name</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>
@@ -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.
Indexes on the table, if any, are not moved; but they can be moved
separately with additional <literal>SET TABLESPACE</literal> commands.
+ All tables 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
<xref linkend="SQL-CREATETABLESPACE">.
</para>
@@ -649,7 +662,8 @@ ALTER TABLE [ IF EXISTS ] <replaceable class="PARAMETER">name</replaceable>
</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
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 ] <replaceable class="PARAMETER">name</replaceable>
<para>
You must own the table to use <command>ALTER TABLE</>.
- To change the schema of a table, you must also have
- <literal>CREATE</literal> privilege on the new schema.
+ To change the schema or tablespace of a table, you must also have
+ <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
parent table as well.
To alter the owner, you must also be a direct or indirect member of the new
diff --git a/doc/src/sgml/ref/alter_tablespace.sgml b/doc/src/sgml/ref/alter_tablespace.sgml
index bd1afb4..7c4aabc 100644
--- a/doc/src/sgml/ref/alter_tablespace.sgml
+++ b/doc/src/sgml/ref/alter_tablespace.sgml
@@ -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> 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> MOVE { ALL | TABLES | INDEXES | MATERIALIZED VIEWS } [ OWNED BY <replaceable class="PARAMETER">role_name</replaceable> [, ...] ] TO <replaceable>new_tablespace</replaceable> [ NOWAIT ]
</synopsis>
</refsynopsisdiv>
@@ -45,44 +44,6 @@ ALTER TABLESPACE <replaceable>name</replaceable> MOVE { ALL | TABLES | INDEXES |
(Note that superusers have these privileges automatically.)
</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>
@@ -136,38 +97,6 @@ ALTER TABLESPACE <replaceable>name</replaceable> MOVE { ALL | TABLES | INDEXES |
</listitem>
</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>
</refsect1>
@@ -186,13 +115,6 @@ ALTER TABLESPACE index_space RENAME TO fast_raid;
<programlisting>
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>
</refsect1>
<refsect1>
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index c86b999..feceed7 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -50,6 +50,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)
}
/*
+ * 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 031be37..28e69a5 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 3088578..f5ddc1c 100644
--- a/src/backend/nodes/copyfuncs.c
+++ b/src/backend/nodes/copyfuncs.c
@@ -3415,14 +3415,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);
@@ -4456,8 +4455,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 1b07db6..ccd6064 100644
--- a/src/backend/nodes/equalfuncs.c
+++ b/src/backend/nodes/equalfuncs.c
@@ -1639,12 +1639,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);
@@ -2920,8 +2919,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 a113809..81daba3 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -1763,6 +1763,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);
@@ -1781,6 +1803,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);
@@ -1835,6 +1879,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:
@@ -7002,103 +7068,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 07e0b98..f648945 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_ImportForeignSchemaStmt:
case T_SecLabelStmt:
@@ -507,9 +507,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:
@@ -1810,10 +1809,6 @@ CreateCommandTag(Node *parsetree)
tag = "ALTER TABLESPACE";
break;
- case T_AlterTableSpaceMoveStmt:
- tag = "ALTER TABLESPACE";
- break;
-
case T_CreateExtensionStmt:
tag = "CREATE EXTENSION";
break;
@@ -1982,6 +1977,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;
@@ -2510,10 +2509,6 @@ GetCommandLogLevel(Node *parsetree)
lev = LOGSTMT_DDL;
break;
- case T_AlterTableSpaceMoveStmt:
- lev = LOGSTMT_DDL;
- break;
-
case T_CreateExtensionStmt:
case T_AlterExtensionStmt:
case T_AlterExtensionContentsStmt:
@@ -2593,6 +2588,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 e55f45a..932322f 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 073cb0d..d01ae8b 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 067c768..a031b88 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_ImportForeignSchemaStmt,
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index 8364bef..f6ccdcd 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -1703,16 +1703,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 6015228..e259254 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 27bc491..a306510 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 913d6ef..ab36aa3 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
On 15 Aug 2014 19:06, "Robert Haas" <robertmhaas@gmail.com> wrote:
As for the expanded-mode changes, I thought there was consensus to
revert that from 9.4.Me too. In fact, I think that's been the consensus for many months,
but unless I'm mistaken it ain't done.
Yeah, this is entirely my fault. I was traveling, busy, not feeling well,
in various permutations but I should have gotten to it earlier.
I'll take care of it tomorrow morning.
On 8/17/14 5:19 PM, Stephen Frost wrote:
Alvaro, all,
* Stephen Frost (sfrost@snowman.net) wrote:
As mentioned, I'll add this to the ALTER TABLE documentation and remove
it from the TABLESPACE docs. That's not done yet but I should have time
in the next few days to get that done also and will then commit it all
to master and back-patch to 9.4, barring objections.Here's a first pass with the documentation changes included. Feedback
welcome, and I'll review it again and plan to commit it on Tuesday.
One thing that is not clear from this (before or after) is whether "all
{tables|indexes|etc} in the tablespace" actually means "in this
tablespace and in the current database". Presumably it does.
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
* Peter Eisentraut (peter_e@gmx.net) wrote:
On 8/17/14 5:19 PM, Stephen Frost wrote:
Alvaro, all,
* Stephen Frost (sfrost@snowman.net) wrote:
As mentioned, I'll add this to the ALTER TABLE documentation and remove
it from the TABLESPACE docs. That's not done yet but I should have time
in the next few days to get that done also and will then commit it all
to master and back-patch to 9.4, barring objections.Here's a first pass with the documentation changes included. Feedback
welcome, and I'll review it again and plan to commit it on Tuesday.One thing that is not clear from this (before or after) is whether "all
{tables|indexes|etc} in the tablespace" actually means "in this
tablespace and in the current database". Presumably it does.
Yes, only those in the current database. There was a mention of that in
the original docs. I'll add it to the new ones.
Thanks,
Stephen
Alvaro,
* Alvaro Herrera (alvherre@2ndquadrant.com) wrote:
ALTER TABLE ALL IN TABLESPACE xyz
which AFAICS should work since ALL is already a reserved keyword.
Pushed to master and REL9_4_STABLE. Apologies on it taking so long-
things have a bit "interesting" for me over the past month or two. :)
Thanks!
Stephen
On Fri, Aug 22, 2014 at 8:14 AM, Stephen Frost <sfrost@snowman.net> wrote:
Alvaro,
* Alvaro Herrera (alvherre@2ndquadrant.com) wrote:
ALTER TABLE ALL IN TABLESPACE xyz
which AFAICS should work since ALL is already a reserved keyword.Pushed to master and REL9_4_STABLE.
You seem to have forgotten to update tab-complete.c.
Attached patch updates that.
Regards,
--
Fujii Masao
Attachments:
tab-completion-alter-table-all-set-tablespace_v1.patchtext/x-patch; charset=US-ASCII; name=tab-completion-alter-table-all-set-tablespace_v1.patchDownload
*** a/src/bin/psql/tab-complete.c
--- b/src/bin/psql/tab-complete.c
***************
*** 953,958 **** psql_completion(const char *text, int start, int end)
--- 953,965 ----
/* ALTER */
+ /* ALTER TABLE */
+ else if (pg_strcasecmp(prev2_wd, "ALTER") == 0 &&
+ pg_strcasecmp(prev_wd, "TABLE") == 0)
+ {
+ COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables,
+ "UNION SELECT 'ALL IN TABLESPACE'");
+ }
/*
* complete with what you can alter (TABLE, GROUP, USER, ...) unless we're
* in ALTER TABLE sth ALTER
***************
*** 970,975 **** psql_completion(const char *text, int start, int end)
--- 977,1001 ----
COMPLETE_WITH_LIST(list_ALTER);
}
+ /* ALTER TABLE,INDEX,MATERIALIZED VIEW xxx ALL IN TABLESPACE xxx */
+ else if (pg_strcasecmp(prev4_wd, "ALL") == 0 &&
+ pg_strcasecmp(prev3_wd, "IN") == 0 &&
+ pg_strcasecmp(prev2_wd, "TABLESPACE") == 0)
+ {
+ static const char *const list_ALTERALLINTSPC[] =
+ {"SET TABLESPACE", "OWNED BY", NULL};
+
+ COMPLETE_WITH_LIST(list_ALTERALLINTSPC);
+ }
+ /* ALTER TABLE,INDEX,MATERIALIZED VIEW xxx ALL IN TABLESPACE xxx OWNED BY */
+ else if (pg_strcasecmp(prev6_wd, "ALL") == 0 &&
+ pg_strcasecmp(prev5_wd, "IN") == 0 &&
+ pg_strcasecmp(prev4_wd, "TABLESPACE") == 0 &&
+ pg_strcasecmp(prev2_wd, "OWNED") == 0 &&
+ pg_strcasecmp(prev4_wd, "BY") == 0)
+ {
+ COMPLETE_WITH_QUERY(Query_for_list_of_roles);
+ }
/* ALTER AGGREGATE,FUNCTION <name> */
else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 &&
(pg_strcasecmp(prev2_wd, "AGGREGATE") == 0 ||
***************
*** 1106,1111 **** psql_completion(const char *text, int start, int end)
--- 1132,1144 ----
COMPLETE_WITH_LIST(list_ALTER_FOREIGN_TABLE);
}
+ /* ALTER INDEX */
+ else if (pg_strcasecmp(prev2_wd, "ALTER") == 0 &&
+ pg_strcasecmp(prev_wd, "INDEX") == 0)
+ {
+ COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes,
+ "UNION SELECT 'ALL IN TABLESPACE'");
+ }
/* ALTER INDEX <name> */
else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 &&
pg_strcasecmp(prev2_wd, "INDEX") == 0)
***************
*** 1169,1175 **** psql_completion(const char *text, int start, int end)
pg_strcasecmp(prev2_wd, "MATERIALIZED") == 0 &&
pg_strcasecmp(prev_wd, "VIEW") == 0)
{
! COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_matviews, NULL);
}
/* ALTER USER,ROLE <name> */
--- 1202,1209 ----
pg_strcasecmp(prev2_wd, "MATERIALIZED") == 0 &&
pg_strcasecmp(prev_wd, "VIEW") == 0)
{
! COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_matviews,
! "UNION SELECT 'ALL IN TABLESPACE'");
}
/* ALTER USER,ROLE <name> */
***************
*** 1742,1753 **** psql_completion(const char *text, int start, int end)
COMPLETE_WITH_CONST("IDENTITY");
}
! /* ALTER TABLESPACE <foo> with RENAME TO, OWNER TO, SET, RESET, MOVE */
else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 &&
pg_strcasecmp(prev2_wd, "TABLESPACE") == 0)
{
static const char *const list_ALTERTSPC[] =
! {"RENAME TO", "OWNER TO", "SET", "RESET", "MOVE", NULL};
COMPLETE_WITH_LIST(list_ALTERTSPC);
}
--- 1776,1787 ----
COMPLETE_WITH_CONST("IDENTITY");
}
! /* ALTER TABLESPACE <foo> with RENAME TO, OWNER TO, SET, RESET */
else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 &&
pg_strcasecmp(prev2_wd, "TABLESPACE") == 0)
{
static const char *const list_ALTERTSPC[] =
! {"RENAME TO", "OWNER TO", "SET", "RESET", NULL};
COMPLETE_WITH_LIST(list_ALTERTSPC);
}
***************
*** 1769,1795 **** psql_completion(const char *text, int start, int end)
COMPLETE_WITH_LIST(list_TABLESPACEOPTIONS);
}
- /* ALTER TABLESPACE <foo> MOVE ALL|TABLES|INDEXES|MATERIALIZED VIEWS */
- else if (pg_strcasecmp(prev4_wd, "ALTER") == 0 &&
- pg_strcasecmp(prev3_wd, "TABLESPACE") == 0 &&
- pg_strcasecmp(prev_wd, "MOVE") == 0)
- {
- static const char *const list_TABLESPACEMOVETARGETS[] =
- {"ALL", "TABLES", "INDEXES", "MATERIALIZED VIEWS", NULL};
-
- COMPLETE_WITH_LIST(list_TABLESPACEMOVETARGETS);
- }
- else if ((pg_strcasecmp(prev4_wd, "TABLESPACE") == 0 &&
- pg_strcasecmp(prev2_wd, "MOVE") == 0) ||
- (pg_strcasecmp(prev5_wd, "TABLESPACE") == 0 &&
- pg_strcasecmp(prev3_wd, "MOVE") == 0 &&
- pg_strcasecmp(prev2_wd, "MATERIALIZED") == 0))
- {
- static const char *const list_TABLESPACEMOVEOPTIONS[] =
- {"OWNED BY", "TO", NULL};
-
- COMPLETE_WITH_LIST(list_TABLESPACEMOVEOPTIONS);
- }
/* ALTER TEXT SEARCH */
else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 &&
--- 1803,1808 ----
***************
*** 2791,2799 **** psql_completion(const char *text, int start, int end)
* but we may as well tab-complete both: perhaps some users prefer one
* variant or the other.
*/
! else if ((pg_strcasecmp(prev3_wd, "FETCH") == 0 ||
! pg_strcasecmp(prev3_wd, "MOVE") == 0) &&
! pg_strcasecmp(prev_wd, "TO") != 0)
{
static const char *const list_FROMIN[] =
{"FROM", "IN", NULL};
--- 2804,2811 ----
* but we may as well tab-complete both: perhaps some users prefer one
* variant or the other.
*/
! else if (pg_strcasecmp(prev3_wd, "FETCH") == 0 ||
! pg_strcasecmp(prev3_wd, "MOVE") == 0)
{
static const char *const list_FROMIN[] =
{"FROM", "IN", NULL};
Fujii,
* Fujii Masao (masao.fujii@gmail.com) wrote:
You seem to have forgotten to update tab-complete.c.
Good point, absolutely correct. I have a bad tendency to do that.
Attached patch updates that.
Many thanks, will review and apply soon.
Thanks again!
Stephen
Fujii,
* Fujii Masao (masao.fujii@gmail.com) wrote:
On Fri, Aug 22, 2014 at 8:14 AM, Stephen Frost <sfrost@snowman.net> wrote:
* Alvaro Herrera (alvherre@2ndquadrant.com) wrote:
ALTER TABLE ALL IN TABLESPACE xyz
which AFAICS should work since ALL is already a reserved keyword.Pushed to master and REL9_4_STABLE.
You seem to have forgotten to update tab-complete.c.
Attached patch updates that.
Pushed. Thanks again,
Stephen
Stephen Frost wrote:
Alvaro,
* Alvaro Herrera (alvherre@2ndquadrant.com) wrote:
ALTER TABLE ALL IN TABLESPACE xyz
which AFAICS should work since ALL is already a reserved keyword.Pushed to master and REL9_4_STABLE.
Thanks. One more tweak --- the whole reason for fiddling with this is
to ensure that event triggers support this operation. Therefore this
node should be handled by ProcessUtilitySlow, not
standard_ProcessUtility, as in the attached patch.
(I checked the documentation for necessary updates; turns out that the
table in the event triggers chapter says that ddl_command_end etc
support the command "ALTER TABLE", and since this is the tag returned by
the new ALTER TABLE ALL IN TABLESPACE command, there is no update
needed. In fact, one can argue that the table is wrong currently
because it doesn't say that ALTER TABLE ALL IN TABLESPACE is not
supported.)
I propose this for 9.4 too.
Apologies on it taking so long-
things have a bit "interesting" for me over the past month or two. :)
I bet they have! Have fun,
--
�lvaro Herrera http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services
Attachments:
all_tablespace.patchtext/x-diff; charset=us-asciiDownload
diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c
index 40ac47f..e2c2d3d 100644
--- a/src/backend/tcop/utility.c
+++ b/src/backend/tcop/utility.c
@@ -507,10 +507,6 @@ standard_ProcessUtility(Node *parsetree,
AlterTableSpaceOptions((AlterTableSpaceOptionsStmt *) parsetree);
break;
- case T_AlterTableMoveAllStmt:
- AlterTableMoveAll((AlterTableMoveAllStmt *) parsetree);
- break;
-
case T_TruncateStmt:
ExecuteTruncate((TruncateStmt *) parsetree);
break;
@@ -1296,6 +1292,10 @@ ProcessUtilitySlow(Node *parsetree,
AlterTSConfiguration((AlterTSConfigurationStmt *) parsetree);
break;
+ case T_AlterTableMoveAllStmt:
+ AlterTableMoveAll((AlterTableMoveAllStmt *) parsetree);
+ break;
+
case T_DropStmt:
ExecDropStmt((DropStmt *) parsetree, isTopLevel);
break;
Alvaro,
* Alvaro Herrera (alvherre@2ndquadrant.com) wrote:
Stephen Frost wrote:
* Alvaro Herrera (alvherre@2ndquadrant.com) wrote:
ALTER TABLE ALL IN TABLESPACE xyz
which AFAICS should work since ALL is already a reserved keyword.Pushed to master and REL9_4_STABLE.
Thanks. One more tweak --- the whole reason for fiddling with this is
to ensure that event triggers support this operation. Therefore this
node should be handled by ProcessUtilitySlow, not
standard_ProcessUtility, as in the attached patch.
Ah, right, of course. I recall looking for what else might need to be
changed and apparently missed that distinction in the call sites.
(I checked the documentation for necessary updates; turns out that the
table in the event triggers chapter says that ddl_command_end etc
support the command "ALTER TABLE", and since this is the tag returned by
the new ALTER TABLE ALL IN TABLESPACE command, there is no update
needed. In fact, one can argue that the table is wrong currently
because it doesn't say that ALTER TABLE ALL IN TABLESPACE is not
supported.)
Heh, yes, true.
I propose this for 9.4 too.
Agreed. Looks pretty straight-forward, will update soon.
Apologies on it taking so long-
things have a bit "interesting" for me over the past month or two. :)I bet they have! Have fun,
Thanks! :)
Stephen
Alvaro,
* Alvaro Herrera (alvherre@2ndquadrant.com) wrote:
Thanks. One more tweak --- the whole reason for fiddling with this is
to ensure that event triggers support this operation. Therefore this
node should be handled by ProcessUtilitySlow, not
standard_ProcessUtility, as in the attached patch.
[...]
I propose this for 9.4 too.
Done.
I bet they have! Have fun,
Thanks! I'm trying to. :)
Stephen