Commit 69724805 authored by Aleksey Midenkov's avatar Aleksey Midenkov Committed by Sergei Golubchik

MDEV-22165 CONVERT TABLE: move in partition from existing table

Syntax for CONVERT TABLE

ALTER TABLE tbl_name CONVERT TABLE tbl_name TO PARTITION partition_name partition_spec

Examples:

    ALTER TABLE t1 CONVERT TABLE tp2 TO PARTITION p2 VALUES LESS THAN MAX_VALUE();

New ALTER_PARTITION_CONVERT_IN command for
fast_alter_partition_table() is done in alter_partition_convert_in()
function which basically does ha_rename_table().

Table structure and data check is basically the same as in EXCHANGE
PARTITION command. And these are done by
compare_table_with_partition() and check_table_data().

Atomic DDL is done by the scheme from MDEV-22166 (see the
corresponding commit message). The only differnce is that it also has
to drop source table frm and that is done by WFRM_DROP_CONVERTED_FROM.

Initial patch was done by Dmitry Shulga <dmitry.shulga@mariadb.com>
parent 7da721be
--- alter_partition.result --- alter_partition.result
+++ alter_partition,innodb.reject +++ alter_partition,innodb.reject
@@ -12,12 +12,9 @@ @@ -17,12 +17,9 @@
end $ end $
# QUERY: ALTER TABLE t1 CONVERT PARTITION p1 TO TABLE tp1 # QUERY: ALTER TABLE t1 CONVERT PARTITION p1 TO TABLE tp1
# CRASH: crash_create_before_create_frm # CRASH: crash_create_before_create_frm
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
t1.frm t1.frm
t1.par t1.par
Table Create Table Table Create Table
@@ -33,12 +30,9 @@ @@ -38,12 +35,9 @@
12 12
22 22
# CRASH: crash_alter_partition_after_create_frm # CRASH: crash_alter_partition_after_create_frm
...@@ -32,7 +32,7 @@ ...@@ -32,7 +32,7 @@
t1.frm t1.frm
t1.par t1.par
Table Create Table Table Create Table
@@ -54,12 +48,9 @@ @@ -59,12 +53,9 @@
12 12
22 22
# CRASH: crash_alter_partition_after_write_frm # CRASH: crash_alter_partition_after_write_frm
...@@ -48,7 +48,7 @@ ...@@ -48,7 +48,7 @@
t1.frm t1.frm
t1.par t1.par
Table Create Table Table Create Table
@@ -75,12 +66,9 @@ @@ -80,12 +71,9 @@
12 12
22 22
# CRASH: crash_convert_partition_1 # CRASH: crash_convert_partition_1
...@@ -64,7 +64,7 @@ ...@@ -64,7 +64,7 @@
t1.frm t1.frm
t1.par t1.par
Table Create Table Table Create Table
@@ -96,12 +84,9 @@ @@ -101,12 +89,9 @@
12 12
22 22
# CRASH: crash_convert_partition_2 # CRASH: crash_convert_partition_2
...@@ -80,7 +80,7 @@ ...@@ -80,7 +80,7 @@
t1.frm t1.frm
t1.par t1.par
Table Create Table Table Create Table
@@ -117,12 +102,9 @@ @@ -122,12 +107,9 @@
12 12
22 22
# CRASH: crash_convert_partition_3 # CRASH: crash_convert_partition_3
...@@ -96,7 +96,7 @@ ...@@ -96,7 +96,7 @@
t1.frm t1.frm
t1.par t1.par
Table Create Table Table Create Table
@@ -138,12 +120,9 @@ @@ -143,12 +125,9 @@
12 12
22 22
# CRASH: crash_convert_partition_4 # CRASH: crash_convert_partition_4
...@@ -112,7 +112,7 @@ ...@@ -112,7 +112,7 @@
t1.frm t1.frm
t1.par t1.par
Table Create Table Table Create Table
@@ -159,12 +138,9 @@ @@ -164,12 +143,9 @@
12 12
22 22
# CRASH: crash_convert_partition_5 # CRASH: crash_convert_partition_5
...@@ -128,7 +128,7 @@ ...@@ -128,7 +128,7 @@
t1.frm t1.frm
t1.par t1.par
Table Create Table Table Create Table
@@ -180,12 +156,9 @@ @@ -185,12 +161,9 @@
12 12
22 22
# CRASH: crash_convert_partition_6 # CRASH: crash_convert_partition_6
...@@ -144,7 +144,7 @@ ...@@ -144,7 +144,7 @@
t1.frm t1.frm
t1.par t1.par
Table Create Table Table Create Table
@@ -201,12 +174,9 @@ @@ -206,12 +179,9 @@
12 12
22 22
# CRASH: crash_convert_partition_7 # CRASH: crash_convert_partition_7
...@@ -160,7 +160,7 @@ ...@@ -160,7 +160,7 @@
t1.frm t1.frm
t1.par t1.par
Table Create Table Table Create Table
@@ -222,12 +192,9 @@ @@ -227,12 +197,9 @@
12 12
22 22
# CRASH: crash_convert_partition_8 # CRASH: crash_convert_partition_8
...@@ -176,7 +176,7 @@ ...@@ -176,7 +176,7 @@
t1.frm t1.frm
t1.par t1.par
Table Create Table Table Create Table
@@ -243,15 +210,12 @@ @@ -248,15 +215,12 @@
12 12
22 22
# CRASH: crash_convert_partition_9 # CRASH: crash_convert_partition_9
...@@ -195,7 +195,7 @@ ...@@ -195,7 +195,7 @@
master-bin.000001 # Query # # use `test`; ALTER TABLE t1 CONVERT PARTITION p1 TO TABLE tp1 master-bin.000001 # Query # # use `test`; ALTER TABLE t1 CONVERT PARTITION p1 TO TABLE tp1
Table Create Table Table Create Table
t1 CREATE TABLE `t1` ( t1 CREATE TABLE `t1` (
@@ -270,15 +234,12 @@ @@ -275,15 +239,12 @@
x x
12 12
# CRASH: crash_convert_partition_10 # CRASH: crash_convert_partition_10
...@@ -214,7 +214,7 @@ ...@@ -214,7 +214,7 @@
master-bin.000001 # Query # # use `test`; ALTER TABLE t1 CONVERT PARTITION p1 TO TABLE tp1 master-bin.000001 # Query # # use `test`; ALTER TABLE t1 CONVERT PARTITION p1 TO TABLE tp1
Table Create Table Table Create Table
t1 CREATE TABLE `t1` ( t1 CREATE TABLE `t1` (
@@ -297,15 +258,12 @@ @@ -302,15 +263,12 @@
x x
12 12
# CRASH: crash_convert_partition_11 # CRASH: crash_convert_partition_11
...@@ -233,3 +233,293 @@ ...@@ -233,3 +233,293 @@
master-bin.000001 # Query # # use `test`; ALTER TABLE t1 CONVERT PARTITION p1 TO TABLE tp1 master-bin.000001 # Query # # use `test`; ALTER TABLE t1 CONVERT PARTITION p1 TO TABLE tp1
Table Create Table Table Create Table
t1 CREATE TABLE `t1` ( t1 CREATE TABLE `t1` (
@@ -330,14 +288,10 @@
12
# QUERY: ALTER TABLE t1 CONVERT TABLE tp2 TO PARTITION p2 values less than (40)
# NO CRASH: crash_create_before_create_frm
-t1#P#p0.MYD
-t1#P#p0.MYI
-t1#P#p1.MYD
-t1#P#p1.MYI
-t1#P#p2.MYD
-t1#P#p2.MYI
-t1#P#pn.MYD
-t1#P#pn.MYI
+t1#P#p0.ibd
+t1#P#p1.ibd
+t1#P#p2.ibd
+t1#P#pn.ibd
t1.frm
t1.par
master-bin.000001 # Query # # use `test`; ALTER TABLE t1 CONVERT TABLE tp2 TO PARTITION p2 values less than (40)
@@ -357,14 +311,10 @@
32
39
# NO CRASH: crash_alter_partition_after_create_frm
-t1#P#p0.MYD
-t1#P#p0.MYI
-t1#P#p1.MYD
-t1#P#p1.MYI
-t1#P#p2.MYD
-t1#P#p2.MYI
-t1#P#pn.MYD
-t1#P#pn.MYI
+t1#P#p0.ibd
+t1#P#p1.ibd
+t1#P#p2.ibd
+t1#P#pn.ibd
t1.frm
t1.par
master-bin.000001 # Query # # use `test`; ALTER TABLE t1 CONVERT TABLE tp2 TO PARTITION p2 values less than (40)
@@ -384,14 +334,10 @@
32
39
# NO CRASH: crash_alter_partition_after_write_frm
-t1#P#p0.MYD
-t1#P#p0.MYI
-t1#P#p1.MYD
-t1#P#p1.MYI
-t1#P#p2.MYD
-t1#P#p2.MYI
-t1#P#pn.MYD
-t1#P#pn.MYI
+t1#P#p0.ibd
+t1#P#p1.ibd
+t1#P#p2.ibd
+t1#P#pn.ibd
t1.frm
t1.par
master-bin.000001 # Query # # use `test`; ALTER TABLE t1 CONVERT TABLE tp2 TO PARTITION p2 values less than (40)
@@ -411,17 +357,13 @@
32
39
# CRASH: crash_convert_partition_1
-t1#P#p0.MYD
-t1#P#p0.MYI
-t1#P#p1.MYD
-t1#P#p1.MYI
-t1#P#pn.MYD
-t1#P#pn.MYI
+t1#P#p0.ibd
+t1#P#p1.ibd
+t1#P#pn.ibd
t1.frm
t1.par
-tp2.MYD
-tp2.MYI
tp2.frm
+tp2.ibd
Table Create Table
t1 CREATE TABLE `t1` (
`x` int(11) DEFAULT NULL
@@ -442,17 +384,13 @@
32
39
# CRASH: crash_convert_partition_2
-t1#P#p0.MYD
-t1#P#p0.MYI
-t1#P#p1.MYD
-t1#P#p1.MYI
-t1#P#pn.MYD
-t1#P#pn.MYI
+t1#P#p0.ibd
+t1#P#p1.ibd
+t1#P#pn.ibd
t1.frm
t1.par
-tp2.MYD
-tp2.MYI
tp2.frm
+tp2.ibd
Table Create Table
t1 CREATE TABLE `t1` (
`x` int(11) DEFAULT NULL
@@ -473,17 +411,13 @@
32
39
# CRASH: crash_convert_partition_3
-t1#P#p0.MYD
-t1#P#p0.MYI
-t1#P#p1.MYD
-t1#P#p1.MYI
-t1#P#pn.MYD
-t1#P#pn.MYI
+t1#P#p0.ibd
+t1#P#p1.ibd
+t1#P#pn.ibd
t1.frm
t1.par
-tp2.MYD
-tp2.MYI
tp2.frm
+tp2.ibd
Table Create Table
t1 CREATE TABLE `t1` (
`x` int(11) DEFAULT NULL
@@ -504,17 +438,13 @@
32
39
# CRASH: crash_convert_partition_4
-t1#P#p0.MYD
-t1#P#p0.MYI
-t1#P#p1.MYD
-t1#P#p1.MYI
-t1#P#pn.MYD
-t1#P#pn.MYI
+t1#P#p0.ibd
+t1#P#p1.ibd
+t1#P#pn.ibd
t1.frm
t1.par
-tp2.MYD
-tp2.MYI
tp2.frm
+tp2.ibd
Table Create Table
t1 CREATE TABLE `t1` (
`x` int(11) DEFAULT NULL
@@ -535,17 +465,13 @@
32
39
# CRASH: crash_convert_partition_5
-t1#P#p0.MYD
-t1#P#p0.MYI
-t1#P#p1.MYD
-t1#P#p1.MYI
-t1#P#pn.MYD
-t1#P#pn.MYI
+t1#P#p0.ibd
+t1#P#p1.ibd
+t1#P#pn.ibd
t1.frm
t1.par
-tp2.MYD
-tp2.MYI
tp2.frm
+tp2.ibd
Table Create Table
t1 CREATE TABLE `t1` (
`x` int(11) DEFAULT NULL
@@ -566,17 +492,13 @@
32
39
# CRASH: crash_convert_partition_6
-t1#P#p0.MYD
-t1#P#p0.MYI
-t1#P#p1.MYD
-t1#P#p1.MYI
-t1#P#pn.MYD
-t1#P#pn.MYI
+t1#P#p0.ibd
+t1#P#p1.ibd
+t1#P#pn.ibd
t1.frm
t1.par
-tp2.MYD
-tp2.MYI
tp2.frm
+tp2.ibd
Table Create Table
t1 CREATE TABLE `t1` (
`x` int(11) DEFAULT NULL
@@ -597,17 +519,13 @@
32
39
# CRASH: crash_convert_partition_7
-t1#P#p0.MYD
-t1#P#p0.MYI
-t1#P#p1.MYD
-t1#P#p1.MYI
-t1#P#pn.MYD
-t1#P#pn.MYI
+t1#P#p0.ibd
+t1#P#p1.ibd
+t1#P#pn.ibd
t1.frm
t1.par
-tp2.MYD
-tp2.MYI
tp2.frm
+tp2.ibd
Table Create Table
t1 CREATE TABLE `t1` (
`x` int(11) DEFAULT NULL
@@ -628,17 +546,13 @@
32
39
# CRASH: crash_convert_partition_8
-t1#P#p0.MYD
-t1#P#p0.MYI
-t1#P#p1.MYD
-t1#P#p1.MYI
-t1#P#pn.MYD
-t1#P#pn.MYI
+t1#P#p0.ibd
+t1#P#p1.ibd
+t1#P#pn.ibd
t1.frm
t1.par
-tp2.MYD
-tp2.MYI
tp2.frm
+tp2.ibd
Table Create Table
t1 CREATE TABLE `t1` (
`x` int(11) DEFAULT NULL
@@ -659,14 +573,10 @@
32
39
# CRASH: crash_convert_partition_9
-t1#P#p0.MYD
-t1#P#p0.MYI
-t1#P#p1.MYD
-t1#P#p1.MYI
-t1#P#p2.MYD
-t1#P#p2.MYI
-t1#P#pn.MYD
-t1#P#pn.MYI
+t1#P#p0.ibd
+t1#P#p1.ibd
+t1#P#p2.ibd
+t1#P#pn.ibd
t1.frm
t1.par
master-bin.000001 # Query # # use `test`; ALTER TABLE t1 CONVERT TABLE tp2 TO PARTITION p2 values less than (40)
@@ -686,14 +596,10 @@
32
39
# CRASH: crash_convert_partition_10
-t1#P#p0.MYD
-t1#P#p0.MYI
-t1#P#p1.MYD
-t1#P#p1.MYI
-t1#P#p2.MYD
-t1#P#p2.MYI
-t1#P#pn.MYD
-t1#P#pn.MYI
+t1#P#p0.ibd
+t1#P#p1.ibd
+t1#P#p2.ibd
+t1#P#pn.ibd
t1.frm
t1.par
master-bin.000001 # Query # # use `test`; ALTER TABLE t1 CONVERT TABLE tp2 TO PARTITION p2 values less than (40)
@@ -713,14 +619,10 @@
32
39
# CRASH: crash_convert_partition_11
-t1#P#p0.MYD
-t1#P#p0.MYI
-t1#P#p1.MYD
-t1#P#p1.MYI
-t1#P#p2.MYD
-t1#P#p2.MYI
-t1#P#pn.MYD
-t1#P#pn.MYI
+t1#P#p0.ibd
+t1#P#p1.ibd
+t1#P#p2.ibd
+t1#P#pn.ibd
t1.frm
t1.par
master-bin.000001 # Query # # use `test`; ALTER TABLE t1 CONVERT TABLE tp2 TO PARTITION p2 values less than (40)
...@@ -55,22 +55,30 @@ let $crash_points='crash_create_before_create_frm', ...@@ -55,22 +55,30 @@ let $crash_points='crash_create_before_create_frm',
#let $crash_count= 1; #let $crash_count= 1;
#let $crash_points= 'crash_convert_partition_10'; #let $crash_points= 'crash_convert_partition_10';
let $statement_count= 1; let $statement_count= 2;
let $statements= 'ALTER TABLE t1 CONVERT PARTITION p1 TO TABLE tp1'; let $statements= 'ALTER TABLE t1 CONVERT PARTITION p1 TO TABLE tp1',
'ALTER TABLE t1 CONVERT TABLE tp2 TO PARTITION p2 values less than (40)';
#let $statement_count=1; #let $statement_count= 1;
#let $statements='CREATE OR REPLACE TABLE t1 SELECT * from const_table'; #let $statements= 'ALTER TABLE t1 CONVERT TABLE tp2 TO PARTITION p2 values less than (40)';
--delimiter $ --delimiter $
create or replace procedure prepare_table() create or replace procedure prepare_table(r int)
begin begin
create or replace table t1 (x int) create or replace table t1 (x int)
with system versioning with system versioning
partition by range(x) ( partition by range(x) (
partition p0 values less than (10), partition p0 values less than (10),
partition p1 values less than (20), partition p1 values less than (20),
partition pn values less than maxvalue); partition pn values less than (30));
insert into t1 values (2), (12), (22); insert into t1 values (2), (12), (22);
if r > 1 then
create or replace table tp2 (x int)
with system versioning;
insert into tp2 values (32), (39);
end if;
flush tables; flush tables;
end $ end $
--delimiter ; --delimiter ;
...@@ -95,7 +103,7 @@ while ($r < $statement_count) ...@@ -95,7 +103,7 @@ while ($r < $statement_count)
let $crash=`select ELT($c, $crash_points)`; let $crash=`select ELT($c, $crash_points)`;
--eval set @@default_storage_engine=$default_engine --eval set @@default_storage_engine=$default_engine
call prepare_table; eval call prepare_table($r);
if (!$c) if (!$c)
{ {
lock tables t1 write; lock tables t1 write;
...@@ -147,6 +155,11 @@ while ($r < $statement_count) ...@@ -147,6 +155,11 @@ while ($r < $statement_count)
show create table tp1; show create table tp1;
--error 0, ER_NO_SUCH_TABLE --error 0, ER_NO_SUCH_TABLE
select * from tp1; select * from tp1;
--replace_result $default_engine DEFAULT_ENGINE ' PAGE_CHECKSUM=1' ''
--error 0, ER_NO_SUCH_TABLE
show create table tp2;
--error 0, ER_NO_SUCH_TABLE
select * from tp2;
# Drop the tables. The warnings will show what was dropped # Drop the tables. The warnings will show what was dropped
--disable_warnings --disable_warnings
drop table t1; drop table t1;
......
...@@ -2,30 +2,40 @@ ...@@ -2,30 +2,40 @@
# To be used with WL#4445: EXCHANGE PARTITION WITH TABLE. # To be used with WL#4445: EXCHANGE PARTITION WITH TABLE.
--eval $create_statement2 --eval $create_statement2
--eval $insert_statement2 --eval $insert_statement2
SHOW CREATE TABLE t2;
--sorted_result
SELECT * FROM t2;
--eval $create_statement --eval $create_statement
--eval $insert_statement --eval $insert_statement
--echo # State before failure --let $dbug_flag= `select @@session.debug_dbug`
--echo # $dbug_flag: BEFORE failure
--replace_result #p# #P# --replace_result #p# #P#
if (!$DATADIR)
{
--let $DATADIR= `SELECT @@datadir;`
}
--list_files $DATADIR/test --list_files $DATADIR/test
SHOW CREATE TABLE t1; SHOW CREATE TABLE t1;
--sorted_result --sorted_result
SELECT * FROM t1; SELECT * FROM t1;
SHOW CREATE TABLE t2;
--sorted_result
SELECT * FROM t2;
# accept all errors # accept all errors
--disable_abort_on_error --disable_abort_on_error
--replace_regex /#sql-exchange-[0-9a-f_\-]*/#sql-exchange/i --replace_regex /#sql-exchange-[0-9a-f_\-]*/#sql-exchange/i
--eval $fail_statement --eval $fail_statement
--enable_abort_on_error --enable_abort_on_error
--echo # State after failure --echo # $dbug_flag: AFTER failure
--replace_result #p# #P# --replace_result #p# #P#
--list_files $DATADIR/test --list_files $DATADIR/test
SHOW CREATE TABLE t1; SHOW CREATE TABLE t1;
--sorted_result --sorted_result
SELECT * FROM t1; SELECT * FROM t1;
DROP TABLE t1; DROP TABLE t1;
--error 0, ER_NO_SUCH_TABLE
SHOW CREATE TABLE t2; SHOW CREATE TABLE t2;
--sorted_result --sorted_result
--error 0, ER_NO_SUCH_TABLE
SELECT * FROM t2; SELECT * FROM t2;
# TODO: everything fails with ER_NO_SUCH_TABLE
# but DROP TABLE fails with ER_BAD_TABLE_ERROR! Why?
--error 0, ER_BAD_TABLE_ERROR
DROP TABLE t2; DROP TABLE t2;
...@@ -29,7 +29,87 @@ ERROR 42000: Can't open table ...@@ -29,7 +29,87 @@ ERROR 42000: Can't open table
DROP VIEW v1; DROP VIEW v1;
DROP TABLE t1, t2; DROP TABLE t1, t2;
# #
# MDEV-22166 MIGRATE PARTITION: move out partition into a table # MDEV-22165 CONVERT PARTITION: move in partition from existing table
#
create or replace table tp1 (a int);
create or replace table t1 (a int)
partition by hash (a) partitions 2;
alter table t1 convert table tp1 to partition p2;
ERROR HY000: CONVERT TABLE TO PARTITION can only be used on RANGE/LIST partitions
create or replace table t1 (a int)
partition by range (a)
(partition p0 values less than (0));
alter table t1 convert table non_existent to partition p1 values less than (10);
ERROR 42S02: Table 'test.non_existent' doesn't exist
alter table t1 convert table tp1 to partition p1 values less than (10);
show create table tp1;
ERROR 42S02: Table 'test.tp1' doesn't exist
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL
) ENGINE=X DEFAULT CHARSET=latin1
PARTITION BY RANGE (`a`)
(PARTITION `p0` VALUES LESS THAN (0) ENGINE = X,
PARTITION `p1` VALUES LESS THAN (10) ENGINE = X)
create table tp2 (x int);
alter table t1 convert table tp2 to partition p2 values less than (20);
ERROR HY000: Tables have different definitions
show create table tp2;
Table Create Table
tp2 CREATE TABLE `tp2` (
`x` int(11) DEFAULT NULL
) ENGINE=X DEFAULT CHARSET=latin1
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL
) ENGINE=X DEFAULT CHARSET=latin1
PARTITION BY RANGE (`a`)
(PARTITION `p0` VALUES LESS THAN (0) ENGINE = X,
PARTITION `p1` VALUES LESS THAN (10) ENGINE = X)
create or replace table tp2 (a int);
insert tp2 values (1), (15), (17);
alter table t1 convert table tp2 to partition p2 values less than (20);
ERROR HY000: Found a row that does not match the partition
delete from tp2;
insert tp2 values (15), (1), (17);
alter table t1 convert table tp2 to partition p2 values less than (20);
ERROR HY000: Found a row that does not match the partition
delete from tp2;
insert tp2 values (15), (17), (1);
alter table t1 convert table tp2 to partition p2 values less than (20);
ERROR HY000: Found a row that does not match the partition
delete from tp2;
insert tp2 values (15), (17);
alter table t1 convert table tp2 to partition p2 values less than (20);
show create table tp2;
ERROR 42S02: Table 'test.tp2' doesn't exist
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL
) ENGINE=X DEFAULT CHARSET=latin1
PARTITION BY RANGE (`a`)
(PARTITION `p0` VALUES LESS THAN (0) ENGINE = X,
PARTITION `p1` VALUES LESS THAN (10) ENGINE = X,
PARTITION `p2` VALUES LESS THAN (20) ENGINE = X)
select * from t1 partition (p2);
a
15
17
create or replace table t1 (a int)
partition by range (a) (
p0 values less than (0),
pn values less than (30));
insert into t1 values (1);
create or replace table tp1 (a int);
insert into tp1 values (2);
alter table t1 convert table tp1 to partition p1 values less than (10);
ERROR HY000: VALUES LESS THAN value must be strictly increasing for each partition
drop tables t1, tp1;
#
# MDEV-22166 CONVERT PARTITION: move out partition into a table
# #
create or replace table t1 (x int); create or replace table t1 (x int);
alter table t1 convert partition p1 to table tp1; alter table t1 convert partition p1 to table tp1;
......
...@@ -39,7 +39,72 @@ DROP VIEW v1; ...@@ -39,7 +39,72 @@ DROP VIEW v1;
DROP TABLE t1, t2; DROP TABLE t1, t2;
--echo # --echo #
--echo # MDEV-22166 MIGRATE PARTITION: move out partition into a table --echo # MDEV-22165 CONVERT PARTITION: move in partition from existing table
--echo #
create or replace table tp1 (a int);
create or replace table t1 (a int)
partition by hash (a) partitions 2;
--error ER_ONLY_ON_RANGE_LIST_PARTITION
alter table t1 convert table tp1 to partition p2;
create or replace table t1 (a int)
partition by range (a)
(partition p0 values less than (0));
--error ER_NO_SUCH_TABLE
alter table t1 convert table non_existent to partition p1 values less than (10);
alter table t1 convert table tp1 to partition p1 values less than (10);
--error ER_NO_SUCH_TABLE
show create table tp1;
--replace_result $engine X ' PAGE_CHECKSUM=1' ''
show create table t1;
create table tp2 (x int);
--error ER_TABLES_DIFFERENT_METADATA
alter table t1 convert table tp2 to partition p2 values less than (20);
--replace_result $engine X ' PAGE_CHECKSUM=1' ''
show create table tp2;
--replace_result $engine X ' PAGE_CHECKSUM=1' ''
show create table t1;
create or replace table tp2 (a int);
insert tp2 values (1), (15), (17);
--error ER_ROW_DOES_NOT_MATCH_PARTITION
alter table t1 convert table tp2 to partition p2 values less than (20);
delete from tp2;
insert tp2 values (15), (1), (17);
--error ER_ROW_DOES_NOT_MATCH_PARTITION
alter table t1 convert table tp2 to partition p2 values less than (20);
delete from tp2;
insert tp2 values (15), (17), (1);
--error ER_ROW_DOES_NOT_MATCH_PARTITION
alter table t1 convert table tp2 to partition p2 values less than (20);
delete from tp2;
insert tp2 values (15), (17);
alter table t1 convert table tp2 to partition p2 values less than (20);
--error ER_NO_SUCH_TABLE
show create table tp2;
--replace_result $engine X ' PAGE_CHECKSUM=1' ''
show create table t1;
select * from t1 partition (p2);
create or replace table t1 (a int)
partition by range (a) (
p0 values less than (0),
pn values less than (30));
insert into t1 values (1);
create or replace table tp1 (a int);
insert into tp1 values (2);
# TODO: would be good to automatically detect order of partitions,
# as well as move the data from succeeding partitions (ADD PARTITION FR).
--error ER_RANGE_NOT_INCREASING_ERROR
alter table t1 convert table tp1 to partition p1 values less than (10);
drop tables t1, tp1;
--echo #
--echo # MDEV-22166 CONVERT PARTITION: move out partition into a table
--echo # --echo #
create or replace table t1 (x int); create or replace table t1 (x int);
......
...@@ -52,7 +52,55 @@ let $fail_statement= $crash_statement; ...@@ -52,7 +52,55 @@ let $fail_statement= $crash_statement;
--source suite/parts/inc/partition_fail_exchange.inc --source suite/parts/inc/partition_fail_exchange.inc
--echo # --echo #
--echo # MDEV-22166 MIGRATE PARTITION: move out partition into a table --echo # MDEV-22165 CONVERT PARTITION: move in partition from existing table
--echo #
let $create_statement= create or replace table t1 (x int primary key)
partition by range(x) (
partition p1 values less than (10),
partition p2 values less than (20),
partition p3 values less than (30));
let $create_statement2= create or replace table t2 (x int primary key);
let $insert_statement= insert into t1 values (2), (12), (22);
let $insert_statement2= insert into t2 values (32), (42), (52);
let $fail_statement= alter table t1 convert table t2 to partition pn values less than maxvalue;
set @save_dbug=@@debug_dbug;
set session debug_dbug="+d,fail_convert_partition_1";
--source suite/parts/inc/partition_fail_t2.inc
set session debug_dbug=@save_dbug;
set session debug_dbug="+d,fail_convert_partition_2";
--source suite/parts/inc/partition_fail_t2.inc
set session debug_dbug=@save_dbug;
set session debug_dbug="+d,fail_convert_partition_3";
--source suite/parts/inc/partition_fail_t2.inc
set session debug_dbug=@save_dbug;
set session debug_dbug="+d,fail_convert_partition_4";
--source suite/parts/inc/partition_fail_t2.inc
set session debug_dbug=@save_dbug;
set session debug_dbug="+d,fail_convert_partition_5";
--source suite/parts/inc/partition_fail_t2.inc
set session debug_dbug=@save_dbug;
set session debug_dbug="+d,fail_convert_partition_6";
--source suite/parts/inc/partition_fail_t2.inc
set session debug_dbug=@save_dbug;
set session debug_dbug="+d,fail_convert_partition_7";
--source suite/parts/inc/partition_fail_t2.inc
set session debug_dbug=@save_dbug;
set session debug_dbug="+d,fail_convert_partition_8";
--source suite/parts/inc/partition_fail_t2.inc
set session debug_dbug=@save_dbug;
set session debug_dbug="+d,fail_convert_partition_9";
--source suite/parts/inc/partition_fail_t2.inc
set session debug_dbug=@save_dbug;
set session debug_dbug="+d,fail_convert_partition_11";
--source suite/parts/inc/partition_fail_t2.inc
set session debug_dbug=@save_dbug;
--echo #
--echo # MDEV-22166 CONVERT PARTITION: move out partition into a table
--echo # --echo #
let $create_statement= create or replace table t1 (x int primary key) let $create_statement= create or replace table t1 (x int primary key)
partition by range(x) ( partition by range(x) (
......
...@@ -823,8 +823,9 @@ typedef bool Log_func(THD*, TABLE*, bool, const uchar*, const uchar*); ...@@ -823,8 +823,9 @@ typedef bool Log_func(THD*, TABLE*, bool, const uchar*, const uchar*);
// Set by Sql_cmd_alter_table_truncate_partition::execute() // Set by Sql_cmd_alter_table_truncate_partition::execute()
#define ALTER_PARTITION_TRUNCATE (1ULL << 11) #define ALTER_PARTITION_TRUNCATE (1ULL << 11)
// Set for REORGANIZE PARTITION // Set for REORGANIZE PARTITION
#define ALTER_PARTITION_TABLE_REORG (1ULL << 12) #define ALTER_PARTITION_TABLE_REORG (1ULL << 12)
#define ALTER_PARTITION_CONVERT_OUT (1ULL << 13) #define ALTER_PARTITION_CONVERT_IN (1ULL << 13)
#define ALTER_PARTITION_CONVERT_OUT (1ULL << 14)
/* /*
This is master database for most of system tables. However there This is master database for most of system tables. However there
......
...@@ -440,6 +440,7 @@ bool Sql_cmd_alter_table::execute(THD *thd) ...@@ -440,6 +440,7 @@ bool Sql_cmd_alter_table::execute(THD *thd)
as for RENAME TO, as being done by SQLCOM_RENAME_TABLE as for RENAME TO, as being done by SQLCOM_RENAME_TABLE
*/ */
if ((alter_info.partition_flags & ALTER_PARTITION_DROP) || if ((alter_info.partition_flags & ALTER_PARTITION_DROP) ||
(alter_info.partition_flags & ALTER_PARTITION_CONVERT_IN) ||
(alter_info.partition_flags & ALTER_PARTITION_CONVERT_OUT) || (alter_info.partition_flags & ALTER_PARTITION_CONVERT_OUT) ||
(alter_info.flags & ALTER_RENAME)) (alter_info.flags & ALTER_RENAME))
priv_needed|= DROP_ACL; priv_needed|= DROP_ACL;
......
...@@ -6045,8 +6045,10 @@ int st_select_lex_unit::save_union_explain_part2(Explain_query *output) ...@@ -6045,8 +6045,10 @@ int st_select_lex_unit::save_union_explain_part2(Explain_query *output)
bool LEX::is_partition_management() const bool LEX::is_partition_management() const
{ {
return (sql_command == SQLCOM_ALTER_TABLE && return (sql_command == SQLCOM_ALTER_TABLE &&
(alter_info.partition_flags == ALTER_PARTITION_ADD || (alter_info.partition_flags & (ALTER_PARTITION_ADD |
alter_info.partition_flags == ALTER_PARTITION_REORGANIZE)); ALTER_PARTITION_CONVERT_IN |
ALTER_PARTITION_CONVERT_OUT |
ALTER_PARTITION_REORGANIZE)));
} }
......
This diff is collapsed.
...@@ -279,11 +279,16 @@ bool verify_data_with_partition(TABLE *table, TABLE *part_table, ...@@ -279,11 +279,16 @@ bool verify_data_with_partition(TABLE *table, TABLE *part_table,
uint32 part_id); uint32 part_id);
bool compare_partition_options(HA_CREATE_INFO *table_create_info, bool compare_partition_options(HA_CREATE_INFO *table_create_info,
partition_element *part_elem); partition_element *part_elem);
bool compare_table_with_partition(THD *thd, TABLE *table,
TABLE *part_table,
partition_element *part_elem,
uint part_id);
bool partition_key_modified(TABLE *table, const MY_BITMAP *fields); bool partition_key_modified(TABLE *table, const MY_BITMAP *fields);
bool write_log_replace_frm(ALTER_PARTITION_PARAM_TYPE *lpt, bool write_log_replace_frm(ALTER_PARTITION_PARAM_TYPE *lpt,
uint next_entry, uint next_entry,
const char *from_path, const char *from_path,
const char *to_path); const char *to_path);
#else #else
#define partition_key_modified(X,Y) 0 #define partition_key_modified(X,Y) 0
#endif #endif
......
...@@ -192,10 +192,8 @@ static bool check_exchange_partition(TABLE *table, TABLE *part_table) ...@@ -192,10 +192,8 @@ static bool check_exchange_partition(TABLE *table, TABLE *part_table)
@param part_table Partitioned table. @param part_table Partitioned table.
@param part_elem Partition element to use for partition specific compare. @param part_elem Partition element to use for partition specific compare.
*/ */
static bool compare_table_with_partition(THD *thd, TABLE *table, bool compare_table_with_partition(THD *thd, TABLE *table, TABLE *part_table,
TABLE *part_table, partition_element *part_elem, uint part_id)
partition_element *part_elem,
uint part_id)
{ {
HA_CREATE_INFO table_create_info, part_create_info; HA_CREATE_INFO table_create_info, part_create_info;
Alter_info part_alter_info; Alter_info part_alter_info;
...@@ -292,7 +290,7 @@ static bool compare_table_with_partition(THD *thd, TABLE *table, ...@@ -292,7 +290,7 @@ static bool compare_table_with_partition(THD *thd, TABLE *table,
The workaround is to use REORGANIZE PARTITION to rewrite The workaround is to use REORGANIZE PARTITION to rewrite
the frm file and then use EXCHANGE PARTITION when they are the same. the frm file and then use EXCHANGE PARTITION when they are the same.
*/ */
if (compare_partition_options(&table_create_info, part_elem)) if (part_elem && compare_partition_options(&table_create_info, part_elem))
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
DBUG_RETURN(FALSE); DBUG_RETURN(FALSE);
...@@ -988,4 +986,53 @@ bool Sql_cmd_alter_table_truncate_partition::execute(THD *thd) ...@@ -988,4 +986,53 @@ bool Sql_cmd_alter_table_truncate_partition::execute(THD *thd)
DBUG_RETURN(error); DBUG_RETURN(error);
} }
/**
Move a table specified in the CONVERT TABLE <table_name> TO PARTITION ...
to the new partition.
@param lpt A structure containing parameters regarding to the statement
ALTER TABLE ... TO PARTITION ...
@param part_file_name a file name of the partition being added
@return false on success, true on error
*/
bool alter_partition_convert_in(ALTER_PARTITION_PARAM_TYPE *lpt)
{
char part_file_name[2*FN_REFLEN+1];
THD *thd= lpt->thd;
const char *path= lpt->table_list->table->s->path.str;
TABLE_LIST *table_from= lpt->table_list->next_local;
const char *partition_name=
thd->lex->part_info->curr_part_elem->partition_name;
if (create_partition_name(part_file_name, sizeof(part_file_name), path,
partition_name, NORMAL_PART_NAME, false))
return true;
char from_file_name[FN_REFLEN+1];
build_table_filename(from_file_name, sizeof(from_file_name),
table_from->db.str, table_from->table_name.str, "", 0);
handler *file= get_new_handler(nullptr, thd->mem_root,
table_from->table->file->ht);
if (unlikely(!file))
return true;
close_all_tables_for_name(thd, table_from->table->s,
HA_EXTRA_PREPARE_FOR_RENAME, nullptr);
bool res= file->ha_rename_table(from_file_name, part_file_name);
if (res)
my_error(ER_ERROR_ON_RENAME, MYF(0), from_file_name,
part_file_name, my_errno);
delete file;
return res;
}
#endif /* WITH_PARTITION_STORAGE_ENGINE */ #endif /* WITH_PARTITION_STORAGE_ENGINE */
...@@ -875,7 +875,6 @@ bool mysql_write_frm(ALTER_PARTITION_PARAM_TYPE *lpt, uint flags) ...@@ -875,7 +875,6 @@ bool mysql_write_frm(ALTER_PARTITION_PARAM_TYPE *lpt, uint flags)
#else /* !WITH_PARTITION_STORAGE_ENGINE */ #else /* !WITH_PARTITION_STORAGE_ENGINE */
DBUG_ASSERT(!(flags & WFRM_WRITE_EXTRACTED)); DBUG_ASSERT(!(flags & WFRM_WRITE_EXTRACTED));
DBUG_ASSERT(!(flags & WFRM_BACKUP_ORIGINAL)); DBUG_ASSERT(!(flags & WFRM_BACKUP_ORIGINAL));
DBUG_ASSERT(!(flags & WFRM_DROP_BACKUP));
#endif /* !WITH_PARTITION_STORAGE_ENGINE */ #endif /* !WITH_PARTITION_STORAGE_ENGINE */
if (flags & WFRM_INSTALL_SHADOW) if (flags & WFRM_INSTALL_SHADOW)
{ {
...@@ -9688,7 +9687,8 @@ bool mysql_alter_table(THD *thd, const LEX_CSTRING *new_db, ...@@ -9688,7 +9687,8 @@ bool mysql_alter_table(THD *thd, const LEX_CSTRING *new_db,
Table maybe does not exist, but we got an exclusive lock Table maybe does not exist, but we got an exclusive lock
on the name, now we can safely try to find out for sure. on the name, now we can safely try to find out for sure.
*/ */
if (ha_table_exists(thd, &alter_ctx.new_db, &alter_ctx.new_name)) if (!(alter_info->partition_flags & ALTER_PARTITION_CONVERT_IN) &&
ha_table_exists(thd, &alter_ctx.new_db, &alter_ctx.new_name))
{ {
/* Table will be closed in do_command() */ /* Table will be closed in do_command() */
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), alter_ctx.new_alias.str); my_error(ER_TABLE_EXISTS_ERROR, MYF(0), alter_ctx.new_alias.str);
......
...@@ -7290,6 +7290,43 @@ alter_commands: ...@@ -7290,6 +7290,43 @@ alter_commands:
MYSQL_YYABORT; MYSQL_YYABORT;
lex->alter_info.partition_flags|= ALTER_PARTITION_CONVERT_OUT; lex->alter_info.partition_flags|= ALTER_PARTITION_CONVERT_OUT;
} }
| CONVERT_SYM TABLE_SYM table_ident
{
LEX *lex= Lex;
if (!lex->first_select_lex()->add_table_to_list(thd, $3, nullptr, 0,
TL_READ_NO_INSERT,
MDL_SHARED_NO_WRITE))
MYSQL_YYABORT;
/*
This will appear as (new_db, new_name) in alter_ctx.
new_db will be IX-locked and new_name X-locked.
*/
lex->first_select_lex()->db= $3->db;
lex->name= $3->table;
if (lex->first_select_lex()->db.str == NULL &&
lex->copy_db_to(&lex->first_select_lex()->db))
MYSQL_YYABORT;
lex->part_info= new (thd->mem_root) partition_info();
if (unlikely(!lex->part_info))
MYSQL_YYABORT;
lex->part_info->num_parts= 1;
/*
OR-ed with ALTER_PARTITION_ADD because too many checks of
ALTER_PARTITION_ADD required.
*/
lex->alter_info.partition_flags|= ALTER_PARTITION_ADD |
ALTER_PARTITION_CONVERT_IN;
}
TO_SYM PARTITION_SYM part_definition
{
LEX *lex= Lex;
lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_alter_table();
if (unlikely(lex->m_sql_cmd == NULL))
MYSQL_YYABORT;
}
; ;
remove_partitioning: remove_partitioning:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment