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,innodb.reject
@@ -12,12 +12,9 @@
@@ -17,12 +17,9 @@
end $
# QUERY: ALTER TABLE t1 CONVERT PARTITION p1 TO TABLE tp1
# CRASH: crash_create_before_create_frm
......@@ -16,7 +16,7 @@
t1.frm
t1.par
Table Create Table
@@ -33,12 +30,9 @@
@@ -38,12 +35,9 @@
12
22
# CRASH: crash_alter_partition_after_create_frm
......@@ -32,7 +32,7 @@
t1.frm
t1.par
Table Create Table
@@ -54,12 +48,9 @@
@@ -59,12 +53,9 @@
12
22
# CRASH: crash_alter_partition_after_write_frm
......@@ -48,7 +48,7 @@
t1.frm
t1.par
Table Create Table
@@ -75,12 +66,9 @@
@@ -80,12 +71,9 @@
12
22
# CRASH: crash_convert_partition_1
......@@ -64,7 +64,7 @@
t1.frm
t1.par
Table Create Table
@@ -96,12 +84,9 @@
@@ -101,12 +89,9 @@
12
22
# CRASH: crash_convert_partition_2
......@@ -80,7 +80,7 @@
t1.frm
t1.par
Table Create Table
@@ -117,12 +102,9 @@
@@ -122,12 +107,9 @@
12
22
# CRASH: crash_convert_partition_3
......@@ -96,7 +96,7 @@
t1.frm
t1.par
Table Create Table
@@ -138,12 +120,9 @@
@@ -143,12 +125,9 @@
12
22
# CRASH: crash_convert_partition_4
......@@ -112,7 +112,7 @@
t1.frm
t1.par
Table Create Table
@@ -159,12 +138,9 @@
@@ -164,12 +143,9 @@
12
22
# CRASH: crash_convert_partition_5
......@@ -128,7 +128,7 @@
t1.frm
t1.par
Table Create Table
@@ -180,12 +156,9 @@
@@ -185,12 +161,9 @@
12
22
# CRASH: crash_convert_partition_6
......@@ -144,7 +144,7 @@
t1.frm
t1.par
Table Create Table
@@ -201,12 +174,9 @@
@@ -206,12 +179,9 @@
12
22
# CRASH: crash_convert_partition_7
......@@ -160,7 +160,7 @@
t1.frm
t1.par
Table Create Table
@@ -222,12 +192,9 @@
@@ -227,12 +197,9 @@
12
22
# CRASH: crash_convert_partition_8
......@@ -176,7 +176,7 @@
t1.frm
t1.par
Table Create Table
@@ -243,15 +210,12 @@
@@ -248,15 +215,12 @@
12
22
# CRASH: crash_convert_partition_9
......@@ -195,7 +195,7 @@
master-bin.000001 # Query # # use `test`; ALTER TABLE t1 CONVERT PARTITION p1 TO TABLE tp1
Table Create Table
t1 CREATE TABLE `t1` (
@@ -270,15 +234,12 @@
@@ -275,15 +239,12 @@
x
12
# CRASH: crash_convert_partition_10
......@@ -214,7 +214,7 @@
master-bin.000001 # Query # # use `test`; ALTER TABLE t1 CONVERT PARTITION p1 TO TABLE tp1
Table Create Table
t1 CREATE TABLE `t1` (
@@ -297,15 +258,12 @@
@@ -302,15 +263,12 @@
x
12
# CRASH: crash_convert_partition_11
......@@ -233,3 +233,293 @@
master-bin.000001 # Query # # use `test`; ALTER TABLE t1 CONVERT PARTITION p1 TO TABLE tp1
Table Create Table
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',
#let $crash_count= 1;
#let $crash_points= 'crash_convert_partition_10';
let $statement_count= 1;
let $statements= 'ALTER TABLE t1 CONVERT PARTITION p1 TO TABLE tp1';
let $statement_count= 2;
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 $statements='CREATE OR REPLACE TABLE t1 SELECT * from const_table';
#let $statement_count= 1;
#let $statements= 'ALTER TABLE t1 CONVERT TABLE tp2 TO PARTITION p2 values less than (40)';
--delimiter $
create or replace procedure prepare_table()
create or replace procedure prepare_table(r int)
begin
create or replace table t1 (x int)
with system versioning
partition by range(x) (
partition p0 values less than (10),
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);
if r > 1 then
create or replace table tp2 (x int)
with system versioning;
insert into tp2 values (32), (39);
end if;
flush tables;
end $
--delimiter ;
......@@ -95,7 +103,7 @@ while ($r < $statement_count)
let $crash=`select ELT($c, $crash_points)`;
--eval set @@default_storage_engine=$default_engine
call prepare_table;
eval call prepare_table($r);
if (!$c)
{
lock tables t1 write;
......@@ -147,6 +155,11 @@ while ($r < $statement_count)
show create table tp1;
--error 0, ER_NO_SUCH_TABLE
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
--disable_warnings
drop table t1;
......
......@@ -2,30 +2,40 @@
# To be used with WL#4445: EXCHANGE PARTITION WITH TABLE.
--eval $create_statement2
--eval $insert_statement2
SHOW CREATE TABLE t2;
--sorted_result
SELECT * FROM t2;
--eval $create_statement
--eval $insert_statement
--echo # State before failure
--let $dbug_flag= `select @@session.debug_dbug`
--echo # $dbug_flag: BEFORE failure
--replace_result #p# #P#
if (!$DATADIR)
{
--let $DATADIR= `SELECT @@datadir;`
}
--list_files $DATADIR/test
SHOW CREATE TABLE t1;
--sorted_result
SELECT * FROM t1;
SHOW CREATE TABLE t2;
--sorted_result
SELECT * FROM t2;
# accept all errors
--disable_abort_on_error
--replace_regex /#sql-exchange-[0-9a-f_\-]*/#sql-exchange/i
--eval $fail_statement
--enable_abort_on_error
--echo # State after failure
--echo # $dbug_flag: AFTER failure
--replace_result #p# #P#
--list_files $DATADIR/test
SHOW CREATE TABLE t1;
--sorted_result
SELECT * FROM t1;
DROP TABLE t1;
--error 0, ER_NO_SUCH_TABLE
SHOW CREATE TABLE t2;
--sorted_result
--error 0, ER_NO_SUCH_TABLE
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;
......@@ -29,7 +29,87 @@ ERROR 42000: Can't open table
DROP VIEW v1;
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);
alter table t1 convert partition p1 to table tp1;
......
......@@ -39,7 +39,72 @@ DROP VIEW v1;
DROP TABLE t1, t2;
--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 #
create or replace table t1 (x int);
......
......@@ -52,7 +52,55 @@ let $fail_statement= $crash_statement;
--source suite/parts/inc/partition_fail_exchange.inc
--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 #
let $create_statement= create or replace table t1 (x int primary key)
partition by range(x) (
......
......@@ -823,8 +823,9 @@ typedef bool Log_func(THD*, TABLE*, bool, const uchar*, const uchar*);
// Set by Sql_cmd_alter_table_truncate_partition::execute()
#define ALTER_PARTITION_TRUNCATE (1ULL << 11)
// Set for REORGANIZE PARTITION
#define ALTER_PARTITION_TABLE_REORG (1ULL << 12)
#define ALTER_PARTITION_CONVERT_OUT (1ULL << 13)
#define ALTER_PARTITION_TABLE_REORG (1ULL << 12)
#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
......
......@@ -440,6 +440,7 @@ bool Sql_cmd_alter_table::execute(THD *thd)
as for RENAME TO, as being done by SQLCOM_RENAME_TABLE
*/
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.flags & ALTER_RENAME))
priv_needed|= DROP_ACL;
......
......@@ -6045,8 +6045,10 @@ int st_select_lex_unit::save_union_explain_part2(Explain_query *output)
bool LEX::is_partition_management() const
{
return (sql_command == SQLCOM_ALTER_TABLE &&
(alter_info.partition_flags == ALTER_PARTITION_ADD ||
alter_info.partition_flags == ALTER_PARTITION_REORGANIZE));
(alter_info.partition_flags & (ALTER_PARTITION_ADD |
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,
uint32 part_id);
bool compare_partition_options(HA_CREATE_INFO *table_create_info,
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 write_log_replace_frm(ALTER_PARTITION_PARAM_TYPE *lpt,
uint next_entry,
const char *from_path,
const char *to_path);
#else
#define partition_key_modified(X,Y) 0
#endif
......
......@@ -192,10 +192,8 @@ static bool check_exchange_partition(TABLE *table, TABLE *part_table)
@param part_table Partitioned table.
@param part_elem Partition element to use for partition specific compare.
*/
static bool compare_table_with_partition(THD *thd, TABLE *table,
TABLE *part_table,
partition_element *part_elem,
uint part_id)
bool compare_table_with_partition(THD *thd, TABLE *table, TABLE *part_table,
partition_element *part_elem, uint part_id)
{
HA_CREATE_INFO table_create_info, part_create_info;
Alter_info part_alter_info;
......@@ -292,7 +290,7 @@ static bool compare_table_with_partition(THD *thd, TABLE *table,
The workaround is to use REORGANIZE PARTITION to rewrite
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(FALSE);
......@@ -988,4 +986,53 @@ bool Sql_cmd_alter_table_truncate_partition::execute(THD *thd)
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 */
......@@ -875,7 +875,6 @@ bool mysql_write_frm(ALTER_PARTITION_PARAM_TYPE *lpt, uint flags)
#else /* !WITH_PARTITION_STORAGE_ENGINE */
DBUG_ASSERT(!(flags & WFRM_WRITE_EXTRACTED));
DBUG_ASSERT(!(flags & WFRM_BACKUP_ORIGINAL));
DBUG_ASSERT(!(flags & WFRM_DROP_BACKUP));
#endif /* !WITH_PARTITION_STORAGE_ENGINE */
if (flags & WFRM_INSTALL_SHADOW)
{
......@@ -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
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() */
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), alter_ctx.new_alias.str);
......
......@@ -7290,6 +7290,43 @@ alter_commands:
MYSQL_YYABORT;
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:
......
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