diff --git a/mysql-test/include/binlog_combinations.combinations b/mysql-test/include/binlog_combinations.combinations new file mode 100644 index 00000000000..07042c2cbec --- /dev/null +++ b/mysql-test/include/binlog_combinations.combinations @@ -0,0 +1,8 @@ +[row] +binlog-format=row + +[stmt] +binlog-format=statement + +[mix] +binlog-format=mixed diff --git a/mysql-test/include/binlog_combinations.inc b/mysql-test/include/binlog_combinations.inc new file mode 100644 index 00000000000..2ddd787681a --- /dev/null +++ b/mysql-test/include/binlog_combinations.inc @@ -0,0 +1,5 @@ +# The goal of including this file is to test with different +# binlog combinations: row, stmt or mix +# (see include/binlog_combinations.combinations) + +--source include/have_log_bin.inc diff --git a/mysql-test/include/lcase_names.combinations b/mysql-test/include/lcase_names.combinations new file mode 100644 index 00000000000..7fd344eab3f --- /dev/null +++ b/mysql-test/include/lcase_names.combinations @@ -0,0 +1,5 @@ +[lcase_def] +[lcase1] +lower_case_table_names=1 +[lcase2] +lower_case_table_names=2 diff --git a/mysql-test/include/lcase_names.inc b/mysql-test/include/lcase_names.inc new file mode 100644 index 00000000000..983e2678d29 --- /dev/null +++ b/mysql-test/include/lcase_names.inc @@ -0,0 +1,2 @@ +# The goal of including this file is to test with different +# lower_case_table_names modes (see include/lcase_name.combinations) diff --git a/mysql-test/suite/atomic/alter_partition.combinations b/mysql-test/suite/atomic/alter_partition.combinations new file mode 100644 index 00000000000..898d2f2f332 --- /dev/null +++ b/mysql-test/suite/atomic/alter_partition.combinations @@ -0,0 +1,6 @@ +[innodb] +innodb + +[myisam] + +[aria] diff --git a/mysql-test/suite/atomic/alter_partition.result b/mysql-test/suite/atomic/alter_partition.result new file mode 100644 index 00000000000..32344d7c192 --- /dev/null +++ b/mysql-test/suite/atomic/alter_partition.result @@ -0,0 +1,273 @@ +# Crash recovery +create or replace procedure prepare_table() +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); +insert into t1 values (2), (12), (22); +flush tables; +end $ +# QUERY: ALTER TABLE t1 CONVERT PARTITION p1 TO TABLE tp1 +# CRASH: ddl_log_create_before_create_frm +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.frm +t1.par +Table Create Table +t1 CREATE TABLE `t1` ( + `x` int(11) DEFAULT NULL +) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING + PARTITION BY RANGE (`x`) +(PARTITION `p0` VALUES LESS THAN (10) ENGINE = DEFAULT_ENGINE, + PARTITION `p1` VALUES LESS THAN (20) ENGINE = DEFAULT_ENGINE, + PARTITION `pn` VALUES LESS THAN MAXVALUE ENGINE = DEFAULT_ENGINE) +x +2 +12 +22 +# CRASH: ddl_log_alter_partition_after_create_frm +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.frm +t1.par +Table Create Table +t1 CREATE TABLE `t1` ( + `x` int(11) DEFAULT NULL +) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING + PARTITION BY RANGE (`x`) +(PARTITION `p0` VALUES LESS THAN (10) ENGINE = DEFAULT_ENGINE, + PARTITION `p1` VALUES LESS THAN (20) ENGINE = DEFAULT_ENGINE, + PARTITION `pn` VALUES LESS THAN MAXVALUE ENGINE = DEFAULT_ENGINE) +x +2 +12 +22 +# CRASH: ddl_log_alter_partition_after_write_frm +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.frm +t1.par +Table Create Table +t1 CREATE TABLE `t1` ( + `x` int(11) DEFAULT NULL +) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING + PARTITION BY RANGE (`x`) +(PARTITION `p0` VALUES LESS THAN (10) ENGINE = DEFAULT_ENGINE, + PARTITION `p1` VALUES LESS THAN (20) ENGINE = DEFAULT_ENGINE, + PARTITION `pn` VALUES LESS THAN MAXVALUE ENGINE = DEFAULT_ENGINE) +x +2 +12 +22 +# 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.frm +t1.par +Table Create Table +t1 CREATE TABLE `t1` ( + `x` int(11) DEFAULT NULL +) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING + PARTITION BY RANGE (`x`) +(PARTITION `p0` VALUES LESS THAN (10) ENGINE = DEFAULT_ENGINE, + PARTITION `p1` VALUES LESS THAN (20) ENGINE = DEFAULT_ENGINE, + PARTITION `pn` VALUES LESS THAN MAXVALUE ENGINE = DEFAULT_ENGINE) +x +2 +12 +22 +# 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.frm +t1.par +Table Create Table +t1 CREATE TABLE `t1` ( + `x` int(11) DEFAULT NULL +) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING + PARTITION BY RANGE (`x`) +(PARTITION `p0` VALUES LESS THAN (10) ENGINE = DEFAULT_ENGINE, + PARTITION `p1` VALUES LESS THAN (20) ENGINE = DEFAULT_ENGINE, + PARTITION `pn` VALUES LESS THAN MAXVALUE ENGINE = DEFAULT_ENGINE) +x +2 +12 +22 +# 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.frm +t1.par +Table Create Table +t1 CREATE TABLE `t1` ( + `x` int(11) DEFAULT NULL +) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING + PARTITION BY RANGE (`x`) +(PARTITION `p0` VALUES LESS THAN (10) ENGINE = DEFAULT_ENGINE, + PARTITION `p1` VALUES LESS THAN (20) ENGINE = DEFAULT_ENGINE, + PARTITION `pn` VALUES LESS THAN MAXVALUE ENGINE = DEFAULT_ENGINE) +x +2 +12 +22 +# 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.frm +t1.par +Table Create Table +t1 CREATE TABLE `t1` ( + `x` int(11) DEFAULT NULL +) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING + PARTITION BY RANGE (`x`) +(PARTITION `p0` VALUES LESS THAN (10) ENGINE = DEFAULT_ENGINE, + PARTITION `p1` VALUES LESS THAN (20) ENGINE = DEFAULT_ENGINE, + PARTITION `pn` VALUES LESS THAN MAXVALUE ENGINE = DEFAULT_ENGINE) +x +2 +12 +22 +# 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.frm +t1.par +Table Create Table +t1 CREATE TABLE `t1` ( + `x` int(11) DEFAULT NULL +) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING + PARTITION BY RANGE (`x`) +(PARTITION `p0` VALUES LESS THAN (10) ENGINE = DEFAULT_ENGINE, + PARTITION `p1` VALUES LESS THAN (20) ENGINE = DEFAULT_ENGINE, + PARTITION `pn` VALUES LESS THAN MAXVALUE ENGINE = DEFAULT_ENGINE) +x +2 +12 +22 +# 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.frm +t1.par +Table Create Table +t1 CREATE TABLE `t1` ( + `x` int(11) DEFAULT NULL +) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING + PARTITION BY RANGE (`x`) +(PARTITION `p0` VALUES LESS THAN (10) ENGINE = DEFAULT_ENGINE, + PARTITION `p1` VALUES LESS THAN (20) ENGINE = DEFAULT_ENGINE, + PARTITION `pn` VALUES LESS THAN MAXVALUE ENGINE = DEFAULT_ENGINE) +x +2 +12 +22 +# 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.frm +t1.par +Table Create Table +t1 CREATE TABLE `t1` ( + `x` int(11) DEFAULT NULL +) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING + PARTITION BY RANGE (`x`) +(PARTITION `p0` VALUES LESS THAN (10) ENGINE = DEFAULT_ENGINE, + PARTITION `p1` VALUES LESS THAN (20) ENGINE = DEFAULT_ENGINE, + PARTITION `pn` VALUES LESS THAN MAXVALUE ENGINE = DEFAULT_ENGINE) +x +2 +12 +22 +# 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.frm +t1.par +Table Create Table +t1 CREATE TABLE `t1` ( + `x` int(11) DEFAULT NULL +) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING + PARTITION BY RANGE (`x`) +(PARTITION `p0` VALUES LESS THAN (10) ENGINE = DEFAULT_ENGINE, + PARTITION `p1` VALUES LESS THAN (20) ENGINE = DEFAULT_ENGINE, + PARTITION `pn` VALUES LESS THAN MAXVALUE ENGINE = DEFAULT_ENGINE) +x +2 +12 +22 +# CRASH: crash_convert_partition_9 +t1#P#p0.MYD +t1#P#p0.MYI +t1#P#pn.MYD +t1#P#pn.MYI +t1.frm +t1.par +tp1.MYD +tp1.MYI +tp1.frm +master-bin.000001 # Query # # use `test`; ALTER TABLE t1 CONVERT PARTITION p1 TO TABLE tp1 +Table Create Table +t1 CREATE TABLE `t1` ( + `x` int(11) DEFAULT NULL +) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING + PARTITION BY RANGE (`x`) +(PARTITION `p0` VALUES LESS THAN (10) ENGINE = DEFAULT_ENGINE, + PARTITION `pn` VALUES LESS THAN MAXVALUE ENGINE = DEFAULT_ENGINE) +x +2 +22 +Table Create Table +tp1 CREATE TABLE `tp1` ( + `x` int(11) DEFAULT NULL +) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING +x +12 +Warnings: +Note 1051 Unknown table 'test.t1' diff --git a/mysql-test/suite/atomic/alter_partition.test b/mysql-test/suite/atomic/alter_partition.test new file mode 100644 index 00000000000..9398b886507 --- /dev/null +++ b/mysql-test/suite/atomic/alter_partition.test @@ -0,0 +1,159 @@ +--source include/have_partition.inc +--source include/have_debug.inc +--source include/have_sequence.inc +--source include/binlog_combinations.inc +--source include/have_binlog_format_row_or_statement.inc +--source include/not_valgrind.inc + +let $default_engine=InnoDB; +let $extra_option=; +let $save_debug=`select @@debug_dbug`; + +if ($MTR_COMBINATION_MYISAM) +{ + let $default_engine=MyISAM; +} +if ($MTR_COMBINATION_ARIA) +{ + let $default_engine=Aria; + let $extra_option=transactional=1; +} + +if ($MTR_COMBINATION_STMT) +{ + let $binlog_format=include/set_binlog_format_statement.sql; +} +if ($MTR_COMBINATION_ROW) +{ + let $binlog_format=include/set_binlog_format_row.sql; +} + +--disable_query_log +--eval set @@default_storage_engine=$default_engine +--enable_query_log + +--echo # Crash recovery + +let $MYSQLD_DATADIR= `SELECT @@datadir`; + +let $crash_count= 12; +let $crash_points='ddl_log_create_before_create_frm', + 'ddl_log_alter_partition_after_create_frm', + 'ddl_log_alter_partition_after_write_frm', + 'crash_convert_partition_1', + 'crash_convert_partition_2', + 'crash_convert_partition_3', + 'crash_convert_partition_4', + 'crash_convert_partition_5', + 'crash_convert_partition_6', + 'crash_convert_partition_7', + 'crash_convert_partition_8', + 'crash_convert_partition_9'; + +#let $crash_count= 1; +#let $crash_points= 'crash_convert_partition_8'; + +let $statement_count= 1; +let $statements= 'ALTER TABLE t1 CONVERT PARTITION p1 TO TABLE tp1'; + +#let $statement_count=1; +#let $statements='CREATE OR REPLACE TABLE t1 SELECT * from const_table'; + +--delimiter $ +create or replace procedure prepare_table() +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); + insert into t1 values (2), (12), (22); + flush tables; +end $ +--delimiter ; + +let $old_debug=`select @@debug_dbug`; + +let $keep_include_silent=1; +let $grep_script=ALTER; +--disable_query_log + +let $r=0; +while ($r < $statement_count) +{ + inc $r; + let $statement=`select ELT($r, $statements)`; + --echo # QUERY: $statement + + let $c=0; + while ($c < $crash_count) + { + inc $c; + let $crash=`select ELT($c, $crash_points)`; + + --eval set @@default_storage_engine=$default_engine + call prepare_table; + if (!$c) + { + lock tables t1 write; + } + + --source $binlog_format + + RESET MASTER; + --exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect + --disable_reconnect + --eval set @@debug_dbug="+d,$crash",@debug_crash_counter=1 + let $errno=0; + --error 0,2013 + --eval $statement; + let $error=$errno; + --enable_reconnect + --source include/wait_until_connected_again.inc + --disable_query_log + --eval set @@debug_dbug="$old_debug" + + if ($error == 0) + { + --echo # NO CRASH: $crash + } + if ($error) + { + --echo # CRASH: $crash + } + # Check which tables still exists + --replace_result MAI MYI MAD MYD + --list_files $MYSQLD_DATADIR/test t* + --replace_regex /backup-\d+/backup/ + --list_files $MYSQLD_DATADIR/test *sql* + --remove_files_wildcard $MYSQLD_DATADIR/test *sql-backup-* + + --let $binlog_file=master-bin.000001 + --source include/show_binlog_events.inc + if ($error) + { + --let $binlog_file=master-bin.000002 + --source include/show_binlog_events.inc + } + + --replace_result $default_engine DEFAULT_ENGINE ' PAGE_CHECKSUM=1' '' + show create table t1; + select * from t1; + --replace_result $default_engine DEFAULT_ENGINE ' PAGE_CHECKSUM=1' '' + --error 0, ER_NO_SUCH_TABLE + show create table tp1; + --error 0, ER_NO_SUCH_TABLE + select * from tp1; + # Drop the tables. The warnings will show what was dropped + --disable_warnings + drop table t1; + drop table if exists tp1; + --enable_warnings + } +} +drop table if exists t1; +drop procedure prepare_table; +--eval set @@debug_dbug="$save_debug" + +--enable_query_log diff --git a/mysql-test/suite/parts/inc/engines.combinations b/mysql-test/suite/parts/inc/engines.combinations new file mode 100644 index 00000000000..17e01265006 --- /dev/null +++ b/mysql-test/suite/parts/inc/engines.combinations @@ -0,0 +1,8 @@ +[innodb] +default-storage-engine=innodb + +[myisam] +default-storage-engine=myisam + +[aria] +default-storage-engine=aria diff --git a/mysql-test/suite/parts/inc/engines.inc b/mysql-test/suite/parts/inc/engines.inc new file mode 100644 index 00000000000..b8995ef08ec --- /dev/null +++ b/mysql-test/suite/parts/inc/engines.inc @@ -0,0 +1,4 @@ +--source include/have_innodb.inc + +let $engine= `select @@default_storage_engine`; + diff --git a/mysql-test/suite/parts/r/alter_table,list.rdiff b/mysql-test/suite/parts/r/alter_table,list.rdiff new file mode 100644 index 00000000000..090eb42de84 --- /dev/null +++ b/mysql-test/suite/parts/r/alter_table,list.rdiff @@ -0,0 +1,87 @@ +--- alter_table.result ++++ alter_table,list.reject +@@ -62,13 +62,13 @@ + partition pn values less than maxvalue); + ERROR HY000: Partitioned tables do not support CREATE TEMPORARY TABLE + create or replace table t1 (x int) +-partition by range(x) ( +-partition p1 values less than (10), +-partition p2 values less than (20), +-partition p3 values less than (30), +-partition p4 values less than (40), +-partition p5 values less than (50), +-partition pn values less than maxvalue); ++partition by list(x) ( ++partition p1 values in (2, 3, 4), ++partition p2 values in (12, 13, 14), ++partition p3 values in (22, 23, 24), ++partition p4 values in (32, 33, 34), ++partition p5 values in (42, 43, 44), ++partition pn values in (52, 53, 54)); + insert into t1 values (2), (12), (22), (32), (42), (52); + create or replace table tp2 (y int); + insert tp2 values (88); +@@ -108,12 +108,12 @@ + t1 CREATE TABLE `t1` ( + `x` int(11) DEFAULT NULL + ) ENGINE=X DEFAULT CHARSET=latin1 +- PARTITION BY RANGE (`x`) +-(PARTITION `p1` VALUES LESS THAN (10) ENGINE = X, +- PARTITION `p3` VALUES LESS THAN (30) ENGINE = X, +- PARTITION `p4` VALUES LESS THAN (40) ENGINE = X, +- PARTITION `p5` VALUES LESS THAN (50) ENGINE = X, +- PARTITION `pn` VALUES LESS THAN MAXVALUE ENGINE = X) ++ PARTITION BY LIST (`x`) ++(PARTITION `p1` VALUES IN (2,3,4) ENGINE = X, ++ PARTITION `p3` VALUES IN (22,23,24) ENGINE = X, ++ PARTITION `p4` VALUES IN (32,33,34) ENGINE = X, ++ PARTITION `p5` VALUES IN (42,43,44) ENGINE = X, ++ PARTITION `pn` VALUES IN (52,53,54) ENGINE = X) + select * from t1 order by x; + x + 2 +@@ -138,11 +138,11 @@ + t1 CREATE TABLE `t1` ( + `x` int(11) DEFAULT NULL + ) ENGINE=X DEFAULT CHARSET=latin1 +- PARTITION BY RANGE (`x`) +-(PARTITION `p1` VALUES LESS THAN (10) ENGINE = X, +- PARTITION `p4` VALUES LESS THAN (40) ENGINE = X, +- PARTITION `p5` VALUES LESS THAN (50) ENGINE = X, +- PARTITION `pn` VALUES LESS THAN MAXVALUE ENGINE = X) ++ PARTITION BY LIST (`x`) ++(PARTITION `p1` VALUES IN (2,3,4) ENGINE = X, ++ PARTITION `p4` VALUES IN (32,33,34) ENGINE = X, ++ PARTITION `p5` VALUES IN (42,43,44) ENGINE = X, ++ PARTITION `pn` VALUES IN (52,53,54) ENGINE = X) + select * from t1 order by x; + x + 2 +@@ -168,10 +168,10 @@ + t1 CREATE TABLE `t1` ( + `x` int(11) DEFAULT NULL + ) ENGINE=X DEFAULT CHARSET=latin1 +- PARTITION BY RANGE (`x`) +-(PARTITION `p1` VALUES LESS THAN (10) ENGINE = X, +- PARTITION `p5` VALUES LESS THAN (50) ENGINE = X, +- PARTITION `pn` VALUES LESS THAN MAXVALUE ENGINE = X) ++ PARTITION BY LIST (`x`) ++(PARTITION `p1` VALUES IN (2,3,4) ENGINE = X, ++ PARTITION `p5` VALUES IN (42,43,44) ENGINE = X, ++ PARTITION `pn` VALUES IN (52,53,54) ENGINE = X) + select * from t1 order by x; + x + 2 +@@ -193,9 +193,9 @@ + t1 CREATE TABLE `t1` ( + `x` int(11) DEFAULT NULL + ) ENGINE=X DEFAULT CHARSET=latin1 +- PARTITION BY RANGE (`x`) +-(PARTITION `p1` VALUES LESS THAN (10) ENGINE = X, +- PARTITION `pn` VALUES LESS THAN MAXVALUE ENGINE = X) ++ PARTITION BY LIST (`x`) ++(PARTITION `p1` VALUES IN (2,3,4) ENGINE = X, ++ PARTITION `pn` VALUES IN (52,53,54) ENGINE = X) + select * from t1 order by x; + x + 2 diff --git a/mysql-test/suite/parts/r/alter_table.result b/mysql-test/suite/parts/r/alter_table.result index 94100b83118..b18790c547e 100644 --- a/mysql-test/suite/parts/r/alter_table.result +++ b/mysql-test/suite/parts/r/alter_table.result @@ -28,3 +28,239 @@ ALTER TABLE v1 EXCHANGE PARTITION p2 WITH TABLE t2 ; ERROR 42000: Can't open table DROP VIEW v1; DROP TABLE t1, t2; +# +# MDEV-22166 MIGRATE PARTITION: move out partition into a table +# +create or replace table t1 (x int); +alter table t1 convert partition p1 to table tp1; +ERROR HY000: Partition management on a not partitioned table is not possible +create or replace table t1 (x int) +partition by hash(x) partitions 2; +alter table t1 convert partition p1 to table tp1; +ERROR HY000: CONVERT PARTITION can only be used on RANGE/LIST partitions +create or replace table t1 (x int) +partition by key(x) partitions 2; +alter table t1 convert partition p1 to table tp1; +ERROR HY000: CONVERT PARTITION can only be used on RANGE/LIST partitions +create or replace table t1 (x int) +partition by range(x) +subpartition by hash(x) subpartitions 3 ( +partition p1 values less than (10), +partition pn values less than maxvalue); +alter table t1 convert partition p1 to table p1; +ERROR HY000: Convert partition is not supported for subpartitioned table. +alter table t1 convert partition p1sp0 to table p1; +ERROR HY000: Wrong partition name or partition list +create or replace table t1 (x int) +partition by range(x) ( +partition p1 values less than (10)); +alter table t1 convert partition p1 to table tp1; +ERROR HY000: Cannot remove all partitions, use DROP TABLE instead +create or replace temporary table t1 (x int) +partition by range(x) ( +partition p0 values less than (10), +partition pn values less than maxvalue); +ERROR HY000: Partitioned tables do not support CREATE TEMPORARY TABLE +create or replace table t1 (x int) +partition by range(x) ( +partition p1 values less than (10), +partition p2 values less than (20), +partition p3 values less than (30), +partition p4 values less than (40), +partition p5 values less than (50), +partition pn values less than maxvalue); +insert into t1 values (2), (12), (22), (32), (42), (52); +create or replace table tp2 (y int); +insert tp2 values (88); +alter table t1 convert partition p2 to table tp2, drop partition p3; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ' drop partition p3' at line 1 +alter table t1 convert partition p00 to table tp00; +ERROR HY000: Wrong partition name or partition list +alter table t1 convert partition p00 to table tp2; +ERROR 42S01: Table 'tp2' already exists +alter table t1 convert partition p2 to table tp2; +ERROR 42S01: Table 'tp2' already exists +create trigger tr1 before update on t1 for each row +begin +alter table t1 convert partition p2 to table tp2; +end$ +ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger +create function f1() returns int +begin +alter table t1 convert partition p2 to table tp2; +end$ +ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger +select * from tp2; +y +88 +drop table tp2; +alter table t1 convert partition p2 to table tp2; +show create table tp2; +Table Create Table +tp2 CREATE TABLE `tp2` ( + `x` int(11) DEFAULT NULL +) ENGINE=X DEFAULT CHARSET=latin1 +select * from tp2; +x +12 +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `x` int(11) DEFAULT NULL +) ENGINE=X DEFAULT CHARSET=latin1 + PARTITION BY RANGE (`x`) +(PARTITION `p1` VALUES LESS THAN (10) ENGINE = X, + PARTITION `p3` VALUES LESS THAN (30) ENGINE = X, + PARTITION `p4` VALUES LESS THAN (40) ENGINE = X, + PARTITION `p5` VALUES LESS THAN (50) ENGINE = X, + PARTITION `pn` VALUES LESS THAN MAXVALUE ENGINE = X) +select * from t1 order by x; +x +2 +22 +32 +42 +52 +alter table t1 convert partition p3 to table inexistent.tp3; +ERROR 42000: Unknown database 'inexistent' +create database EXISTENT; +alter table t1 convert partition p3 to table EXISTENT.TP3; +show create table EXISTENT.TP3; +Table Create Table +TP3 CREATE TABLE `TP3`-ok ( + `x` int(11) DEFAULT NULL +) ENGINE=X DEFAULT CHARSET=latin1 +select * from EXISTENT.TP3 order by x; +x +22 +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `x` int(11) DEFAULT NULL +) ENGINE=X DEFAULT CHARSET=latin1 + PARTITION BY RANGE (`x`) +(PARTITION `p1` VALUES LESS THAN (10) ENGINE = X, + PARTITION `p4` VALUES LESS THAN (40) ENGINE = X, + PARTITION `p5` VALUES LESS THAN (50) ENGINE = X, + PARTITION `pn` VALUES LESS THAN MAXVALUE ENGINE = X) +select * from t1 order by x; +x +2 +32 +42 +52 +# LOCK TABLES +lock tables t1 write; +alter table t1 convert partition p4 to table tp4; +show create table tp4; +ERROR HY000: Table 'tp4' was not locked with LOCK TABLES +unlock tables; +show create table tp4; +Table Create Table +tp4 CREATE TABLE `tp4` ( + `x` int(11) DEFAULT NULL +) ENGINE=X DEFAULT CHARSET=latin1 +select * from tp4; +x +32 +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `x` int(11) DEFAULT NULL +) ENGINE=X DEFAULT CHARSET=latin1 + PARTITION BY RANGE (`x`) +(PARTITION `p1` VALUES LESS THAN (10) ENGINE = X, + PARTITION `p5` VALUES LESS THAN (50) ENGINE = X, + PARTITION `pn` VALUES LESS THAN MAXVALUE ENGINE = X) +select * from t1 order by x; +x +2 +42 +52 +# PS +prepare stmt from 'alter table t1 convert partition p5 to table tp5'; +execute stmt; +show create table tp5; +Table Create Table +tp5 CREATE TABLE `tp5` ( + `x` int(11) DEFAULT NULL +) ENGINE=X DEFAULT CHARSET=latin1 +select * from tp5; +x +42 +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `x` int(11) DEFAULT NULL +) ENGINE=X DEFAULT CHARSET=latin1 + PARTITION BY RANGE (`x`) +(PARTITION `p1` VALUES LESS THAN (10) ENGINE = X, + PARTITION `pn` VALUES LESS THAN MAXVALUE ENGINE = X) +select * from t1 order by x; +x +2 +52 +drop table tp5; +execute stmt; +ERROR HY000: Wrong partition name or partition list +execute stmt; +ERROR HY000: Wrong partition name or partition list +drop prepare stmt; +# Privileges +create user alan; +grant usage on *.* to alan; +grant create, insert, drop on test.* to alan; +connect alan,localhost,alan,,test; +show grants for current_user; +Grants for alan@% +GRANT USAGE ON *.* TO `alan`@`%` +GRANT INSERT, CREATE, DROP ON `test`.* TO `alan`@`%` +alter table t1 convert partition p1 to table tp1; +ERROR 42000: ALTER command denied to user 'alan'@'localhost' for table 't1' +connection default; +revoke all on test.* from alan; +grant create, insert, alter on test.* to alan; +connection alan; +use test; +show grants for current_user; +Grants for alan@% +GRANT USAGE ON *.* TO `alan`@`%` +GRANT INSERT, CREATE, ALTER ON `test`.* TO `alan`@`%` +alter table t1 convert partition p1 to table tp1; +ERROR 42000: DROP command denied to user 'alan'@'localhost' for table 't1' +connection default; +revoke all on test.* from alan; +grant create, drop, alter on test.* to alan; +connection alan; +use test; +show grants for current_user; +Grants for alan@% +GRANT USAGE ON *.* TO `alan`@`%` +GRANT CREATE, DROP, ALTER ON `test`.* TO `alan`@`%` +alter table t1 convert partition p1 to table tp1; +ERROR 42000: INSERT command denied to user 'alan'@'localhost' for table 'tp1' +connection default; +revoke all on test.* from alan; +grant insert, drop, alter on test.* to alan; +connection alan; +use test; +show grants for current_user; +Grants for alan@% +GRANT USAGE ON *.* TO `alan`@`%` +GRANT INSERT, DROP, ALTER ON `test`.* TO `alan`@`%` +alter table t1 convert partition p1 to table tp1; +ERROR 42000: CREATE command denied to user 'alan'@'localhost' for table 'tp1' +connection default; +grant create, insert, drop, alter on test.* to alan; +connection alan; +use test; +show grants for current_user; +Grants for alan@% +GRANT USAGE ON *.* TO `alan`@`%` +GRANT INSERT, CREATE, DROP, ALTER ON `test`.* TO `alan`@`%` +alter table t1 convert partition p1 to table tp1; +disconnect alan; +connection default; +drop database EXISTENT; +drop user alan; +drop tables t1, tp1, tp2, tp4; diff --git a/mysql-test/suite/parts/r/partition_debug.result b/mysql-test/suite/parts/r/partition_debug.result index 571ab329bc2..6a69fa0337a 100644 --- a/mysql-test/suite/parts/r/partition_debug.result +++ b/mysql-test/suite/parts/r/partition_debug.result @@ -1958,3 +1958,2135 @@ a b 4 Original from partition p0 DROP TABLE t2; SET SESSION debug_dbug=@save_dbug; +# +# MDEV-22166 MIGRATE PARTITION: move out partition into a table +# +set @save_dbug=@@debug_dbug; +set session debug_dbug="+d,fail_create_before_create_frm"; +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), +partition p4 values less than (40), +partition p5 values less than (50), +partition pn values less than maxvalue); +insert into t1 values (2), (12), (22), (32), (42), (52); +# d,fail_create_before_create_frm: BEFORE failure +db.opt +t1#P#p1.MYD +t1#P#p1.MYI +t1#P#p2.MYD +t1#P#p2.MYI +t1#P#p3.MYD +t1#P#p3.MYI +t1#P#p4.MYD +t1#P#p4.MYI +t1#P#p5.MYD +t1#P#p5.MYI +t1#P#pn.MYD +t1#P#pn.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `x` int(11) NOT NULL, + PRIMARY KEY (`x`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 + PARTITION BY RANGE (`x`) +(PARTITION `p1` VALUES LESS THAN (10) ENGINE = MyISAM, + PARTITION `p2` VALUES LESS THAN (20) ENGINE = MyISAM, + PARTITION `p3` VALUES LESS THAN (30) ENGINE = MyISAM, + PARTITION `p4` VALUES LESS THAN (40) ENGINE = MyISAM, + PARTITION `p5` VALUES LESS THAN (50) ENGINE = MyISAM, + PARTITION `pn` VALUES LESS THAN MAXVALUE ENGINE = MyISAM) +SELECT * FROM t1; +x +12 +2 +22 +32 +42 +52 +alter table t1 convert partition p2 to table tp2; +ERROR HY000: Unknown error +# d,fail_create_before_create_frm: AFTER failure +db.opt +t1#P#p1.MYD +t1#P#p1.MYI +t1#P#p2.MYD +t1#P#p2.MYI +t1#P#p3.MYD +t1#P#p3.MYI +t1#P#p4.MYD +t1#P#p4.MYI +t1#P#p5.MYD +t1#P#p5.MYI +t1#P#pn.MYD +t1#P#pn.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `x` int(11) NOT NULL, + PRIMARY KEY (`x`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 + PARTITION BY RANGE (`x`) +(PARTITION `p1` VALUES LESS THAN (10) ENGINE = MyISAM, + PARTITION `p2` VALUES LESS THAN (20) ENGINE = MyISAM, + PARTITION `p3` VALUES LESS THAN (30) ENGINE = MyISAM, + PARTITION `p4` VALUES LESS THAN (40) ENGINE = MyISAM, + PARTITION `p5` VALUES LESS THAN (50) ENGINE = MyISAM, + PARTITION `pn` VALUES LESS THAN MAXVALUE ENGINE = MyISAM) +SELECT * FROM t1; +x +12 +2 +22 +32 +42 +52 +DROP TABLE t1; +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), +partition p4 values less than (40), +partition p5 values less than (50), +partition pn values less than maxvalue); +insert into t1 values (2), (12), (22), (32), (42), (52); +# d,fail_create_before_create_frm: BEFORE failure (under LOCK TABLE) +db.opt +t1#P#p1.MYD +t1#P#p1.MYI +t1#P#p2.MYD +t1#P#p2.MYI +t1#P#p3.MYD +t1#P#p3.MYI +t1#P#p4.MYD +t1#P#p4.MYI +t1#P#p5.MYD +t1#P#p5.MYI +t1#P#pn.MYD +t1#P#pn.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `x` int(11) NOT NULL, + PRIMARY KEY (`x`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 + PARTITION BY RANGE (`x`) +(PARTITION `p1` VALUES LESS THAN (10) ENGINE = MyISAM, + PARTITION `p2` VALUES LESS THAN (20) ENGINE = MyISAM, + PARTITION `p3` VALUES LESS THAN (30) ENGINE = MyISAM, + PARTITION `p4` VALUES LESS THAN (40) ENGINE = MyISAM, + PARTITION `p5` VALUES LESS THAN (50) ENGINE = MyISAM, + PARTITION `pn` VALUES LESS THAN MAXVALUE ENGINE = MyISAM) +SELECT * FROM t1; +x +12 +2 +22 +32 +42 +52 +LOCK TABLE t1 WRITE; +alter table t1 convert partition p2 to table tp2; +ERROR HY000: Unknown error +# d,fail_create_before_create_frm: AFTER failure (under LOCK TABLE) +db.opt +t1#P#p1.MYD +t1#P#p1.MYI +t1#P#p2.MYD +t1#P#p2.MYI +t1#P#p3.MYD +t1#P#p3.MYI +t1#P#p4.MYD +t1#P#p4.MYI +t1#P#p5.MYD +t1#P#p5.MYI +t1#P#pn.MYD +t1#P#pn.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `x` int(11) NOT NULL, + PRIMARY KEY (`x`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 + PARTITION BY RANGE (`x`) +(PARTITION `p1` VALUES LESS THAN (10) ENGINE = MyISAM, + PARTITION `p2` VALUES LESS THAN (20) ENGINE = MyISAM, + PARTITION `p3` VALUES LESS THAN (30) ENGINE = MyISAM, + PARTITION `p4` VALUES LESS THAN (40) ENGINE = MyISAM, + PARTITION `p5` VALUES LESS THAN (50) ENGINE = MyISAM, + PARTITION `pn` VALUES LESS THAN MAXVALUE ENGINE = MyISAM) +SELECT * FROM t1; +x +12 +2 +22 +32 +42 +52 +UNLOCK TABLES; +DROP TABLE t1; +set session debug_dbug=@save_dbug; +set session debug_dbug="+d,fail_alter_partition_after_write_frm"; +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), +partition p4 values less than (40), +partition p5 values less than (50), +partition pn values less than maxvalue); +insert into t1 values (2), (12), (22), (32), (42), (52); +# d,fail_alter_partition_after_write_frm: BEFORE failure +db.opt +t1#P#p1.MYD +t1#P#p1.MYI +t1#P#p2.MYD +t1#P#p2.MYI +t1#P#p3.MYD +t1#P#p3.MYI +t1#P#p4.MYD +t1#P#p4.MYI +t1#P#p5.MYD +t1#P#p5.MYI +t1#P#pn.MYD +t1#P#pn.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `x` int(11) NOT NULL, + PRIMARY KEY (`x`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 + PARTITION BY RANGE (`x`) +(PARTITION `p1` VALUES LESS THAN (10) ENGINE = MyISAM, + PARTITION `p2` VALUES LESS THAN (20) ENGINE = MyISAM, + PARTITION `p3` VALUES LESS THAN (30) ENGINE = MyISAM, + PARTITION `p4` VALUES LESS THAN (40) ENGINE = MyISAM, + PARTITION `p5` VALUES LESS THAN (50) ENGINE = MyISAM, + PARTITION `pn` VALUES LESS THAN MAXVALUE ENGINE = MyISAM) +SELECT * FROM t1; +x +12 +2 +22 +32 +42 +52 +alter table t1 convert partition p2 to table tp2; +ERROR HY000: Unknown error +# d,fail_alter_partition_after_write_frm: AFTER failure +db.opt +t1#P#p1.MYD +t1#P#p1.MYI +t1#P#p2.MYD +t1#P#p2.MYI +t1#P#p3.MYD +t1#P#p3.MYI +t1#P#p4.MYD +t1#P#p4.MYI +t1#P#p5.MYD +t1#P#p5.MYI +t1#P#pn.MYD +t1#P#pn.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `x` int(11) NOT NULL, + PRIMARY KEY (`x`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 + PARTITION BY RANGE (`x`) +(PARTITION `p1` VALUES LESS THAN (10) ENGINE = MyISAM, + PARTITION `p2` VALUES LESS THAN (20) ENGINE = MyISAM, + PARTITION `p3` VALUES LESS THAN (30) ENGINE = MyISAM, + PARTITION `p4` VALUES LESS THAN (40) ENGINE = MyISAM, + PARTITION `p5` VALUES LESS THAN (50) ENGINE = MyISAM, + PARTITION `pn` VALUES LESS THAN MAXVALUE ENGINE = MyISAM) +SELECT * FROM t1; +x +12 +2 +22 +32 +42 +52 +DROP TABLE t1; +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), +partition p4 values less than (40), +partition p5 values less than (50), +partition pn values less than maxvalue); +insert into t1 values (2), (12), (22), (32), (42), (52); +# d,fail_alter_partition_after_write_frm: BEFORE failure (under LOCK TABLE) +db.opt +t1#P#p1.MYD +t1#P#p1.MYI +t1#P#p2.MYD +t1#P#p2.MYI +t1#P#p3.MYD +t1#P#p3.MYI +t1#P#p4.MYD +t1#P#p4.MYI +t1#P#p5.MYD +t1#P#p5.MYI +t1#P#pn.MYD +t1#P#pn.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `x` int(11) NOT NULL, + PRIMARY KEY (`x`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 + PARTITION BY RANGE (`x`) +(PARTITION `p1` VALUES LESS THAN (10) ENGINE = MyISAM, + PARTITION `p2` VALUES LESS THAN (20) ENGINE = MyISAM, + PARTITION `p3` VALUES LESS THAN (30) ENGINE = MyISAM, + PARTITION `p4` VALUES LESS THAN (40) ENGINE = MyISAM, + PARTITION `p5` VALUES LESS THAN (50) ENGINE = MyISAM, + PARTITION `pn` VALUES LESS THAN MAXVALUE ENGINE = MyISAM) +SELECT * FROM t1; +x +12 +2 +22 +32 +42 +52 +LOCK TABLE t1 WRITE; +alter table t1 convert partition p2 to table tp2; +ERROR HY000: Unknown error +# d,fail_alter_partition_after_write_frm: AFTER failure (under LOCK TABLE) +db.opt +t1#P#p1.MYD +t1#P#p1.MYI +t1#P#p2.MYD +t1#P#p2.MYI +t1#P#p3.MYD +t1#P#p3.MYI +t1#P#p4.MYD +t1#P#p4.MYI +t1#P#p5.MYD +t1#P#p5.MYI +t1#P#pn.MYD +t1#P#pn.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `x` int(11) NOT NULL, + PRIMARY KEY (`x`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 + PARTITION BY RANGE (`x`) +(PARTITION `p1` VALUES LESS THAN (10) ENGINE = MyISAM, + PARTITION `p2` VALUES LESS THAN (20) ENGINE = MyISAM, + PARTITION `p3` VALUES LESS THAN (30) ENGINE = MyISAM, + PARTITION `p4` VALUES LESS THAN (40) ENGINE = MyISAM, + PARTITION `p5` VALUES LESS THAN (50) ENGINE = MyISAM, + PARTITION `pn` VALUES LESS THAN MAXVALUE ENGINE = MyISAM) +SELECT * FROM t1; +x +12 +2 +22 +32 +42 +52 +UNLOCK TABLES; +DROP TABLE t1; +set session debug_dbug=@save_dbug; +set session debug_dbug="+d,error_convert_partition_00"; +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), +partition p4 values less than (40), +partition p5 values less than (50), +partition pn values less than maxvalue); +insert into t1 values (2), (12), (22), (32), (42), (52); +# d,error_convert_partition_00: BEFORE failure +db.opt +t1#P#p1.MYD +t1#P#p1.MYI +t1#P#p2.MYD +t1#P#p2.MYI +t1#P#p3.MYD +t1#P#p3.MYI +t1#P#p4.MYD +t1#P#p4.MYI +t1#P#p5.MYD +t1#P#p5.MYI +t1#P#pn.MYD +t1#P#pn.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `x` int(11) NOT NULL, + PRIMARY KEY (`x`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 + PARTITION BY RANGE (`x`) +(PARTITION `p1` VALUES LESS THAN (10) ENGINE = MyISAM, + PARTITION `p2` VALUES LESS THAN (20) ENGINE = MyISAM, + PARTITION `p3` VALUES LESS THAN (30) ENGINE = MyISAM, + PARTITION `p4` VALUES LESS THAN (40) ENGINE = MyISAM, + PARTITION `p5` VALUES LESS THAN (50) ENGINE = MyISAM, + PARTITION `pn` VALUES LESS THAN MAXVALUE ENGINE = MyISAM) +SELECT * FROM t1; +x +12 +2 +22 +32 +42 +52 +alter table t1 convert partition p2 to table tp2; +ERROR HY000: Error on rename of './test/t1#P#p2' to './test/tp2' (errno: 137 "No more records (read after end of file)") +# d,error_convert_partition_00: AFTER failure +db.opt +t1#P#p1.MYD +t1#P#p1.MYI +t1#P#p2.MYD +t1#P#p2.MYI +t1#P#p3.MYD +t1#P#p3.MYI +t1#P#p4.MYD +t1#P#p4.MYI +t1#P#p5.MYD +t1#P#p5.MYI +t1#P#pn.MYD +t1#P#pn.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `x` int(11) NOT NULL, + PRIMARY KEY (`x`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 + PARTITION BY RANGE (`x`) +(PARTITION `p1` VALUES LESS THAN (10) ENGINE = MyISAM, + PARTITION `p2` VALUES LESS THAN (20) ENGINE = MyISAM, + PARTITION `p3` VALUES LESS THAN (30) ENGINE = MyISAM, + PARTITION `p4` VALUES LESS THAN (40) ENGINE = MyISAM, + PARTITION `p5` VALUES LESS THAN (50) ENGINE = MyISAM, + PARTITION `pn` VALUES LESS THAN MAXVALUE ENGINE = MyISAM) +SELECT * FROM t1; +x +12 +2 +22 +32 +42 +52 +DROP TABLE t1; +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), +partition p4 values less than (40), +partition p5 values less than (50), +partition pn values less than maxvalue); +insert into t1 values (2), (12), (22), (32), (42), (52); +# d,error_convert_partition_00: BEFORE failure (under LOCK TABLE) +db.opt +t1#P#p1.MYD +t1#P#p1.MYI +t1#P#p2.MYD +t1#P#p2.MYI +t1#P#p3.MYD +t1#P#p3.MYI +t1#P#p4.MYD +t1#P#p4.MYI +t1#P#p5.MYD +t1#P#p5.MYI +t1#P#pn.MYD +t1#P#pn.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `x` int(11) NOT NULL, + PRIMARY KEY (`x`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 + PARTITION BY RANGE (`x`) +(PARTITION `p1` VALUES LESS THAN (10) ENGINE = MyISAM, + PARTITION `p2` VALUES LESS THAN (20) ENGINE = MyISAM, + PARTITION `p3` VALUES LESS THAN (30) ENGINE = MyISAM, + PARTITION `p4` VALUES LESS THAN (40) ENGINE = MyISAM, + PARTITION `p5` VALUES LESS THAN (50) ENGINE = MyISAM, + PARTITION `pn` VALUES LESS THAN MAXVALUE ENGINE = MyISAM) +SELECT * FROM t1; +x +12 +2 +22 +32 +42 +52 +LOCK TABLE t1 WRITE; +alter table t1 convert partition p2 to table tp2; +ERROR HY000: Error on rename of './test/t1#P#p2' to './test/tp2' (errno: 137 "No more records (read after end of file)") +# d,error_convert_partition_00: AFTER failure (under LOCK TABLE) +db.opt +t1#P#p1.MYD +t1#P#p1.MYI +t1#P#p2.MYD +t1#P#p2.MYI +t1#P#p3.MYD +t1#P#p3.MYI +t1#P#p4.MYD +t1#P#p4.MYI +t1#P#p5.MYD +t1#P#p5.MYI +t1#P#pn.MYD +t1#P#pn.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `x` int(11) NOT NULL, + PRIMARY KEY (`x`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 + PARTITION BY RANGE (`x`) +(PARTITION `p1` VALUES LESS THAN (10) ENGINE = MyISAM, + PARTITION `p2` VALUES LESS THAN (20) ENGINE = MyISAM, + PARTITION `p3` VALUES LESS THAN (30) ENGINE = MyISAM, + PARTITION `p4` VALUES LESS THAN (40) ENGINE = MyISAM, + PARTITION `p5` VALUES LESS THAN (50) ENGINE = MyISAM, + PARTITION `pn` VALUES LESS THAN MAXVALUE ENGINE = MyISAM) +SELECT * FROM t1; +x +12 +2 +22 +32 +42 +52 +UNLOCK TABLES; +DROP TABLE t1; +set session debug_dbug=@save_dbug; +set session debug_dbug="+d,fail_convert_partition_1"; +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), +partition p4 values less than (40), +partition p5 values less than (50), +partition pn values less than maxvalue); +insert into t1 values (2), (12), (22), (32), (42), (52); +# d,fail_convert_partition_1: BEFORE failure +db.opt +t1#P#p1.MYD +t1#P#p1.MYI +t1#P#p2.MYD +t1#P#p2.MYI +t1#P#p3.MYD +t1#P#p3.MYI +t1#P#p4.MYD +t1#P#p4.MYI +t1#P#p5.MYD +t1#P#p5.MYI +t1#P#pn.MYD +t1#P#pn.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `x` int(11) NOT NULL, + PRIMARY KEY (`x`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 + PARTITION BY RANGE (`x`) +(PARTITION `p1` VALUES LESS THAN (10) ENGINE = MyISAM, + PARTITION `p2` VALUES LESS THAN (20) ENGINE = MyISAM, + PARTITION `p3` VALUES LESS THAN (30) ENGINE = MyISAM, + PARTITION `p4` VALUES LESS THAN (40) ENGINE = MyISAM, + PARTITION `p5` VALUES LESS THAN (50) ENGINE = MyISAM, + PARTITION `pn` VALUES LESS THAN MAXVALUE ENGINE = MyISAM) +SELECT * FROM t1; +x +12 +2 +22 +32 +42 +52 +alter table t1 convert partition p2 to table tp2; +ERROR HY000: Unknown error +# d,fail_convert_partition_1: AFTER failure +db.opt +t1#P#p1.MYD +t1#P#p1.MYI +t1#P#p2.MYD +t1#P#p2.MYI +t1#P#p3.MYD +t1#P#p3.MYI +t1#P#p4.MYD +t1#P#p4.MYI +t1#P#p5.MYD +t1#P#p5.MYI +t1#P#pn.MYD +t1#P#pn.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `x` int(11) NOT NULL, + PRIMARY KEY (`x`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 + PARTITION BY RANGE (`x`) +(PARTITION `p1` VALUES LESS THAN (10) ENGINE = MyISAM, + PARTITION `p2` VALUES LESS THAN (20) ENGINE = MyISAM, + PARTITION `p3` VALUES LESS THAN (30) ENGINE = MyISAM, + PARTITION `p4` VALUES LESS THAN (40) ENGINE = MyISAM, + PARTITION `p5` VALUES LESS THAN (50) ENGINE = MyISAM, + PARTITION `pn` VALUES LESS THAN MAXVALUE ENGINE = MyISAM) +SELECT * FROM t1; +x +12 +2 +22 +32 +42 +52 +DROP TABLE t1; +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), +partition p4 values less than (40), +partition p5 values less than (50), +partition pn values less than maxvalue); +insert into t1 values (2), (12), (22), (32), (42), (52); +# d,fail_convert_partition_1: BEFORE failure (under LOCK TABLE) +db.opt +t1#P#p1.MYD +t1#P#p1.MYI +t1#P#p2.MYD +t1#P#p2.MYI +t1#P#p3.MYD +t1#P#p3.MYI +t1#P#p4.MYD +t1#P#p4.MYI +t1#P#p5.MYD +t1#P#p5.MYI +t1#P#pn.MYD +t1#P#pn.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `x` int(11) NOT NULL, + PRIMARY KEY (`x`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 + PARTITION BY RANGE (`x`) +(PARTITION `p1` VALUES LESS THAN (10) ENGINE = MyISAM, + PARTITION `p2` VALUES LESS THAN (20) ENGINE = MyISAM, + PARTITION `p3` VALUES LESS THAN (30) ENGINE = MyISAM, + PARTITION `p4` VALUES LESS THAN (40) ENGINE = MyISAM, + PARTITION `p5` VALUES LESS THAN (50) ENGINE = MyISAM, + PARTITION `pn` VALUES LESS THAN MAXVALUE ENGINE = MyISAM) +SELECT * FROM t1; +x +12 +2 +22 +32 +42 +52 +LOCK TABLE t1 WRITE; +alter table t1 convert partition p2 to table tp2; +ERROR HY000: Unknown error +# d,fail_convert_partition_1: AFTER failure (under LOCK TABLE) +db.opt +t1#P#p1.MYD +t1#P#p1.MYI +t1#P#p2.MYD +t1#P#p2.MYI +t1#P#p3.MYD +t1#P#p3.MYI +t1#P#p4.MYD +t1#P#p4.MYI +t1#P#p5.MYD +t1#P#p5.MYI +t1#P#pn.MYD +t1#P#pn.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `x` int(11) NOT NULL, + PRIMARY KEY (`x`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 + PARTITION BY RANGE (`x`) +(PARTITION `p1` VALUES LESS THAN (10) ENGINE = MyISAM, + PARTITION `p2` VALUES LESS THAN (20) ENGINE = MyISAM, + PARTITION `p3` VALUES LESS THAN (30) ENGINE = MyISAM, + PARTITION `p4` VALUES LESS THAN (40) ENGINE = MyISAM, + PARTITION `p5` VALUES LESS THAN (50) ENGINE = MyISAM, + PARTITION `pn` VALUES LESS THAN MAXVALUE ENGINE = MyISAM) +SELECT * FROM t1; +x +12 +2 +22 +32 +42 +52 +UNLOCK TABLES; +DROP TABLE t1; +set session debug_dbug=@save_dbug; +set session debug_dbug="+d,fail_convert_partition_2"; +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), +partition p4 values less than (40), +partition p5 values less than (50), +partition pn values less than maxvalue); +insert into t1 values (2), (12), (22), (32), (42), (52); +# d,fail_convert_partition_2: BEFORE failure +db.opt +t1#P#p1.MYD +t1#P#p1.MYI +t1#P#p2.MYD +t1#P#p2.MYI +t1#P#p3.MYD +t1#P#p3.MYI +t1#P#p4.MYD +t1#P#p4.MYI +t1#P#p5.MYD +t1#P#p5.MYI +t1#P#pn.MYD +t1#P#pn.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `x` int(11) NOT NULL, + PRIMARY KEY (`x`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 + PARTITION BY RANGE (`x`) +(PARTITION `p1` VALUES LESS THAN (10) ENGINE = MyISAM, + PARTITION `p2` VALUES LESS THAN (20) ENGINE = MyISAM, + PARTITION `p3` VALUES LESS THAN (30) ENGINE = MyISAM, + PARTITION `p4` VALUES LESS THAN (40) ENGINE = MyISAM, + PARTITION `p5` VALUES LESS THAN (50) ENGINE = MyISAM, + PARTITION `pn` VALUES LESS THAN MAXVALUE ENGINE = MyISAM) +SELECT * FROM t1; +x +12 +2 +22 +32 +42 +52 +alter table t1 convert partition p2 to table tp2; +ERROR HY000: Unknown error +# d,fail_convert_partition_2: AFTER failure +db.opt +t1#P#p1.MYD +t1#P#p1.MYI +t1#P#p2.MYD +t1#P#p2.MYI +t1#P#p3.MYD +t1#P#p3.MYI +t1#P#p4.MYD +t1#P#p4.MYI +t1#P#p5.MYD +t1#P#p5.MYI +t1#P#pn.MYD +t1#P#pn.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `x` int(11) NOT NULL, + PRIMARY KEY (`x`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 + PARTITION BY RANGE (`x`) +(PARTITION `p1` VALUES LESS THAN (10) ENGINE = MyISAM, + PARTITION `p2` VALUES LESS THAN (20) ENGINE = MyISAM, + PARTITION `p3` VALUES LESS THAN (30) ENGINE = MyISAM, + PARTITION `p4` VALUES LESS THAN (40) ENGINE = MyISAM, + PARTITION `p5` VALUES LESS THAN (50) ENGINE = MyISAM, + PARTITION `pn` VALUES LESS THAN MAXVALUE ENGINE = MyISAM) +SELECT * FROM t1; +x +12 +2 +22 +32 +42 +52 +DROP TABLE t1; +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), +partition p4 values less than (40), +partition p5 values less than (50), +partition pn values less than maxvalue); +insert into t1 values (2), (12), (22), (32), (42), (52); +# d,fail_convert_partition_2: BEFORE failure (under LOCK TABLE) +db.opt +t1#P#p1.MYD +t1#P#p1.MYI +t1#P#p2.MYD +t1#P#p2.MYI +t1#P#p3.MYD +t1#P#p3.MYI +t1#P#p4.MYD +t1#P#p4.MYI +t1#P#p5.MYD +t1#P#p5.MYI +t1#P#pn.MYD +t1#P#pn.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `x` int(11) NOT NULL, + PRIMARY KEY (`x`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 + PARTITION BY RANGE (`x`) +(PARTITION `p1` VALUES LESS THAN (10) ENGINE = MyISAM, + PARTITION `p2` VALUES LESS THAN (20) ENGINE = MyISAM, + PARTITION `p3` VALUES LESS THAN (30) ENGINE = MyISAM, + PARTITION `p4` VALUES LESS THAN (40) ENGINE = MyISAM, + PARTITION `p5` VALUES LESS THAN (50) ENGINE = MyISAM, + PARTITION `pn` VALUES LESS THAN MAXVALUE ENGINE = MyISAM) +SELECT * FROM t1; +x +12 +2 +22 +32 +42 +52 +LOCK TABLE t1 WRITE; +alter table t1 convert partition p2 to table tp2; +ERROR HY000: Unknown error +# d,fail_convert_partition_2: AFTER failure (under LOCK TABLE) +db.opt +t1#P#p1.MYD +t1#P#p1.MYI +t1#P#p2.MYD +t1#P#p2.MYI +t1#P#p3.MYD +t1#P#p3.MYI +t1#P#p4.MYD +t1#P#p4.MYI +t1#P#p5.MYD +t1#P#p5.MYI +t1#P#pn.MYD +t1#P#pn.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `x` int(11) NOT NULL, + PRIMARY KEY (`x`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 + PARTITION BY RANGE (`x`) +(PARTITION `p1` VALUES LESS THAN (10) ENGINE = MyISAM, + PARTITION `p2` VALUES LESS THAN (20) ENGINE = MyISAM, + PARTITION `p3` VALUES LESS THAN (30) ENGINE = MyISAM, + PARTITION `p4` VALUES LESS THAN (40) ENGINE = MyISAM, + PARTITION `p5` VALUES LESS THAN (50) ENGINE = MyISAM, + PARTITION `pn` VALUES LESS THAN MAXVALUE ENGINE = MyISAM) +SELECT * FROM t1; +x +12 +2 +22 +32 +42 +52 +UNLOCK TABLES; +DROP TABLE t1; +set session debug_dbug=@save_dbug; +set session debug_dbug="+d,fail_convert_partition_3"; +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), +partition p4 values less than (40), +partition p5 values less than (50), +partition pn values less than maxvalue); +insert into t1 values (2), (12), (22), (32), (42), (52); +# d,fail_convert_partition_3: BEFORE failure +db.opt +t1#P#p1.MYD +t1#P#p1.MYI +t1#P#p2.MYD +t1#P#p2.MYI +t1#P#p3.MYD +t1#P#p3.MYI +t1#P#p4.MYD +t1#P#p4.MYI +t1#P#p5.MYD +t1#P#p5.MYI +t1#P#pn.MYD +t1#P#pn.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `x` int(11) NOT NULL, + PRIMARY KEY (`x`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 + PARTITION BY RANGE (`x`) +(PARTITION `p1` VALUES LESS THAN (10) ENGINE = MyISAM, + PARTITION `p2` VALUES LESS THAN (20) ENGINE = MyISAM, + PARTITION `p3` VALUES LESS THAN (30) ENGINE = MyISAM, + PARTITION `p4` VALUES LESS THAN (40) ENGINE = MyISAM, + PARTITION `p5` VALUES LESS THAN (50) ENGINE = MyISAM, + PARTITION `pn` VALUES LESS THAN MAXVALUE ENGINE = MyISAM) +SELECT * FROM t1; +x +12 +2 +22 +32 +42 +52 +alter table t1 convert partition p2 to table tp2; +ERROR HY000: Unknown error +# d,fail_convert_partition_3: AFTER failure +db.opt +t1#P#p1.MYD +t1#P#p1.MYI +t1#P#p2.MYD +t1#P#p2.MYI +t1#P#p3.MYD +t1#P#p3.MYI +t1#P#p4.MYD +t1#P#p4.MYI +t1#P#p5.MYD +t1#P#p5.MYI +t1#P#pn.MYD +t1#P#pn.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `x` int(11) NOT NULL, + PRIMARY KEY (`x`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 + PARTITION BY RANGE (`x`) +(PARTITION `p1` VALUES LESS THAN (10) ENGINE = MyISAM, + PARTITION `p2` VALUES LESS THAN (20) ENGINE = MyISAM, + PARTITION `p3` VALUES LESS THAN (30) ENGINE = MyISAM, + PARTITION `p4` VALUES LESS THAN (40) ENGINE = MyISAM, + PARTITION `p5` VALUES LESS THAN (50) ENGINE = MyISAM, + PARTITION `pn` VALUES LESS THAN MAXVALUE ENGINE = MyISAM) +SELECT * FROM t1; +x +12 +2 +22 +32 +42 +52 +DROP TABLE t1; +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), +partition p4 values less than (40), +partition p5 values less than (50), +partition pn values less than maxvalue); +insert into t1 values (2), (12), (22), (32), (42), (52); +# d,fail_convert_partition_3: BEFORE failure (under LOCK TABLE) +db.opt +t1#P#p1.MYD +t1#P#p1.MYI +t1#P#p2.MYD +t1#P#p2.MYI +t1#P#p3.MYD +t1#P#p3.MYI +t1#P#p4.MYD +t1#P#p4.MYI +t1#P#p5.MYD +t1#P#p5.MYI +t1#P#pn.MYD +t1#P#pn.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `x` int(11) NOT NULL, + PRIMARY KEY (`x`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 + PARTITION BY RANGE (`x`) +(PARTITION `p1` VALUES LESS THAN (10) ENGINE = MyISAM, + PARTITION `p2` VALUES LESS THAN (20) ENGINE = MyISAM, + PARTITION `p3` VALUES LESS THAN (30) ENGINE = MyISAM, + PARTITION `p4` VALUES LESS THAN (40) ENGINE = MyISAM, + PARTITION `p5` VALUES LESS THAN (50) ENGINE = MyISAM, + PARTITION `pn` VALUES LESS THAN MAXVALUE ENGINE = MyISAM) +SELECT * FROM t1; +x +12 +2 +22 +32 +42 +52 +LOCK TABLE t1 WRITE; +alter table t1 convert partition p2 to table tp2; +ERROR HY000: Unknown error +# d,fail_convert_partition_3: AFTER failure (under LOCK TABLE) +db.opt +t1#P#p1.MYD +t1#P#p1.MYI +t1#P#p2.MYD +t1#P#p2.MYI +t1#P#p3.MYD +t1#P#p3.MYI +t1#P#p4.MYD +t1#P#p4.MYI +t1#P#p5.MYD +t1#P#p5.MYI +t1#P#pn.MYD +t1#P#pn.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `x` int(11) NOT NULL, + PRIMARY KEY (`x`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 + PARTITION BY RANGE (`x`) +(PARTITION `p1` VALUES LESS THAN (10) ENGINE = MyISAM, + PARTITION `p2` VALUES LESS THAN (20) ENGINE = MyISAM, + PARTITION `p3` VALUES LESS THAN (30) ENGINE = MyISAM, + PARTITION `p4` VALUES LESS THAN (40) ENGINE = MyISAM, + PARTITION `p5` VALUES LESS THAN (50) ENGINE = MyISAM, + PARTITION `pn` VALUES LESS THAN MAXVALUE ENGINE = MyISAM) +SELECT * FROM t1; +x +12 +2 +22 +32 +42 +52 +UNLOCK TABLES; +DROP TABLE t1; +set session debug_dbug=@save_dbug; +set session debug_dbug="+d,fail_convert_partition_4"; +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), +partition p4 values less than (40), +partition p5 values less than (50), +partition pn values less than maxvalue); +insert into t1 values (2), (12), (22), (32), (42), (52); +# d,fail_convert_partition_4: BEFORE failure +db.opt +t1#P#p1.MYD +t1#P#p1.MYI +t1#P#p2.MYD +t1#P#p2.MYI +t1#P#p3.MYD +t1#P#p3.MYI +t1#P#p4.MYD +t1#P#p4.MYI +t1#P#p5.MYD +t1#P#p5.MYI +t1#P#pn.MYD +t1#P#pn.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `x` int(11) NOT NULL, + PRIMARY KEY (`x`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 + PARTITION BY RANGE (`x`) +(PARTITION `p1` VALUES LESS THAN (10) ENGINE = MyISAM, + PARTITION `p2` VALUES LESS THAN (20) ENGINE = MyISAM, + PARTITION `p3` VALUES LESS THAN (30) ENGINE = MyISAM, + PARTITION `p4` VALUES LESS THAN (40) ENGINE = MyISAM, + PARTITION `p5` VALUES LESS THAN (50) ENGINE = MyISAM, + PARTITION `pn` VALUES LESS THAN MAXVALUE ENGINE = MyISAM) +SELECT * FROM t1; +x +12 +2 +22 +32 +42 +52 +alter table t1 convert partition p2 to table tp2; +ERROR HY000: Unknown error +# d,fail_convert_partition_4: AFTER failure +db.opt +t1#P#p1.MYD +t1#P#p1.MYI +t1#P#p2.MYD +t1#P#p2.MYI +t1#P#p3.MYD +t1#P#p3.MYI +t1#P#p4.MYD +t1#P#p4.MYI +t1#P#p5.MYD +t1#P#p5.MYI +t1#P#pn.MYD +t1#P#pn.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `x` int(11) NOT NULL, + PRIMARY KEY (`x`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 + PARTITION BY RANGE (`x`) +(PARTITION `p1` VALUES LESS THAN (10) ENGINE = MyISAM, + PARTITION `p2` VALUES LESS THAN (20) ENGINE = MyISAM, + PARTITION `p3` VALUES LESS THAN (30) ENGINE = MyISAM, + PARTITION `p4` VALUES LESS THAN (40) ENGINE = MyISAM, + PARTITION `p5` VALUES LESS THAN (50) ENGINE = MyISAM, + PARTITION `pn` VALUES LESS THAN MAXVALUE ENGINE = MyISAM) +SELECT * FROM t1; +x +12 +2 +22 +32 +42 +52 +DROP TABLE t1; +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), +partition p4 values less than (40), +partition p5 values less than (50), +partition pn values less than maxvalue); +insert into t1 values (2), (12), (22), (32), (42), (52); +# d,fail_convert_partition_4: BEFORE failure (under LOCK TABLE) +db.opt +t1#P#p1.MYD +t1#P#p1.MYI +t1#P#p2.MYD +t1#P#p2.MYI +t1#P#p3.MYD +t1#P#p3.MYI +t1#P#p4.MYD +t1#P#p4.MYI +t1#P#p5.MYD +t1#P#p5.MYI +t1#P#pn.MYD +t1#P#pn.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `x` int(11) NOT NULL, + PRIMARY KEY (`x`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 + PARTITION BY RANGE (`x`) +(PARTITION `p1` VALUES LESS THAN (10) ENGINE = MyISAM, + PARTITION `p2` VALUES LESS THAN (20) ENGINE = MyISAM, + PARTITION `p3` VALUES LESS THAN (30) ENGINE = MyISAM, + PARTITION `p4` VALUES LESS THAN (40) ENGINE = MyISAM, + PARTITION `p5` VALUES LESS THAN (50) ENGINE = MyISAM, + PARTITION `pn` VALUES LESS THAN MAXVALUE ENGINE = MyISAM) +SELECT * FROM t1; +x +12 +2 +22 +32 +42 +52 +LOCK TABLE t1 WRITE; +alter table t1 convert partition p2 to table tp2; +ERROR HY000: Unknown error +# d,fail_convert_partition_4: AFTER failure (under LOCK TABLE) +db.opt +t1#P#p1.MYD +t1#P#p1.MYI +t1#P#p2.MYD +t1#P#p2.MYI +t1#P#p3.MYD +t1#P#p3.MYI +t1#P#p4.MYD +t1#P#p4.MYI +t1#P#p5.MYD +t1#P#p5.MYI +t1#P#pn.MYD +t1#P#pn.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `x` int(11) NOT NULL, + PRIMARY KEY (`x`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 + PARTITION BY RANGE (`x`) +(PARTITION `p1` VALUES LESS THAN (10) ENGINE = MyISAM, + PARTITION `p2` VALUES LESS THAN (20) ENGINE = MyISAM, + PARTITION `p3` VALUES LESS THAN (30) ENGINE = MyISAM, + PARTITION `p4` VALUES LESS THAN (40) ENGINE = MyISAM, + PARTITION `p5` VALUES LESS THAN (50) ENGINE = MyISAM, + PARTITION `pn` VALUES LESS THAN MAXVALUE ENGINE = MyISAM) +SELECT * FROM t1; +x +12 +2 +22 +32 +42 +52 +UNLOCK TABLES; +DROP TABLE t1; +set session debug_dbug=@save_dbug; +set session debug_dbug="+d,fail_convert_partition_5"; +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), +partition p4 values less than (40), +partition p5 values less than (50), +partition pn values less than maxvalue); +insert into t1 values (2), (12), (22), (32), (42), (52); +# d,fail_convert_partition_5: BEFORE failure +db.opt +t1#P#p1.MYD +t1#P#p1.MYI +t1#P#p2.MYD +t1#P#p2.MYI +t1#P#p3.MYD +t1#P#p3.MYI +t1#P#p4.MYD +t1#P#p4.MYI +t1#P#p5.MYD +t1#P#p5.MYI +t1#P#pn.MYD +t1#P#pn.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `x` int(11) NOT NULL, + PRIMARY KEY (`x`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 + PARTITION BY RANGE (`x`) +(PARTITION `p1` VALUES LESS THAN (10) ENGINE = MyISAM, + PARTITION `p2` VALUES LESS THAN (20) ENGINE = MyISAM, + PARTITION `p3` VALUES LESS THAN (30) ENGINE = MyISAM, + PARTITION `p4` VALUES LESS THAN (40) ENGINE = MyISAM, + PARTITION `p5` VALUES LESS THAN (50) ENGINE = MyISAM, + PARTITION `pn` VALUES LESS THAN MAXVALUE ENGINE = MyISAM) +SELECT * FROM t1; +x +12 +2 +22 +32 +42 +52 +alter table t1 convert partition p2 to table tp2; +ERROR HY000: Unknown error +# d,fail_convert_partition_5: AFTER failure +db.opt +t1#P#p1.MYD +t1#P#p1.MYI +t1#P#p2.MYD +t1#P#p2.MYI +t1#P#p3.MYD +t1#P#p3.MYI +t1#P#p4.MYD +t1#P#p4.MYI +t1#P#p5.MYD +t1#P#p5.MYI +t1#P#pn.MYD +t1#P#pn.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `x` int(11) NOT NULL, + PRIMARY KEY (`x`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 + PARTITION BY RANGE (`x`) +(PARTITION `p1` VALUES LESS THAN (10) ENGINE = MyISAM, + PARTITION `p2` VALUES LESS THAN (20) ENGINE = MyISAM, + PARTITION `p3` VALUES LESS THAN (30) ENGINE = MyISAM, + PARTITION `p4` VALUES LESS THAN (40) ENGINE = MyISAM, + PARTITION `p5` VALUES LESS THAN (50) ENGINE = MyISAM, + PARTITION `pn` VALUES LESS THAN MAXVALUE ENGINE = MyISAM) +SELECT * FROM t1; +x +12 +2 +22 +32 +42 +52 +DROP TABLE t1; +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), +partition p4 values less than (40), +partition p5 values less than (50), +partition pn values less than maxvalue); +insert into t1 values (2), (12), (22), (32), (42), (52); +# d,fail_convert_partition_5: BEFORE failure (under LOCK TABLE) +db.opt +t1#P#p1.MYD +t1#P#p1.MYI +t1#P#p2.MYD +t1#P#p2.MYI +t1#P#p3.MYD +t1#P#p3.MYI +t1#P#p4.MYD +t1#P#p4.MYI +t1#P#p5.MYD +t1#P#p5.MYI +t1#P#pn.MYD +t1#P#pn.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `x` int(11) NOT NULL, + PRIMARY KEY (`x`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 + PARTITION BY RANGE (`x`) +(PARTITION `p1` VALUES LESS THAN (10) ENGINE = MyISAM, + PARTITION `p2` VALUES LESS THAN (20) ENGINE = MyISAM, + PARTITION `p3` VALUES LESS THAN (30) ENGINE = MyISAM, + PARTITION `p4` VALUES LESS THAN (40) ENGINE = MyISAM, + PARTITION `p5` VALUES LESS THAN (50) ENGINE = MyISAM, + PARTITION `pn` VALUES LESS THAN MAXVALUE ENGINE = MyISAM) +SELECT * FROM t1; +x +12 +2 +22 +32 +42 +52 +LOCK TABLE t1 WRITE; +alter table t1 convert partition p2 to table tp2; +ERROR HY000: Unknown error +# d,fail_convert_partition_5: AFTER failure (under LOCK TABLE) +db.opt +t1#P#p1.MYD +t1#P#p1.MYI +t1#P#p2.MYD +t1#P#p2.MYI +t1#P#p3.MYD +t1#P#p3.MYI +t1#P#p4.MYD +t1#P#p4.MYI +t1#P#p5.MYD +t1#P#p5.MYI +t1#P#pn.MYD +t1#P#pn.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `x` int(11) NOT NULL, + PRIMARY KEY (`x`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 + PARTITION BY RANGE (`x`) +(PARTITION `p1` VALUES LESS THAN (10) ENGINE = MyISAM, + PARTITION `p2` VALUES LESS THAN (20) ENGINE = MyISAM, + PARTITION `p3` VALUES LESS THAN (30) ENGINE = MyISAM, + PARTITION `p4` VALUES LESS THAN (40) ENGINE = MyISAM, + PARTITION `p5` VALUES LESS THAN (50) ENGINE = MyISAM, + PARTITION `pn` VALUES LESS THAN MAXVALUE ENGINE = MyISAM) +SELECT * FROM t1; +x +12 +2 +22 +32 +42 +52 +UNLOCK TABLES; +DROP TABLE t1; +set session debug_dbug=@save_dbug; +set session debug_dbug="+d,fail_convert_partition_6"; +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), +partition p4 values less than (40), +partition p5 values less than (50), +partition pn values less than maxvalue); +insert into t1 values (2), (12), (22), (32), (42), (52); +# d,fail_convert_partition_6: BEFORE failure +db.opt +t1#P#p1.MYD +t1#P#p1.MYI +t1#P#p2.MYD +t1#P#p2.MYI +t1#P#p3.MYD +t1#P#p3.MYI +t1#P#p4.MYD +t1#P#p4.MYI +t1#P#p5.MYD +t1#P#p5.MYI +t1#P#pn.MYD +t1#P#pn.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `x` int(11) NOT NULL, + PRIMARY KEY (`x`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 + PARTITION BY RANGE (`x`) +(PARTITION `p1` VALUES LESS THAN (10) ENGINE = MyISAM, + PARTITION `p2` VALUES LESS THAN (20) ENGINE = MyISAM, + PARTITION `p3` VALUES LESS THAN (30) ENGINE = MyISAM, + PARTITION `p4` VALUES LESS THAN (40) ENGINE = MyISAM, + PARTITION `p5` VALUES LESS THAN (50) ENGINE = MyISAM, + PARTITION `pn` VALUES LESS THAN MAXVALUE ENGINE = MyISAM) +SELECT * FROM t1; +x +12 +2 +22 +32 +42 +52 +alter table t1 convert partition p2 to table tp2; +ERROR HY000: Unknown error +# d,fail_convert_partition_6: AFTER failure +db.opt +t1#P#p1.MYD +t1#P#p1.MYI +t1#P#p2.MYD +t1#P#p2.MYI +t1#P#p3.MYD +t1#P#p3.MYI +t1#P#p4.MYD +t1#P#p4.MYI +t1#P#p5.MYD +t1#P#p5.MYI +t1#P#pn.MYD +t1#P#pn.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `x` int(11) NOT NULL, + PRIMARY KEY (`x`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 + PARTITION BY RANGE (`x`) +(PARTITION `p1` VALUES LESS THAN (10) ENGINE = MyISAM, + PARTITION `p2` VALUES LESS THAN (20) ENGINE = MyISAM, + PARTITION `p3` VALUES LESS THAN (30) ENGINE = MyISAM, + PARTITION `p4` VALUES LESS THAN (40) ENGINE = MyISAM, + PARTITION `p5` VALUES LESS THAN (50) ENGINE = MyISAM, + PARTITION `pn` VALUES LESS THAN MAXVALUE ENGINE = MyISAM) +SELECT * FROM t1; +x +12 +2 +22 +32 +42 +52 +DROP TABLE t1; +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), +partition p4 values less than (40), +partition p5 values less than (50), +partition pn values less than maxvalue); +insert into t1 values (2), (12), (22), (32), (42), (52); +# d,fail_convert_partition_6: BEFORE failure (under LOCK TABLE) +db.opt +t1#P#p1.MYD +t1#P#p1.MYI +t1#P#p2.MYD +t1#P#p2.MYI +t1#P#p3.MYD +t1#P#p3.MYI +t1#P#p4.MYD +t1#P#p4.MYI +t1#P#p5.MYD +t1#P#p5.MYI +t1#P#pn.MYD +t1#P#pn.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `x` int(11) NOT NULL, + PRIMARY KEY (`x`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 + PARTITION BY RANGE (`x`) +(PARTITION `p1` VALUES LESS THAN (10) ENGINE = MyISAM, + PARTITION `p2` VALUES LESS THAN (20) ENGINE = MyISAM, + PARTITION `p3` VALUES LESS THAN (30) ENGINE = MyISAM, + PARTITION `p4` VALUES LESS THAN (40) ENGINE = MyISAM, + PARTITION `p5` VALUES LESS THAN (50) ENGINE = MyISAM, + PARTITION `pn` VALUES LESS THAN MAXVALUE ENGINE = MyISAM) +SELECT * FROM t1; +x +12 +2 +22 +32 +42 +52 +LOCK TABLE t1 WRITE; +alter table t1 convert partition p2 to table tp2; +ERROR HY000: Unknown error +# d,fail_convert_partition_6: AFTER failure (under LOCK TABLE) +db.opt +t1#P#p1.MYD +t1#P#p1.MYI +t1#P#p2.MYD +t1#P#p2.MYI +t1#P#p3.MYD +t1#P#p3.MYI +t1#P#p4.MYD +t1#P#p4.MYI +t1#P#p5.MYD +t1#P#p5.MYI +t1#P#pn.MYD +t1#P#pn.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `x` int(11) NOT NULL, + PRIMARY KEY (`x`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 + PARTITION BY RANGE (`x`) +(PARTITION `p1` VALUES LESS THAN (10) ENGINE = MyISAM, + PARTITION `p2` VALUES LESS THAN (20) ENGINE = MyISAM, + PARTITION `p3` VALUES LESS THAN (30) ENGINE = MyISAM, + PARTITION `p4` VALUES LESS THAN (40) ENGINE = MyISAM, + PARTITION `p5` VALUES LESS THAN (50) ENGINE = MyISAM, + PARTITION `pn` VALUES LESS THAN MAXVALUE ENGINE = MyISAM) +SELECT * FROM t1; +x +12 +2 +22 +32 +42 +52 +UNLOCK TABLES; +DROP TABLE t1; +set session debug_dbug=@save_dbug; +set session debug_dbug="+d,fail_convert_partition_7"; +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), +partition p4 values less than (40), +partition p5 values less than (50), +partition pn values less than maxvalue); +insert into t1 values (2), (12), (22), (32), (42), (52); +# d,fail_convert_partition_7: BEFORE failure +db.opt +t1#P#p1.MYD +t1#P#p1.MYI +t1#P#p2.MYD +t1#P#p2.MYI +t1#P#p3.MYD +t1#P#p3.MYI +t1#P#p4.MYD +t1#P#p4.MYI +t1#P#p5.MYD +t1#P#p5.MYI +t1#P#pn.MYD +t1#P#pn.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `x` int(11) NOT NULL, + PRIMARY KEY (`x`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 + PARTITION BY RANGE (`x`) +(PARTITION `p1` VALUES LESS THAN (10) ENGINE = MyISAM, + PARTITION `p2` VALUES LESS THAN (20) ENGINE = MyISAM, + PARTITION `p3` VALUES LESS THAN (30) ENGINE = MyISAM, + PARTITION `p4` VALUES LESS THAN (40) ENGINE = MyISAM, + PARTITION `p5` VALUES LESS THAN (50) ENGINE = MyISAM, + PARTITION `pn` VALUES LESS THAN MAXVALUE ENGINE = MyISAM) +SELECT * FROM t1; +x +12 +2 +22 +32 +42 +52 +alter table t1 convert partition p2 to table tp2; +ERROR HY000: Unknown error +# d,fail_convert_partition_7: AFTER failure +db.opt +t1#P#p1.MYD +t1#P#p1.MYI +t1#P#p2.MYD +t1#P#p2.MYI +t1#P#p3.MYD +t1#P#p3.MYI +t1#P#p4.MYD +t1#P#p4.MYI +t1#P#p5.MYD +t1#P#p5.MYI +t1#P#pn.MYD +t1#P#pn.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `x` int(11) NOT NULL, + PRIMARY KEY (`x`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 + PARTITION BY RANGE (`x`) +(PARTITION `p1` VALUES LESS THAN (10) ENGINE = MyISAM, + PARTITION `p2` VALUES LESS THAN (20) ENGINE = MyISAM, + PARTITION `p3` VALUES LESS THAN (30) ENGINE = MyISAM, + PARTITION `p4` VALUES LESS THAN (40) ENGINE = MyISAM, + PARTITION `p5` VALUES LESS THAN (50) ENGINE = MyISAM, + PARTITION `pn` VALUES LESS THAN MAXVALUE ENGINE = MyISAM) +SELECT * FROM t1; +x +12 +2 +22 +32 +42 +52 +DROP TABLE t1; +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), +partition p4 values less than (40), +partition p5 values less than (50), +partition pn values less than maxvalue); +insert into t1 values (2), (12), (22), (32), (42), (52); +# d,fail_convert_partition_7: BEFORE failure (under LOCK TABLE) +db.opt +t1#P#p1.MYD +t1#P#p1.MYI +t1#P#p2.MYD +t1#P#p2.MYI +t1#P#p3.MYD +t1#P#p3.MYI +t1#P#p4.MYD +t1#P#p4.MYI +t1#P#p5.MYD +t1#P#p5.MYI +t1#P#pn.MYD +t1#P#pn.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `x` int(11) NOT NULL, + PRIMARY KEY (`x`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 + PARTITION BY RANGE (`x`) +(PARTITION `p1` VALUES LESS THAN (10) ENGINE = MyISAM, + PARTITION `p2` VALUES LESS THAN (20) ENGINE = MyISAM, + PARTITION `p3` VALUES LESS THAN (30) ENGINE = MyISAM, + PARTITION `p4` VALUES LESS THAN (40) ENGINE = MyISAM, + PARTITION `p5` VALUES LESS THAN (50) ENGINE = MyISAM, + PARTITION `pn` VALUES LESS THAN MAXVALUE ENGINE = MyISAM) +SELECT * FROM t1; +x +12 +2 +22 +32 +42 +52 +LOCK TABLE t1 WRITE; +alter table t1 convert partition p2 to table tp2; +ERROR HY000: Unknown error +# d,fail_convert_partition_7: AFTER failure (under LOCK TABLE) +db.opt +t1#P#p1.MYD +t1#P#p1.MYI +t1#P#p2.MYD +t1#P#p2.MYI +t1#P#p3.MYD +t1#P#p3.MYI +t1#P#p4.MYD +t1#P#p4.MYI +t1#P#p5.MYD +t1#P#p5.MYI +t1#P#pn.MYD +t1#P#pn.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `x` int(11) NOT NULL, + PRIMARY KEY (`x`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 + PARTITION BY RANGE (`x`) +(PARTITION `p1` VALUES LESS THAN (10) ENGINE = MyISAM, + PARTITION `p2` VALUES LESS THAN (20) ENGINE = MyISAM, + PARTITION `p3` VALUES LESS THAN (30) ENGINE = MyISAM, + PARTITION `p4` VALUES LESS THAN (40) ENGINE = MyISAM, + PARTITION `p5` VALUES LESS THAN (50) ENGINE = MyISAM, + PARTITION `pn` VALUES LESS THAN MAXVALUE ENGINE = MyISAM) +SELECT * FROM t1; +x +12 +2 +22 +32 +42 +52 +UNLOCK TABLES; +DROP TABLE t1; +set session debug_dbug=@save_dbug; +set session debug_dbug="+d,fail_convert_partition_8"; +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), +partition p4 values less than (40), +partition p5 values less than (50), +partition pn values less than maxvalue); +insert into t1 values (2), (12), (22), (32), (42), (52); +# d,fail_convert_partition_8: BEFORE failure +db.opt +t1#P#p1.MYD +t1#P#p1.MYI +t1#P#p2.MYD +t1#P#p2.MYI +t1#P#p3.MYD +t1#P#p3.MYI +t1#P#p4.MYD +t1#P#p4.MYI +t1#P#p5.MYD +t1#P#p5.MYI +t1#P#pn.MYD +t1#P#pn.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `x` int(11) NOT NULL, + PRIMARY KEY (`x`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 + PARTITION BY RANGE (`x`) +(PARTITION `p1` VALUES LESS THAN (10) ENGINE = MyISAM, + PARTITION `p2` VALUES LESS THAN (20) ENGINE = MyISAM, + PARTITION `p3` VALUES LESS THAN (30) ENGINE = MyISAM, + PARTITION `p4` VALUES LESS THAN (40) ENGINE = MyISAM, + PARTITION `p5` VALUES LESS THAN (50) ENGINE = MyISAM, + PARTITION `pn` VALUES LESS THAN MAXVALUE ENGINE = MyISAM) +SELECT * FROM t1; +x +12 +2 +22 +32 +42 +52 +alter table t1 convert partition p2 to table tp2; +ERROR HY000: Unknown error +# d,fail_convert_partition_8: AFTER failure +db.opt +t1#P#p1.MYD +t1#P#p1.MYI +t1#P#p2.MYD +t1#P#p2.MYI +t1#P#p3.MYD +t1#P#p3.MYI +t1#P#p4.MYD +t1#P#p4.MYI +t1#P#p5.MYD +t1#P#p5.MYI +t1#P#pn.MYD +t1#P#pn.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `x` int(11) NOT NULL, + PRIMARY KEY (`x`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 + PARTITION BY RANGE (`x`) +(PARTITION `p1` VALUES LESS THAN (10) ENGINE = MyISAM, + PARTITION `p2` VALUES LESS THAN (20) ENGINE = MyISAM, + PARTITION `p3` VALUES LESS THAN (30) ENGINE = MyISAM, + PARTITION `p4` VALUES LESS THAN (40) ENGINE = MyISAM, + PARTITION `p5` VALUES LESS THAN (50) ENGINE = MyISAM, + PARTITION `pn` VALUES LESS THAN MAXVALUE ENGINE = MyISAM) +SELECT * FROM t1; +x +12 +2 +22 +32 +42 +52 +DROP TABLE t1; +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), +partition p4 values less than (40), +partition p5 values less than (50), +partition pn values less than maxvalue); +insert into t1 values (2), (12), (22), (32), (42), (52); +# d,fail_convert_partition_8: BEFORE failure (under LOCK TABLE) +db.opt +t1#P#p1.MYD +t1#P#p1.MYI +t1#P#p2.MYD +t1#P#p2.MYI +t1#P#p3.MYD +t1#P#p3.MYI +t1#P#p4.MYD +t1#P#p4.MYI +t1#P#p5.MYD +t1#P#p5.MYI +t1#P#pn.MYD +t1#P#pn.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `x` int(11) NOT NULL, + PRIMARY KEY (`x`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 + PARTITION BY RANGE (`x`) +(PARTITION `p1` VALUES LESS THAN (10) ENGINE = MyISAM, + PARTITION `p2` VALUES LESS THAN (20) ENGINE = MyISAM, + PARTITION `p3` VALUES LESS THAN (30) ENGINE = MyISAM, + PARTITION `p4` VALUES LESS THAN (40) ENGINE = MyISAM, + PARTITION `p5` VALUES LESS THAN (50) ENGINE = MyISAM, + PARTITION `pn` VALUES LESS THAN MAXVALUE ENGINE = MyISAM) +SELECT * FROM t1; +x +12 +2 +22 +32 +42 +52 +LOCK TABLE t1 WRITE; +alter table t1 convert partition p2 to table tp2; +ERROR HY000: Unknown error +# d,fail_convert_partition_8: AFTER failure (under LOCK TABLE) +db.opt +t1#P#p1.MYD +t1#P#p1.MYI +t1#P#p2.MYD +t1#P#p2.MYI +t1#P#p3.MYD +t1#P#p3.MYI +t1#P#p4.MYD +t1#P#p4.MYI +t1#P#p5.MYD +t1#P#p5.MYI +t1#P#pn.MYD +t1#P#pn.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `x` int(11) NOT NULL, + PRIMARY KEY (`x`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 + PARTITION BY RANGE (`x`) +(PARTITION `p1` VALUES LESS THAN (10) ENGINE = MyISAM, + PARTITION `p2` VALUES LESS THAN (20) ENGINE = MyISAM, + PARTITION `p3` VALUES LESS THAN (30) ENGINE = MyISAM, + PARTITION `p4` VALUES LESS THAN (40) ENGINE = MyISAM, + PARTITION `p5` VALUES LESS THAN (50) ENGINE = MyISAM, + PARTITION `pn` VALUES LESS THAN MAXVALUE ENGINE = MyISAM) +SELECT * FROM t1; +x +12 +2 +22 +32 +42 +52 +UNLOCK TABLES; +DROP TABLE t1; +set session debug_dbug=@save_dbug; +set session debug_dbug="+d,fail_convert_partition_9"; +# Already finished DDL logging, so tp2 now exists: +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), +partition p4 values less than (40), +partition p5 values less than (50), +partition pn values less than maxvalue); +insert into t1 values (2), (12), (22), (32), (42), (52); +# d,fail_convert_partition_9: BEFORE failure +db.opt +t1#P#p1.MYD +t1#P#p1.MYI +t1#P#p2.MYD +t1#P#p2.MYI +t1#P#p3.MYD +t1#P#p3.MYI +t1#P#p4.MYD +t1#P#p4.MYI +t1#P#p5.MYD +t1#P#p5.MYI +t1#P#pn.MYD +t1#P#pn.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `x` int(11) NOT NULL, + PRIMARY KEY (`x`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 + PARTITION BY RANGE (`x`) +(PARTITION `p1` VALUES LESS THAN (10) ENGINE = MyISAM, + PARTITION `p2` VALUES LESS THAN (20) ENGINE = MyISAM, + PARTITION `p3` VALUES LESS THAN (30) ENGINE = MyISAM, + PARTITION `p4` VALUES LESS THAN (40) ENGINE = MyISAM, + PARTITION `p5` VALUES LESS THAN (50) ENGINE = MyISAM, + PARTITION `pn` VALUES LESS THAN MAXVALUE ENGINE = MyISAM) +SELECT * FROM t1; +x +12 +2 +22 +32 +42 +52 +alter table t1 convert partition p2 to table tp2; +ERROR HY000: Unknown error +# d,fail_convert_partition_9: AFTER failure +db.opt +t1#P#p1.MYD +t1#P#p1.MYI +t1#P#p3.MYD +t1#P#p3.MYI +t1#P#p4.MYD +t1#P#p4.MYI +t1#P#p5.MYD +t1#P#p5.MYI +t1#P#pn.MYD +t1#P#pn.MYI +t1.frm +t1.par +tp2.MYD +tp2.MYI +tp2.frm +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `x` int(11) NOT NULL, + PRIMARY KEY (`x`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 + PARTITION BY RANGE (`x`) +(PARTITION `p1` VALUES LESS THAN (10) ENGINE = MyISAM, + PARTITION `p3` VALUES LESS THAN (30) ENGINE = MyISAM, + PARTITION `p4` VALUES LESS THAN (40) ENGINE = MyISAM, + PARTITION `p5` VALUES LESS THAN (50) ENGINE = MyISAM, + PARTITION `pn` VALUES LESS THAN MAXVALUE ENGINE = MyISAM) +SELECT * FROM t1; +x +2 +22 +32 +42 +52 +DROP TABLE t1; +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), +partition p4 values less than (40), +partition p5 values less than (50), +partition pn values less than maxvalue); +insert into t1 values (2), (12), (22), (32), (42), (52); +# d,fail_convert_partition_9: BEFORE failure (under LOCK TABLE) +db.opt +t1#P#p1.MYD +t1#P#p1.MYI +t1#P#p2.MYD +t1#P#p2.MYI +t1#P#p3.MYD +t1#P#p3.MYI +t1#P#p4.MYD +t1#P#p4.MYI +t1#P#p5.MYD +t1#P#p5.MYI +t1#P#pn.MYD +t1#P#pn.MYI +t1.frm +t1.par +tp2.MYD +tp2.MYI +tp2.frm +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `x` int(11) NOT NULL, + PRIMARY KEY (`x`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 + PARTITION BY RANGE (`x`) +(PARTITION `p1` VALUES LESS THAN (10) ENGINE = MyISAM, + PARTITION `p2` VALUES LESS THAN (20) ENGINE = MyISAM, + PARTITION `p3` VALUES LESS THAN (30) ENGINE = MyISAM, + PARTITION `p4` VALUES LESS THAN (40) ENGINE = MyISAM, + PARTITION `p5` VALUES LESS THAN (50) ENGINE = MyISAM, + PARTITION `pn` VALUES LESS THAN MAXVALUE ENGINE = MyISAM) +SELECT * FROM t1; +x +12 +2 +22 +32 +42 +52 +LOCK TABLE t1 WRITE; +alter table t1 convert partition p2 to table tp2; +ERROR 42S01: Table 'tp2' already exists +# d,fail_convert_partition_9: AFTER failure (under LOCK TABLE) +db.opt +t1#P#p1.MYD +t1#P#p1.MYI +t1#P#p2.MYD +t1#P#p2.MYI +t1#P#p3.MYD +t1#P#p3.MYI +t1#P#p4.MYD +t1#P#p4.MYI +t1#P#p5.MYD +t1#P#p5.MYI +t1#P#pn.MYD +t1#P#pn.MYI +t1.frm +t1.par +tp2.MYD +tp2.MYI +tp2.frm +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `x` int(11) NOT NULL, + PRIMARY KEY (`x`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 + PARTITION BY RANGE (`x`) +(PARTITION `p1` VALUES LESS THAN (10) ENGINE = MyISAM, + PARTITION `p2` VALUES LESS THAN (20) ENGINE = MyISAM, + PARTITION `p3` VALUES LESS THAN (30) ENGINE = MyISAM, + PARTITION `p4` VALUES LESS THAN (40) ENGINE = MyISAM, + PARTITION `p5` VALUES LESS THAN (50) ENGINE = MyISAM, + PARTITION `pn` VALUES LESS THAN MAXVALUE ENGINE = MyISAM) +SELECT * FROM t1; +x +12 +2 +22 +32 +42 +52 +UNLOCK TABLES; +DROP TABLE t1; +set session debug_dbug=@save_dbug; +show create table tp2; +Table Create Table +tp2 CREATE TABLE `tp2` ( + `x` int(11) NOT NULL, + PRIMARY KEY (`x`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +select * from tp2; +x +12 +drop table tp2; diff --git a/mysql-test/suite/parts/t/alter_table.combinations b/mysql-test/suite/parts/t/alter_table.combinations new file mode 100644 index 00000000000..d4feae10f19 --- /dev/null +++ b/mysql-test/suite/parts/t/alter_table.combinations @@ -0,0 +1,2 @@ +[range] +[list] diff --git a/mysql-test/suite/parts/t/alter_table.test b/mysql-test/suite/parts/t/alter_table.test index 53b61806acb..0d605c11bd6 100644 --- a/mysql-test/suite/parts/t/alter_table.test +++ b/mysql-test/suite/parts/t/alter_table.test @@ -1,9 +1,8 @@ -# -# General errors with ALTER TABLE and partitions that doesn't have to be run -# on all engines -# - +# Permissions don't work with embedded +--source include/not_embedded.inc --source include/have_partition.inc +--source include/lcase_names.inc +--source suite/parts/inc/engines.inc # # MDEV-22649 SIGSEGV in ha_partition::create_partitioning_metadata on ALTER @@ -38,3 +37,202 @@ CREATE TABLE t2 (i INT); ALTER TABLE v1 EXCHANGE PARTITION p2 WITH TABLE t2 ; DROP VIEW v1; DROP TABLE t1, t2; + +--echo # +--echo # MDEV-22166 MIGRATE PARTITION: move out partition into a table +--echo # + +create or replace table t1 (x int); +--error ER_PARTITION_MGMT_ON_NONPARTITIONED +alter table t1 convert partition p1 to table tp1; + +create or replace table t1 (x int) +partition by hash(x) partitions 2; +--error ER_ONLY_ON_RANGE_LIST_PARTITION +alter table t1 convert partition p1 to table tp1; + +create or replace table t1 (x int) +partition by key(x) partitions 2; +--error ER_ONLY_ON_RANGE_LIST_PARTITION +alter table t1 convert partition p1 to table tp1; + +create or replace table t1 (x int) +partition by range(x) +subpartition by hash(x) subpartitions 3 ( + partition p1 values less than (10), + partition pn values less than maxvalue); +--error ER_PARTITION_CONVERT_SUBPARTITIONED +alter table t1 convert partition p1 to table p1; +--error ER_PARTITION_DOES_NOT_EXIST +alter table t1 convert partition p1sp0 to table p1; + +create or replace table t1 (x int) +partition by range(x) ( + partition p1 values less than (10)); +--error ER_DROP_LAST_PARTITION +alter table t1 convert partition p1 to table tp1; + +--error ER_FEATURE_NOT_SUPPORTED_WITH_PARTITIONING +create or replace temporary table t1 (x int) +partition by range(x) ( + partition p0 values less than (10), + partition pn values less than maxvalue); + +if ($MTR_COMBINATION_RANGE) +{ + create or replace table t1 (x int) + partition by range(x) ( + partition p1 values less than (10), + partition p2 values less than (20), + partition p3 values less than (30), + partition p4 values less than (40), + partition p5 values less than (50), + partition pn values less than maxvalue); +} + +if ($MTR_COMBINATION_LIST) +{ + create or replace table t1 (x int) + partition by list(x) ( + partition p1 values in (2, 3, 4), + partition p2 values in (12, 13, 14), + partition p3 values in (22, 23, 24), + partition p4 values in (32, 33, 34), + partition p5 values in (42, 43, 44), + partition pn values in (52, 53, 54)); +} + +insert into t1 values (2), (12), (22), (32), (42), (52); + +create or replace table tp2 (y int); +insert tp2 values (88); +# Multiple ALTER PARTITION statements are not possible +--error ER_PARSE_ERROR +alter table t1 convert partition p2 to table tp2, drop partition p3; +# TODO: probably no need in such specific codes, should be ER_PARTITION_NON_EXISTENT +--error ER_PARTITION_DOES_NOT_EXIST +alter table t1 convert partition p00 to table tp00; +# Better error here is ER_PARTITION_DOES_NOT_EXIST, +# but mysql_alter_table() works checks new table before anything else. +# So, looks like no big reason to change anything here. +--error ER_TABLE_EXISTS_ERROR +alter table t1 convert partition p00 to table tp2; +--error ER_TABLE_EXISTS_ERROR +alter table t1 convert partition p2 to table tp2; +--delimiter $ +--error ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG +create trigger tr1 before update on t1 for each row +begin + alter table t1 convert partition p2 to table tp2; +end$ +--error ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG +create function f1() returns int +begin + alter table t1 convert partition p2 to table tp2; +end$ +--delimiter ; +select * from tp2; +drop table tp2; +alter table t1 convert partition p2 to table tp2; + +--replace_result $engine X ' PAGE_CHECKSUM=1' '' +show create table tp2; +select * from tp2; +--replace_result $engine X ' PAGE_CHECKSUM=1' '' +show create table t1; +select * from t1 order by x; + +--error ER_BAD_DB_ERROR +alter table t1 convert partition p3 to table inexistent.tp3; +create database EXISTENT; +alter table t1 convert partition p3 to table EXISTENT.TP3; + +# The only way to put `` into var... +--let $tp3=`select '`TP3`'` +if ($MTR_COMBINATION_LCASE1) +{ + --let $tp3= `select '`tp3`'` +} +--replace_result $engine X ' PAGE_CHECKSUM=1' '' $tp3 `TP3`-ok +show create table EXISTENT.TP3; +select * from EXISTENT.TP3 order by x; +--replace_result $engine X ' PAGE_CHECKSUM=1' '' +show create table t1; +select * from t1 order by x; + +--echo # LOCK TABLES +lock tables t1 write; +alter table t1 convert partition p4 to table tp4; +# TODO: lock table tp4 in ALTER TABLE, otherwise there is no +# guarantee in data consistency between t1 and tp4 +--error ER_TABLE_NOT_LOCKED +show create table tp4; + +unlock tables; +--replace_result $engine X ' PAGE_CHECKSUM=1' '' +show create table tp4; +select * from tp4; +--replace_result $engine X ' PAGE_CHECKSUM=1' '' +show create table t1; +select * from t1 order by x; + +--echo # PS +prepare stmt from 'alter table t1 convert partition p5 to table tp5'; +execute stmt; +--replace_result $engine X ' PAGE_CHECKSUM=1' '' +show create table tp5; +select * from tp5; +--replace_result $engine X ' PAGE_CHECKSUM=1' '' +show create table t1; +select * from t1 order by x; +drop table tp5; +--error ER_PARTITION_DOES_NOT_EXIST +execute stmt; +--error ER_PARTITION_DOES_NOT_EXIST +execute stmt; +drop prepare stmt; + +--echo # Privileges +create user alan; +grant usage on *.* to alan; +grant create, insert, drop on test.* to alan; +--connect alan,localhost,alan,,test +show grants for current_user; +--error ER_TABLEACCESS_DENIED_ERROR +alter table t1 convert partition p1 to table tp1; +--connection default +revoke all on test.* from alan; +grant create, insert, alter on test.* to alan; +--connection alan +use test; +show grants for current_user; +--error ER_TABLEACCESS_DENIED_ERROR +alter table t1 convert partition p1 to table tp1; +--connection default +revoke all on test.* from alan; +grant create, drop, alter on test.* to alan; +--connection alan +use test; +show grants for current_user; +--error ER_TABLEACCESS_DENIED_ERROR +alter table t1 convert partition p1 to table tp1; +--connection default +revoke all on test.* from alan; +grant insert, drop, alter on test.* to alan; +--connection alan +use test; +show grants for current_user; +--error ER_TABLEACCESS_DENIED_ERROR +alter table t1 convert partition p1 to table tp1; +--connection default +grant create, insert, drop, alter on test.* to alan; +--connection alan +use test; +show grants for current_user; +alter table t1 convert partition p1 to table tp1; +--disconnect alan +--connection default + +drop database EXISTENT; +drop user alan; +drop tables t1, tp1, tp2, tp4; diff --git a/mysql-test/suite/parts/t/partition_debug.test b/mysql-test/suite/parts/t/partition_debug.test index 6d7cf3ae8b3..48b3392aa4f 100644 --- a/mysql-test/suite/parts/t/partition_debug.test +++ b/mysql-test/suite/parts/t/partition_debug.test @@ -50,3 +50,63 @@ let $crash_statement= ALTER TABLE t1 EXCHANGE PARTITION p0 WITH TABLE t2; --source suite/parts/inc/partition_crash_exchange.inc 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 # +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), + partition p4 values less than (40), + partition p5 values less than (50), + partition pn values less than maxvalue); + +let $insert_statement= insert into t1 values (2), (12), (22), (32), (42), (52); +let $fail_statement= alter table t1 convert partition p2 to table tp2; + +set @save_dbug=@@debug_dbug; +set session debug_dbug="+d,fail_create_before_create_frm"; +--source suite/parts/inc/partition_fail.inc +set session debug_dbug=@save_dbug; +set session debug_dbug="+d,fail_alter_partition_after_write_frm"; +--source suite/parts/inc/partition_fail.inc +set session debug_dbug=@save_dbug; +set session debug_dbug="+d,error_convert_partition_00"; +--source suite/parts/inc/partition_fail.inc +#set session debug_dbug=@save_dbug; +#set session debug_dbug="+d,fail_convert_partition_01"; +#--source suite/parts/inc/partition_fail.inc +set session debug_dbug=@save_dbug; +set session debug_dbug="+d,fail_convert_partition_1"; +--source suite/parts/inc/partition_fail.inc +set session debug_dbug=@save_dbug; +set session debug_dbug="+d,fail_convert_partition_2"; +--source suite/parts/inc/partition_fail.inc +set session debug_dbug=@save_dbug; +set session debug_dbug="+d,fail_convert_partition_3"; +--source suite/parts/inc/partition_fail.inc +set session debug_dbug=@save_dbug; +set session debug_dbug="+d,fail_convert_partition_4"; +--source suite/parts/inc/partition_fail.inc +set session debug_dbug=@save_dbug; +set session debug_dbug="+d,fail_convert_partition_5"; +--source suite/parts/inc/partition_fail.inc +set session debug_dbug=@save_dbug; +set session debug_dbug="+d,fail_convert_partition_6"; +--source suite/parts/inc/partition_fail.inc +set session debug_dbug=@save_dbug; +set session debug_dbug="+d,fail_convert_partition_7"; +--source suite/parts/inc/partition_fail.inc +set session debug_dbug=@save_dbug; +set session debug_dbug="+d,fail_convert_partition_8"; +--source suite/parts/inc/partition_fail.inc +set session debug_dbug=@save_dbug; +set session debug_dbug="+d,fail_convert_partition_9"; +--echo # Already finished DDL logging, so tp2 now exists: +--source suite/parts/inc/partition_fail.inc +set session debug_dbug=@save_dbug; +show create table tp2; +select * from tp2; +drop table tp2; diff --git a/mysql-test/suite/versioning/r/partition,heap.rdiff b/mysql-test/suite/versioning/r/partition,heap.rdiff new file mode 100644 index 00000000000..f7b534bb114 --- /dev/null +++ b/mysql-test/suite/versioning/r/partition,heap.rdiff @@ -0,0 +1,85 @@ +--- partition.result ++++ partition,heap.reject +@@ -1545,82 +1545,3 @@ + (PARTITION `p0` HISTORY ENGINE = X, + PARTITION `pn` CURRENT ENGINE = X) + drop tables t1, tp1; +-# Complex table +-create or replace table t1 ( +-x int primary key auto_increment, +-t timestamp(6) default '2001-11-11 11:11:11', +-b blob(4096) compressed null, +-c varchar(1033) character set utf8 not null, +-u int, +-unique key (x, u), +-m enum('a', 'b', 'c') not null default 'a' comment 'absolute', +-i1 tinyint, i2 smallint, i3 bigint, +-index three(i1, i2, i3), +-v1 timestamp(6) generated always as (t + interval 1 day), +-v2 timestamp(6) generated always as (t + interval 1 month) stored, +-s timestamp(6) as row start, +-e timestamp(6) as row end, +-period for system_time (s, e), +-ps date, pe date, +-period for app_time (ps, pe), +-constraint check_constr check (u > -1)) +-with system versioning default charset=ucs2 +-partition by range(x) ( +-partition p0 values less than (10), +-partition p1 values less than (20), +-partition pn values less than maxvalue); +-alter table t1 convert partition p1 to table tp1; +-show create table tp1; +-Table Create Table +-tp1 CREATE TABLE `tp1` ( +- `x` int(11) NOT NULL AUTO_INCREMENT, +- `t` timestamp(6) NOT NULL DEFAULT '2001-11-11 11:11:11.000000', +- `b` blob /*!100301 COMPRESSED*/ DEFAULT NULL, +- `c` varchar(1033) CHARACTER SET utf8mb3 NOT NULL, +- `u` int(11) DEFAULT NULL, +- `m` enum('a','b','c') NOT NULL DEFAULT 'a' COMMENT 'absolute', +- `i1` tinyint(4) DEFAULT NULL, +- `i2` smallint(6) DEFAULT NULL, +- `i3` bigint(20) DEFAULT NULL, +- `v1` timestamp(6) GENERATED ALWAYS AS (`t` + interval 1 day) VIRTUAL, +- `v2` timestamp(6) GENERATED ALWAYS AS (`t` + interval 1 month) STORED, +- `s` timestamp(6) GENERATED ALWAYS AS ROW START, +- `e` timestamp(6) GENERATED ALWAYS AS ROW END, +- `ps` date NOT NULL, +- `pe` date NOT NULL, +- PERIOD FOR `app_time` (`ps`, `pe`), +- PRIMARY KEY (`x`,`e`), +- UNIQUE KEY `x` (`x`,`u`,`e`), +- KEY `three` (`i1`,`i2`,`i3`), +- PERIOD FOR SYSTEM_TIME (`s`, `e`), +- CONSTRAINT `check_constr` CHECK (`u` > -1) +-) ENGINE=X DEFAULT CHARSET=ucs2 WITH SYSTEM VERSIONING +-show create table t1; +-Table Create Table +-t1 CREATE TABLE `t1` ( +- `x` int(11) NOT NULL AUTO_INCREMENT, +- `t` timestamp(6) NOT NULL DEFAULT '2001-11-11 11:11:11.000000', +- `b` blob /*!100301 COMPRESSED*/ DEFAULT NULL, +- `c` varchar(1033) CHARACTER SET utf8mb3 NOT NULL, +- `u` int(11) DEFAULT NULL, +- `m` enum('a','b','c') NOT NULL DEFAULT 'a' COMMENT 'absolute', +- `i1` tinyint(4) DEFAULT NULL, +- `i2` smallint(6) DEFAULT NULL, +- `i3` bigint(20) DEFAULT NULL, +- `v1` timestamp(6) GENERATED ALWAYS AS (`t` + interval 1 day) VIRTUAL, +- `v2` timestamp(6) GENERATED ALWAYS AS (`t` + interval 1 month) STORED, +- `s` timestamp(6) GENERATED ALWAYS AS ROW START, +- `e` timestamp(6) GENERATED ALWAYS AS ROW END, +- `ps` date NOT NULL, +- `pe` date NOT NULL, +- PERIOD FOR `app_time` (`ps`, `pe`), +- PRIMARY KEY (`x`,`e`), +- UNIQUE KEY `x` (`x`,`u`,`e`), +- KEY `three` (`i1`,`i2`,`i3`), +- PERIOD FOR SYSTEM_TIME (`s`, `e`), +- CONSTRAINT `check_constr` CHECK (`u` > -1) +-) ENGINE=X DEFAULT CHARSET=ucs2 WITH SYSTEM VERSIONING +- PARTITION BY RANGE (`x`) +-(PARTITION `p0` VALUES LESS THAN (10) ENGINE = X, +- PARTITION `pn` VALUES LESS THAN MAXVALUE ENGINE = X) +-drop tables t1, tp1; diff --git a/mysql-test/suite/versioning/r/partition.result b/mysql-test/suite/versioning/r/partition.result index feb1e597e98..87af899b1b3 100644 --- a/mysql-test/suite/versioning/r/partition.result +++ b/mysql-test/suite/versioning/r/partition.result @@ -1286,3 +1286,367 @@ drop tables t1; # SET GLOBAL innodb_stats_persistent=@save_persistent; # End of 10.6 tests +# +# MDEV-22166 MIGRATE PARTITION: move out partition into a table +# +create or replace table t1 (x int) +with system versioning +partition by range(x) ( +partition p1 values less than (10), +partition p2 values less than (20), +partition p3 values less than (30), +partition p4 values less than (40), +partition p5 values less than (50), +partition pn values less than maxvalue); +insert into t1 values (2), (12), (22), (32), (42), (52); +update t1 set x= x + 1; +alter table t1 convert partition p2 to table tp2; +show create table tp2; +Table Create Table +tp2 CREATE TABLE `tp2` ( + `x` int(11) DEFAULT NULL +) ENGINE=X DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING +select * from tp2; +x +13 +select * from tp2 for system_time all order by x; +x +12 +13 +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `x` int(11) DEFAULT NULL +) ENGINE=X DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING + PARTITION BY RANGE (`x`) +(PARTITION `p1` VALUES LESS THAN (10) ENGINE = X, + PARTITION `p3` VALUES LESS THAN (30) ENGINE = X, + PARTITION `p4` VALUES LESS THAN (40) ENGINE = X, + PARTITION `p5` VALUES LESS THAN (50) ENGINE = X, + PARTITION `pn` VALUES LESS THAN MAXVALUE ENGINE = X) +select * from t1 order by x; +x +3 +23 +33 +43 +53 +select * from t1 for system_time all order by x; +x +2 +3 +22 +23 +32 +33 +42 +43 +52 +53 +# SP +create or replace procedure sp() +alter table t1 convert partition p3 to table tp3; +call sp; +show create table tp3; +Table Create Table +tp3 CREATE TABLE `tp3` ( + `x` int(11) DEFAULT NULL +) ENGINE=X DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING +select * from tp3; +x +23 +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `x` int(11) DEFAULT NULL +) ENGINE=X DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING + PARTITION BY RANGE (`x`) +(PARTITION `p1` VALUES LESS THAN (10) ENGINE = X, + PARTITION `p4` VALUES LESS THAN (40) ENGINE = X, + PARTITION `p5` VALUES LESS THAN (50) ENGINE = X, + PARTITION `pn` VALUES LESS THAN MAXVALUE ENGINE = X) +select * from t1 order by x; +x +3 +33 +43 +53 +drop table tp3; +call sp; +ERROR HY000: Wrong partition name or partition list +call sp; +ERROR HY000: Wrong partition name or partition list +drop procedure sp; +# LOCK TABLES, PS, SP +create or replace procedure sp() +alter table t1 convert partition p4 to table tp4; +lock tables t1 write; +prepare stmt from 'call sp'; +execute stmt; +unlock tables; +show create table tp4; +Table Create Table +tp4 CREATE TABLE `tp4` ( + `x` int(11) DEFAULT NULL +) ENGINE=X DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING +select * from tp4; +x +33 +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `x` int(11) DEFAULT NULL +) ENGINE=X DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING + PARTITION BY RANGE (`x`) +(PARTITION `p1` VALUES LESS THAN (10) ENGINE = X, + PARTITION `p5` VALUES LESS THAN (50) ENGINE = X, + PARTITION `pn` VALUES LESS THAN MAXVALUE ENGINE = X) +select * from t1 order by x; +x +3 +43 +53 +drop table tp4; +lock tables t1 write; +execute stmt; +ERROR HY000: Wrong partition name or partition list +call sp; +ERROR HY000: Wrong partition name or partition list +drop prepare stmt; +unlock tables; +drop procedure sp; +unlock tables; +drop tables t1, tp2; +# System-versioned tables (SYSTEM_TIME LIMIT) +create or replace table t1 ( +x int, +row_start timestamp(6) as row start invisible, +row_end timestamp(6) as row end invisible, +period for system_time(row_start, row_end) +) with system versioning +partition by system_time limit 1 partitions 4; +insert into t1 values (2), (12), (22); +update t1 set x= x + 1 where x = 2; +update t1 set x= x + 1 where x = 12; +update t1 set x= x + 1 where x = 22; +select * from t1 partition (p1); +x +12 +alter table t1 convert partition pn to table tp1; +ERROR HY000: Wrong partitions for `t1`: must have at least one HISTORY and exactly one last CURRENT +alter table t1 convert partition p1 to table tp1; +show create table tp1; +Table Create Table +tp1 CREATE TABLE `tp1` ( + `x` int(11) DEFAULT NULL, + `row_start` timestamp(6) GENERATED ALWAYS AS ROW START INVISIBLE, + `row_end` timestamp(6) GENERATED ALWAYS AS ROW END INVISIBLE, + PERIOD FOR SYSTEM_TIME (`row_start`, `row_end`) +) ENGINE=X DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING +select * from tp1; +x +select * from tp1 for system_time all; +x +12 +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `x` int(11) DEFAULT NULL, + `row_start` timestamp(6) GENERATED ALWAYS AS ROW START INVISIBLE, + `row_end` timestamp(6) GENERATED ALWAYS AS ROW END INVISIBLE, + PERIOD FOR SYSTEM_TIME (`row_start`, `row_end`) +) ENGINE=X DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING + PARTITION BY SYSTEM_TIME LIMIT 1 +(PARTITION `p0` HISTORY ENGINE = X, + PARTITION `p2` HISTORY ENGINE = X, + PARTITION `pn` CURRENT ENGINE = X) +select * from t1 order by x; +x +3 +13 +23 +select * from t1 for system_time all order by x; +x +2 +3 +13 +22 +23 +drop tables t1, tp1; +# System-versioned tables (SYSTEM_TIME INTERVAL) +set timestamp= unix_timestamp('2000-01-01 00:00:00'); +create or replace table t1 ( +x int, +row_start timestamp(6) as row start invisible, +row_end timestamp(6) as row end invisible, +period for system_time(row_start, row_end) +) with system versioning +partition by system_time interval 1 hour partitions 4; +insert into t1 values (2), (12), (22); +set timestamp= unix_timestamp('2000-01-01 00:00:01'); +update t1 set x= x + 1 where x = 2; +set timestamp= unix_timestamp('2000-01-01 01:00:00'); +update t1 set x= x + 1 where x = 12; +set timestamp= unix_timestamp('2000-01-01 02:00:00'); +update t1 set x= x + 1 where x = 22; +select * from t1 partition (p0); +x +2 +select * from t1 partition (p1); +x +12 +select * from t1 partition (p2); +x +22 +alter table t1 convert partition p1 to table tp1; +ERROR HY000: Can only drop oldest partitions when rotating by INTERVAL +alter table t1 convert partition p0 to table tp0; +alter table t1 convert partition p1 to table tp1; +alter table t1 convert partition p2 to table tp2; +ERROR HY000: Wrong partitions for `t1`: must have at least one HISTORY and exactly one last CURRENT +show create table tp0; +Table Create Table +tp0 CREATE TABLE `tp0` ( + `x` int(11) DEFAULT NULL, + `row_start` timestamp(6) GENERATED ALWAYS AS ROW START INVISIBLE, + `row_end` timestamp(6) GENERATED ALWAYS AS ROW END INVISIBLE, + PERIOD FOR SYSTEM_TIME (`row_start`, `row_end`) +) ENGINE=X DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING +show create table tp1; +Table Create Table +tp1 CREATE TABLE `tp1` ( + `x` int(11) DEFAULT NULL, + `row_start` timestamp(6) GENERATED ALWAYS AS ROW START INVISIBLE, + `row_end` timestamp(6) GENERATED ALWAYS AS ROW END INVISIBLE, + PERIOD FOR SYSTEM_TIME (`row_start`, `row_end`) +) ENGINE=X DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING +select * from tp0; +x +select * from tp1; +x +select * from tp0 for system_time all; +x +2 +select * from tp1 for system_time all; +x +12 +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `x` int(11) DEFAULT NULL, + `row_start` timestamp(6) GENERATED ALWAYS AS ROW START INVISIBLE, + `row_end` timestamp(6) GENERATED ALWAYS AS ROW END INVISIBLE, + PERIOD FOR SYSTEM_TIME (`row_start`, `row_end`) +) ENGINE=X DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING + PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR STARTS TIMESTAMP'2000-01-01 02:00:00' +(PARTITION `p2` HISTORY ENGINE = X, + PARTITION `pn` CURRENT ENGINE = X) +select * from t1; +x +3 +13 +23 +select * from t1 for system_time all order by x; +x +3 +13 +22 +23 +drop tables t1, tp0, tp1; +# System-versioned tables (implicit) +create or replace table t1(x int) with system versioning +partition by system_time limit 1 partitions 3; +alter table t1 convert partition p1 to table tp1; +show create table tp1; +Table Create Table +tp1 CREATE TABLE `tp1` ( + `x` int(11) DEFAULT NULL +) ENGINE=X DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `x` int(11) DEFAULT NULL +) ENGINE=X DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING + PARTITION BY SYSTEM_TIME LIMIT 1 +(PARTITION `p0` HISTORY ENGINE = X, + PARTITION `pn` CURRENT ENGINE = X) +drop tables t1, tp1; +# Complex table +create or replace table t1 ( +x int primary key auto_increment, +t timestamp(6) default '2001-11-11 11:11:11', +b blob(4096) compressed null, +c varchar(1033) character set utf8 not null, +u int, +unique key (x, u), +m enum('a', 'b', 'c') not null default 'a' comment 'absolute', +i1 tinyint, i2 smallint, i3 bigint, +index three(i1, i2, i3), +v1 timestamp(6) generated always as (t + interval 1 day), +v2 timestamp(6) generated always as (t + interval 1 month) stored, +s timestamp(6) as row start, +e timestamp(6) as row end, +period for system_time (s, e), +ps date, pe date, +period for app_time (ps, pe), +constraint check_constr check (u > -1)) +with system versioning default charset=ucs2 +partition by range(x) ( +partition p0 values less than (10), +partition p1 values less than (20), +partition pn values less than maxvalue); +alter table t1 convert partition p1 to table tp1; +show create table tp1; +Table Create Table +tp1 CREATE TABLE `tp1` ( + `x` int(11) NOT NULL AUTO_INCREMENT, + `t` timestamp(6) NOT NULL DEFAULT '2001-11-11 11:11:11.000000', + `b` blob /*!100301 COMPRESSED*/ DEFAULT NULL, + `c` varchar(1033) CHARACTER SET utf8mb3 NOT NULL, + `u` int(11) DEFAULT NULL, + `m` enum('a','b','c') NOT NULL DEFAULT 'a' COMMENT 'absolute', + `i1` tinyint(4) DEFAULT NULL, + `i2` smallint(6) DEFAULT NULL, + `i3` bigint(20) DEFAULT NULL, + `v1` timestamp(6) GENERATED ALWAYS AS (`t` + interval 1 day) VIRTUAL, + `v2` timestamp(6) GENERATED ALWAYS AS (`t` + interval 1 month) STORED, + `s` timestamp(6) GENERATED ALWAYS AS ROW START, + `e` timestamp(6) GENERATED ALWAYS AS ROW END, + `ps` date NOT NULL, + `pe` date NOT NULL, + PERIOD FOR `app_time` (`ps`, `pe`), + PRIMARY KEY (`x`,`e`), + UNIQUE KEY `x` (`x`,`u`,`e`), + KEY `three` (`i1`,`i2`,`i3`), + PERIOD FOR SYSTEM_TIME (`s`, `e`), + CONSTRAINT `check_constr` CHECK (`u` > -1) +) ENGINE=X DEFAULT CHARSET=ucs2 WITH SYSTEM VERSIONING +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `x` int(11) NOT NULL AUTO_INCREMENT, + `t` timestamp(6) NOT NULL DEFAULT '2001-11-11 11:11:11.000000', + `b` blob /*!100301 COMPRESSED*/ DEFAULT NULL, + `c` varchar(1033) CHARACTER SET utf8mb3 NOT NULL, + `u` int(11) DEFAULT NULL, + `m` enum('a','b','c') NOT NULL DEFAULT 'a' COMMENT 'absolute', + `i1` tinyint(4) DEFAULT NULL, + `i2` smallint(6) DEFAULT NULL, + `i3` bigint(20) DEFAULT NULL, + `v1` timestamp(6) GENERATED ALWAYS AS (`t` + interval 1 day) VIRTUAL, + `v2` timestamp(6) GENERATED ALWAYS AS (`t` + interval 1 month) STORED, + `s` timestamp(6) GENERATED ALWAYS AS ROW START, + `e` timestamp(6) GENERATED ALWAYS AS ROW END, + `ps` date NOT NULL, + `pe` date NOT NULL, + PERIOD FOR `app_time` (`ps`, `pe`), + PRIMARY KEY (`x`,`e`), + UNIQUE KEY `x` (`x`,`u`,`e`), + KEY `three` (`i1`,`i2`,`i3`), + PERIOD FOR SYSTEM_TIME (`s`, `e`), + CONSTRAINT `check_constr` CHECK (`u` > -1) +) ENGINE=X DEFAULT CHARSET=ucs2 WITH SYSTEM VERSIONING + PARTITION BY RANGE (`x`) +(PARTITION `p0` VALUES LESS THAN (10) ENGINE = X, + PARTITION `pn` VALUES LESS THAN MAXVALUE ENGINE = X) +drop tables t1, tp1; diff --git a/mysql-test/suite/versioning/t/partition.test b/mysql-test/suite/versioning/t/partition.test index b461dbaef3e..ce41e0c96b3 100644 --- a/mysql-test/suite/versioning/t/partition.test +++ b/mysql-test/suite/versioning/t/partition.test @@ -1110,4 +1110,203 @@ SET GLOBAL innodb_stats_persistent=@save_persistent; --echo # End of 10.6 tests +--echo # +--echo # MDEV-22166 MIGRATE PARTITION: move out partition into a table +--echo # +create or replace table t1 (x int) +with system versioning +partition by range(x) ( + partition p1 values less than (10), + partition p2 values less than (20), + partition p3 values less than (30), + partition p4 values less than (40), + partition p5 values less than (50), + partition pn values less than maxvalue); + +insert into t1 values (2), (12), (22), (32), (42), (52); +update t1 set x= x + 1; + +alter table t1 convert partition p2 to table tp2; +--replace_result $default_engine X ' PAGE_CHECKSUM=1' '' +show create table tp2; +select * from tp2; +select * from tp2 for system_time all order by x; + +--replace_result $default_engine X ' PAGE_CHECKSUM=1' '' +show create table t1; +select * from t1 order by x; +select * from t1 for system_time all order by x; + +--echo # SP +create or replace procedure sp() +alter table t1 convert partition p3 to table tp3; +call sp; +--replace_result $default_engine X ' PAGE_CHECKSUM=1' '' +show create table tp3; +select * from tp3; +--replace_result $default_engine X ' PAGE_CHECKSUM=1' '' +show create table t1; +select * from t1 order by x; +drop table tp3; +--error ER_PARTITION_DOES_NOT_EXIST +call sp; +--error ER_PARTITION_DOES_NOT_EXIST +call sp; +drop procedure sp; + +--echo # LOCK TABLES, PS, SP +create or replace procedure sp() +alter table t1 convert partition p4 to table tp4; +lock tables t1 write; +prepare stmt from 'call sp'; +execute stmt; + +# TODO: don't unlock here (see above TODO) +unlock tables; +--replace_result $default_engine X ' PAGE_CHECKSUM=1' '' +show create table tp4; +select * from tp4; +--replace_result $default_engine X ' PAGE_CHECKSUM=1' '' +show create table t1; +select * from t1 order by x; +drop table tp4; +lock tables t1 write; +--error ER_PARTITION_DOES_NOT_EXIST +execute stmt; +--error ER_PARTITION_DOES_NOT_EXIST +call sp; +drop prepare stmt; +unlock tables; +drop procedure sp; +unlock tables; + +drop tables t1, tp2; + +--echo # System-versioned tables (SYSTEM_TIME LIMIT) + +create or replace table t1 ( + x int, + row_start timestamp(6) as row start invisible, + row_end timestamp(6) as row end invisible, + period for system_time(row_start, row_end) +) with system versioning +partition by system_time limit 1 partitions 4; + +insert into t1 values (2), (12), (22); +update t1 set x= x + 1 where x = 2; +update t1 set x= x + 1 where x = 12; +update t1 set x= x + 1 where x = 22; + +select * from t1 partition (p1); +--error ER_VERS_WRONG_PARTS +alter table t1 convert partition pn to table tp1; +alter table t1 convert partition p1 to table tp1; + +--replace_result $default_engine X ' PAGE_CHECKSUM=1' '' +show create table tp1; +select * from tp1; +select * from tp1 for system_time all; + +--replace_result $default_engine X ' PAGE_CHECKSUM=1' '' +show create table t1; +select * from t1 order by x; +select * from t1 for system_time all order by x; + +drop tables t1, tp1; + +--echo # System-versioned tables (SYSTEM_TIME INTERVAL) + +set timestamp= unix_timestamp('2000-01-01 00:00:00'); +create or replace table t1 ( + x int, + row_start timestamp(6) as row start invisible, + row_end timestamp(6) as row end invisible, + period for system_time(row_start, row_end) +) with system versioning +partition by system_time interval 1 hour partitions 4; + +insert into t1 values (2), (12), (22); +set timestamp= unix_timestamp('2000-01-01 00:00:01'); +update t1 set x= x + 1 where x = 2; +set timestamp= unix_timestamp('2000-01-01 01:00:00'); +update t1 set x= x + 1 where x = 12; +set timestamp= unix_timestamp('2000-01-01 02:00:00'); +update t1 set x= x + 1 where x = 22; + +select * from t1 partition (p0); +select * from t1 partition (p1); +select * from t1 partition (p2); +--error ER_VERS_DROP_PARTITION_INTERVAL +alter table t1 convert partition p1 to table tp1; +alter table t1 convert partition p0 to table tp0; +alter table t1 convert partition p1 to table tp1; +--error ER_VERS_WRONG_PARTS +alter table t1 convert partition p2 to table tp2; + +--replace_result $default_engine X ' PAGE_CHECKSUM=1' '' +show create table tp0; +--replace_result $default_engine X ' PAGE_CHECKSUM=1' '' +show create table tp1; +select * from tp0; +select * from tp1; +select * from tp0 for system_time all; +select * from tp1 for system_time all; + +--replace_result $default_engine X ' PAGE_CHECKSUM=1' '' +show create table t1; +select * from t1; +select * from t1 for system_time all order by x; + +drop tables t1, tp0, tp1; + +--echo # System-versioned tables (implicit) + +create or replace table t1(x int) with system versioning +partition by system_time limit 1 partitions 3; + +alter table t1 convert partition p1 to table tp1; +--replace_result $default_engine X ' PAGE_CHECKSUM=1' '' +show create table tp1; +--replace_result $default_engine X ' PAGE_CHECKSUM=1' '' +show create table t1; + +drop tables t1, tp1; + +if (!$MTR_COMBINATION_HEAP) +{ +--echo # Complex table +create or replace table t1 ( + x int primary key auto_increment, + t timestamp(6) default '2001-11-11 11:11:11', + b blob(4096) compressed null, + c varchar(1033) character set utf8 not null, + u int, + unique key (x, u), + m enum('a', 'b', 'c') not null default 'a' comment 'absolute', + i1 tinyint, i2 smallint, i3 bigint, + index three(i1, i2, i3), + v1 timestamp(6) generated always as (t + interval 1 day), + v2 timestamp(6) generated always as (t + interval 1 month) stored, + s timestamp(6) as row start, + e timestamp(6) as row end, + period for system_time (s, e), + ps date, pe date, + period for app_time (ps, pe), + constraint check_constr check (u > -1)) +with system versioning default charset=ucs2 +partition by range(x) ( + partition p0 values less than (10), + partition p1 values less than (20), + partition pn values less than maxvalue); + +alter table t1 convert partition p1 to table tp1; + +--replace_result $default_engine X ' PAGE_CHECKSUM=1' '' +show create table tp1; +--replace_result $default_engine X ' PAGE_CHECKSUM=1' '' +show create table t1; + +drop tables t1, tp1; +} + --source suite/versioning/common_finish.inc diff --git a/sql/handler.h b/sql/handler.h index 1dfce4d4044..23e3bf6f5ce 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -824,6 +824,7 @@ typedef bool Log_func(THD*, TABLE*, bool, const uchar*, const uchar*); #define ALTER_PARTITION_TRUNCATE (1ULL << 11) // Set for REORGANIZE PARTITION #define ALTER_PARTITION_TABLE_REORG (1ULL << 12) +#define ALTER_PARTITION_CONVERT_OUT (1ULL << 13) /* This is master database for most of system tables. However there diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt index 6b8fd2bcd9e..9e21c39f17e 100644 --- a/sql/share/errmsg-utf8.txt +++ b/sql/share/errmsg-utf8.txt @@ -7992,3 +7992,5 @@ ER_STORAGE_ENGINE_DISABLED eng "Storage engine %s is disabled" WARN_SFORMAT_ERROR eng "SFORMAT error: %s" +ER_PARTITION_CONVERT_SUBPARTITIONED + eng "Convert partition is not supported for subpartitioned table." diff --git a/sql/sql_alter.cc b/sql/sql_alter.cc index 4213721c130..ae6f60dbc6c 100644 --- a/sql/sql_alter.cc +++ b/sql/sql_alter.cc @@ -262,10 +262,8 @@ Alter_table_ctx::Alter_table_ctx() storage_engine_partitioned(false), tmp_storage_engine_name_partitioned(false), fk_error_if_delete_row(false), fk_error_id(NULL), - fk_error_table(NULL) -#ifdef DBUG_ASSERT_EXISTS - , tmp_table(false) -#endif + fk_error_table(NULL), + tmp_table(false) { } @@ -442,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_OUT) || (alter_info.flags & ALTER_RENAME)) priv_needed|= DROP_ACL; diff --git a/sql/sql_alter.h b/sql/sql_alter.h index a0f89c28d2a..5975aa9a101 100644 --- a/sql/sql_alter.h +++ b/sql/sql_alter.h @@ -250,13 +250,15 @@ public: const LEX_CSTRING *new_db_arg, const LEX_CSTRING *new_name_arg); /** - @return true if the table is moved to another database, false otherwise. + @return true if the table is moved to another database or a new table + created by ALTER_PARTITION_CONVERT_OUT, false otherwise. */ bool is_database_changed() const { return (new_db.str != db.str); }; /** - @return true if the table is renamed, false otherwise. + @return true if the table is renamed or a new table created by + ALTER_PARTITION_CONVERT_OUT, false otherwise. */ bool is_table_renamed() const { return (is_database_changed() || new_name.str != table_name.str); }; diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 7441305276f..e46800dcdc2 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -11255,6 +11255,26 @@ bool LEX::stmt_alter_table_exchange_partition(Table_ident *table) } +bool LEX::stmt_alter_table(Table_ident *table) +{ + DBUG_ASSERT(sql_command == SQLCOM_ALTER_TABLE); + DBUG_ASSERT(!m_sql_cmd); + first_select_lex()->db= table->db; + if (first_select_lex()->db.str == NULL && + copy_db_to(&first_select_lex()->db)) + return true; + if (unlikely(check_table_name(table->table.str, table->table.length, + false)) || + (table->db.str && unlikely(check_db_name((LEX_STRING*) &table->db)))) + { + my_error(ER_WRONG_TABLE_NAME, MYF(0), table->table.str); + return true; + } + name= table->table; + return false; +} + + void LEX::stmt_purge_to(const LEX_CSTRING &to) { type= 0; diff --git a/sql/sql_lex.h b/sql/sql_lex.h index ef4e738860b..14cf90caa04 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -4661,6 +4661,7 @@ public: void stmt_deallocate_prepare(const Lex_ident_sys_st &ident); bool stmt_alter_table_exchange_partition(Table_ident *table); + bool stmt_alter_table(Table_ident *table); void stmt_purge_to(const LEX_CSTRING &to); bool stmt_purge_before(Item *item); diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index 06f8fee80cd..d53d91c3504 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -77,11 +77,6 @@ using std::min; #ifdef WITH_PARTITION_STORAGE_ENGINE #include "ha_partition.h" -#define ERROR_INJECT_CRASH(code) \ - (DBUG_IF(code) && (DBUG_SUICIDE(), 0)) -#define ERROR_INJECT_ERROR(code) \ - (DBUG_IF(code) && (my_error(ER_UNKNOWN_ERROR, MYF(0)), 1)) - /* Partition related functions declarations and some static constants; */ @@ -4871,6 +4866,7 @@ uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info, if (alter_info->partition_flags & (ALTER_PARTITION_ADD | ALTER_PARTITION_DROP | + ALTER_PARTITION_CONVERT_OUT | ALTER_PARTITION_COALESCE | ALTER_PARTITION_REORGANIZE | ALTER_PARTITION_TABLE_REORG | @@ -5366,8 +5362,12 @@ that are reorganised. tab_part_info->is_auto_partitioned= FALSE; } } - else if (alter_info->partition_flags & ALTER_PARTITION_DROP) + else if ((alter_info->partition_flags & ALTER_PARTITION_DROP) | + (alter_info->partition_flags & ALTER_PARTITION_CONVERT_OUT)) { + const char * const cmd= + (alter_info->partition_flags & ALTER_PARTITION_CONVERT_OUT) ? + "CONVERT" : "DROP"; /* Drop a partition from a range partition and list partitioning is always safe and can be made more or less immediate. It is necessary @@ -5396,7 +5396,7 @@ that are reorganised. if (!(tab_part_info->part_type == RANGE_PARTITION || tab_part_info->part_type == LIST_PARTITION)) { - my_error(ER_ONLY_ON_RANGE_LIST_PARTITION, MYF(0), "DROP"); + my_error(ER_ONLY_ON_RANGE_LIST_PARTITION, MYF(0), cmd); goto err; } if (num_parts_dropped >= tab_part_info->num_parts) @@ -5438,7 +5438,7 @@ that are reorganised. } while (++part_count < tab_part_info->num_parts); if (num_parts_found != num_parts_dropped) { - my_error(ER_DROP_PARTITION_NON_EXISTENT, MYF(0), "DROP"); + my_error(ER_PARTITION_DOES_NOT_EXIST, MYF(0)); goto err; } if (table->file->is_fk_defined_on_table_or_index(MAX_KEY)) @@ -5446,8 +5446,17 @@ that are reorganised. my_error(ER_ROW_IS_REFERENCED, MYF(0)); goto err; } + DBUG_ASSERT(!(alter_info->partition_flags & ALTER_PARTITION_CONVERT_OUT) || + num_parts_dropped == 1); /* NOTE: num_parts is used in generate_partition_syntax() */ tab_part_info->num_parts-= num_parts_dropped; + if ((alter_info->partition_flags & ALTER_PARTITION_CONVERT_OUT) && + tab_part_info->is_sub_partitioned()) + { + // TODO technically this can be converted to a *partitioned* table + my_error(ER_PARTITION_CONVERT_SUBPARTITIONED, MYF(0)); + goto err; + } } else if (alter_info->partition_flags & ALTER_PARTITION_REBUILD) { @@ -5791,7 +5800,7 @@ the generated partition syntax in a correct manner. goto err; } } - } // ADD, DROP, COALESCE, REORGANIZE, TABLE_REORG, REBUILD + } // ADD, DROP, COALESCE, REORGANIZE, TABLE_REORG, REBUILD, CONVERT else { /* @@ -6131,6 +6140,68 @@ static bool mysql_drop_partitions(ALTER_PARTITION_PARAM_TYPE *lpt) } +/* + Convert partition to a table in an ALTER TABLE of partitions + + SYNOPSIS + alter_partition_convert_out() + lpt Struct containing parameters + + RETURN VALUES + TRUE Failure + FALSE Success + + DESCRIPTION + Rename partition table marked with PART_TO_BE_DROPPED into a separate table + under the name lpt->alter_ctx->(new_db, new_name). + + This is ddl-logged by write_log_convert_out_partition(). +*/ + +static bool alter_partition_convert_out(ALTER_PARTITION_PARAM_TYPE *lpt) +{ + partition_info *part_info= lpt->table->part_info; + THD *thd= lpt->thd; + int error; + handler *file= get_new_handler(NULL, thd->mem_root, part_info->default_engine_type); + + DBUG_ASSERT(lpt->thd->mdl_context.is_lock_owner(MDL_key::TABLE, + lpt->table->s->db.str, + lpt->table->s->table_name.str, + MDL_EXCLUSIVE)); + + char from_name[FN_REFLEN + 1], to_name[FN_REFLEN + 1]; + const char *path= lpt->table->s->path.str; + + build_table_filename(to_name, sizeof(to_name) - 1, lpt->alter_ctx->new_db.str, + lpt->alter_ctx->new_name.str, "", 0); + + for (const partition_element &e: part_info->partitions) + { + if (e.part_state != PART_TO_BE_DROPPED) + continue; + + if (unlikely((error= create_partition_name(from_name, sizeof(from_name), + path, e.partition_name, + NORMAL_PART_NAME, FALSE)))) + { + DBUG_ASSERT(thd->is_error()); + return true; + } + if (DBUG_IF("error_convert_partition_00") || + unlikely(error= file->ha_rename_table(from_name, to_name))) + { + my_error(ER_ERROR_ON_RENAME, MYF(0), from_name, to_name, my_errno); + lpt->table->file->print_error(error, MYF(0)); + return true; + } + break; + } + + return false; +} + + /* Release all log entries for this partition info struct SYNOPSIS @@ -6169,6 +6240,11 @@ static void release_part_info_log_entries(DDL_LOG_MEMORY_ENTRY *log_entry) the partition info object */ + +/* + TODO: Partitioning atomic DDL refactoring: this should be replaced with + ddl_log_create_table(). +*/ static bool write_log_delete_frm(ALTER_PARTITION_PARAM_TYPE *lpt, const char *to_path) { @@ -6177,7 +6253,8 @@ static bool write_log_delete_frm(ALTER_PARTITION_PARAM_TYPE *lpt, DBUG_ENTER("write_log_delete_frm"); bzero(&ddl_log_entry, sizeof(ddl_log_entry)); ddl_log_entry.action_type= DDL_LOG_DELETE_ACTION; - ddl_log_entry.next_entry= 0; + ddl_log_entry.next_entry= lpt->part_info->list ? lpt->part_info->list->entry_pos : 0; + lex_string_set(&ddl_log_entry.handler_name, reg_ext); lex_string_set(&ddl_log_entry.name, to_path); @@ -6207,7 +6284,7 @@ static bool write_log_delete_frm(ALTER_PARTITION_PARAM_TYPE *lpt, the partition info object */ -static bool write_log_replace_frm(ALTER_PARTITION_PARAM_TYPE *lpt, +bool write_log_replace_frm(ALTER_PARTITION_PARAM_TYPE *lpt, uint next_entry, const char *from_path, const char *to_path) @@ -6343,21 +6420,21 @@ static bool write_log_changed_partitions(ALTER_PARTITION_PARAM_TYPE *lpt, /* - Log dropped partitions + Log dropped or converted partitions SYNOPSIS - write_log_dropped_partitions() + log_drop_or_convert_action() lpt Struct containing parameters RETURN VALUES TRUE Error FALSE Success */ -static bool write_log_dropped_partitions(ALTER_PARTITION_PARAM_TYPE *lpt, - uint *next_entry, - const char *path, - bool temp_list) +static bool log_drop_or_convert_action(ALTER_PARTITION_PARAM_TYPE *lpt, + uint *next_entry, const char *path, + const char *from_name, bool temp_list) { DDL_LOG_ENTRY ddl_log_entry; + const bool convert_action= (from_name != NULL); partition_info *part_info= lpt->part_info; DDL_LOG_MEMORY_ENTRY *log_entry; char tmp_path[FN_REFLEN + 1]; @@ -6365,10 +6442,13 @@ static bool write_log_dropped_partitions(ALTER_PARTITION_PARAM_TYPE *lpt, List_iterator temp_it(part_info->temp_partitions); uint num_temp_partitions= part_info->temp_partitions.elements; uint num_elements= part_info->partitions.elements; - DBUG_ENTER("write_log_dropped_partitions"); + DBUG_ENTER("log_drop_or_convert_action"); bzero(&ddl_log_entry, sizeof(ddl_log_entry)); - ddl_log_entry.action_type= DDL_LOG_DELETE_ACTION; + + ddl_log_entry.action_type= convert_action ? + DDL_LOG_RENAME_ACTION : + DDL_LOG_DELETE_ACTION; if (temp_list) num_elements= num_temp_partitions; while (num_elements--) @@ -6389,8 +6469,10 @@ static bool write_log_dropped_partitions(ALTER_PARTITION_PARAM_TYPE *lpt, name_variant= TEMP_PART_NAME; else name_variant= NORMAL_PART_NAME; + DBUG_ASSERT(!convert_action || part_elem->part_state == PART_TO_BE_DROPPED); if (part_info->is_sub_partitioned()) { + DBUG_ASSERT(!convert_action); List_iterator sub_it(part_elem->subpartitions); uint num_subparts= part_info->num_subparts; uint j= 0; @@ -6424,7 +6506,9 @@ static bool write_log_dropped_partitions(ALTER_PARTITION_PARAM_TYPE *lpt, part_elem->partition_name, name_variant, TRUE)) DBUG_RETURN(TRUE); - lex_string_set(&ddl_log_entry.name, tmp_path); + ddl_log_entry.name= { tmp_path, strlen(tmp_path) }; + if (convert_action) + ddl_log_entry.from_name= { from_name, strlen(from_name) }; if (ddl_log_write_entry(&ddl_log_entry, &log_entry)) { DBUG_RETURN(TRUE); @@ -6439,6 +6523,35 @@ static bool write_log_dropped_partitions(ALTER_PARTITION_PARAM_TYPE *lpt, } +inline +static bool write_log_dropped_partitions(ALTER_PARTITION_PARAM_TYPE *lpt, + uint *next_entry, const char *path, + bool temp_list) +{ + return log_drop_or_convert_action(lpt, next_entry, path, NULL, temp_list); +} + +inline +static bool write_log_convert_out_partition(ALTER_PARTITION_PARAM_TYPE *lpt, + uint *next_entry, const char *path) +{ + char from_name[FN_REFLEN + 1]; + build_table_filename(from_name, sizeof(from_name) - 1, lpt->alter_ctx->new_db.str, + lpt->alter_ctx->new_name.str, "", 0); + DDL_LOG_MEMORY_ENTRY *main_entry= lpt->part_info->main_entry; + bool res= log_drop_or_convert_action(lpt, next_entry, path, from_name, false); + /* + NOTE: main_entry is "drop shadow frm", we have to keep it like this, + because partitioning crash-safety disables it at install shadow FRM phase + That is not really needed though, because shadow frm is replaced with + backup frm so there is nothing to drop. But we avoid spurious action by + disabling it. + */ + lpt->part_info->main_entry= main_entry; + return res; +} + + /* Write the log entry to ensure that the shadow frm file is removed at crash. @@ -6455,17 +6568,22 @@ static bool write_log_dropped_partitions(ALTER_PARTITION_PARAM_TYPE *lpt, file and its corresponding handler file. */ -static bool write_log_drop_shadow_frm(ALTER_PARTITION_PARAM_TYPE *lpt) +static bool write_log_drop_shadow_frm(ALTER_PARTITION_PARAM_TYPE *lpt, + uint flags= 0) { partition_info *part_info= lpt->part_info; DDL_LOG_MEMORY_ENTRY *log_entry; - char shadow_path[FN_REFLEN + 1]; + char path[FN_REFLEN + 1]; DBUG_ENTER("write_log_drop_shadow_frm"); + const bool drop_backup= (flags & WFRM_DROP_BACKUP); - build_table_shadow_filename(shadow_path, sizeof(shadow_path) - 1, lpt); + DBUG_ASSERT(!drop_backup || !part_info->is_active()); + + build_table_shadow_filename(path, sizeof(path) - 1, lpt, drop_backup); mysql_mutex_lock(&LOCK_gdl); - if (write_log_delete_frm(lpt, (const char*)shadow_path)) + if (write_log_delete_frm(lpt, (const char*)path)) goto error; + log_entry= part_info->list; if (ddl_log_write_execute_entry(log_entry->entry_pos, &part_info->execute_entry)) @@ -6585,6 +6703,35 @@ error: } +static bool write_log_convert_out_partition(ALTER_PARTITION_PARAM_TYPE *lpt) +{ + partition_info *part_info= lpt->part_info; + char tmp_path[FN_REFLEN + 1]; + char path[FN_REFLEN + 1]; + uint next_entry= part_info->list ? part_info->list->entry_pos : 0; + + build_table_filename(path, sizeof(path) - 1, lpt->db.str, lpt->table_name.str, "", 0); + build_table_shadow_filename(tmp_path, sizeof(tmp_path) - 1, lpt); + + mysql_mutex_lock(&LOCK_gdl); + + if (write_log_convert_out_partition(lpt, &next_entry, (const char*)path)) + goto error; + DBUG_ASSERT(next_entry == part_info->list->entry_pos); + if (ddl_log_write_execute_entry(part_info->list->entry_pos, + &part_info->execute_entry)) + goto error; + mysql_mutex_unlock(&LOCK_gdl); + return false; + +error: + mysql_mutex_unlock(&LOCK_gdl); + part_info->main_entry= NULL; + my_error(ER_DDL_LOG_ERROR, MYF(0)); + return true; +} + + /* Write the log entries to ensure that the add partition command is not executed at all if a crash before it has completed @@ -6721,6 +6868,10 @@ error: FALSE Success */ +/* + TODO: Partitioning atomic DDL refactoring: this should be replaced with + ddl_log_complete(). +*/ static void write_log_completed(ALTER_PARTITION_PARAM_TYPE *lpt, bool dont_crash) { @@ -6832,6 +6983,10 @@ static int alter_close_table(ALTER_PARTITION_PARAM_TYPE *lpt) @param close_table Table is still open, close it before reverting */ +/* + TODO: Partitioning atomic DDL refactoring: this should be replaced with + correct combination of ddl_log_revert() / ddl_log_complete() +*/ static void handle_alter_part_error(ALTER_PARTITION_PARAM_TYPE *lpt, bool action_completed, bool drop_partition, @@ -7066,11 +7221,23 @@ bool log_partition_alter_to_ddl_log(ALTER_PARTITION_PARAM_TYPE *lpt) uint fast_alter_partition_table(THD *thd, TABLE *table, Alter_info *alter_info, + Alter_table_ctx *alter_ctx, HA_CREATE_INFO *create_info, - TABLE_LIST *table_list, - const LEX_CSTRING *db, - const LEX_CSTRING *table_name) + TABLE_LIST *table_list) { + /* + TODO: Partitioning atomic DDL refactoring. + + DDL log chain state is stored in partition_info: + + struct st_ddl_log_memory_entry *first_log_entry; + struct st_ddl_log_memory_entry *exec_log_entry; + struct st_ddl_log_memory_entry *frm_log_entry; + + Make it stored and used in DDL_LOG_STATE like it was done in MDEV-17567. + This requires mysql_write_frm() refactoring (see comment there). + */ + /* Set-up struct used to write frm files */ partition_info *part_info; ALTER_PARTITION_PARAM_TYPE lpt_obj; @@ -7088,13 +7255,14 @@ uint fast_alter_partition_table(THD *thd, TABLE *table, lpt->table_list= table_list; lpt->part_info= part_info; lpt->alter_info= alter_info; + lpt->alter_ctx= alter_ctx; lpt->create_info= create_info; lpt->db_options= create_info->table_options_with_row_type(); lpt->table= table; lpt->key_info_buffer= 0; lpt->key_count= 0; - lpt->db= *db; - lpt->table_name= *table_name; + lpt->db= alter_ctx->db; + lpt->table_name= alter_ctx->table_name; lpt->org_tabledef_version= table->s->tabledef_version; lpt->copied= 0; lpt->deleted= 0; @@ -7253,6 +7421,67 @@ uint fast_alter_partition_table(THD *thd, TABLE *table, if (alter_partition_lock_handling(lpt)) goto err; } + else if (alter_info->partition_flags & ALTER_PARTITION_CONVERT_OUT) + { + if (mysql_write_frm(lpt, WFRM_WRITE_CONVERTED_TO) || + ERROR_INJECT_CRASH("crash_convert_partition_1") || + ERROR_INJECT_ERROR("fail_convert_partition_1") || + write_log_drop_shadow_frm(lpt) || + ERROR_INJECT_CRASH("crash_convert_partition_2") || + ERROR_INJECT_ERROR("fail_convert_partition_2") || + mysql_write_frm(lpt, WFRM_WRITE_SHADOW) || + ERROR_INJECT_CRASH("crash_convert_partition_3") || + ERROR_INJECT_ERROR("fail_convert_partition_3") || + wait_while_table_is_used(thd, table, HA_EXTRA_NOT_USED) || + ERROR_INJECT_CRASH("crash_convert_partition_4") || + ERROR_INJECT_ERROR("fail_convert_partition_4") || + write_log_convert_out_partition(lpt) || + ERROR_INJECT_CRASH("crash_convert_partition_5") || + ERROR_INJECT_ERROR("fail_convert_partition_5") || + alter_close_table(lpt) || + ERROR_INJECT_CRASH("crash_convert_partition_6") || + ERROR_INJECT_ERROR("fail_convert_partition_6") || + alter_partition_convert_out(lpt) || + ERROR_INJECT_CRASH("crash_convert_partition_7") || + ERROR_INJECT_ERROR("fail_convert_partition_7") || + (frm_install= true, false) || + mysql_write_frm(lpt, WFRM_INSTALL_SHADOW|WFRM_BACKUP_ORIGINAL) || + log_partition_alter_to_ddl_log(lpt) || + (frm_install= false, false) || + ERROR_INJECT_CRASH("crash_convert_partition_8") || + ERROR_INJECT_ERROR("fail_convert_partition_8") || + ((!thd->lex->no_write_to_binlog) && + ((thd->binlog_xid= thd->query_id), + ddl_log_update_xid(lpt->part_info, thd->binlog_xid), + write_bin_log(thd, false, thd->query(), thd->query_length()), + (thd->binlog_xid= 0))) || + (ddl_log_complete(lpt->part_info), false) || + /* + TODO: + + 1. Add DDL_LOG_EXECUTE_IF_CLOSED to ddl_log_entry_code. + Execute entry is executed only if another entry is active. + This requires ddl log file extension or store entry_pos into some + string field of execute entry: name, tmp_name, etc. These are + not used now for execute entry. + 2. Log WFRM_DROP_BACKUP into separate "cleanup" chain and execute it + only if the main chain is closed. That must be logged before + WFRM_BACKUP_ORIGINAL is done. + + */ + write_log_drop_shadow_frm(lpt, WFRM_DROP_BACKUP) || + ERROR_INJECT_CRASH("crash_convert_partition_9") || + ERROR_INJECT_ERROR("fail_convert_partition_9")) + { + (void) ddl_log_revert(thd, lpt->part_info); + handle_alter_part_error(lpt, true, true, frm_install); + goto err; + } + /* Drop backup frm */ + (void) ddl_log_revert(thd, lpt->part_info); + if (alter_partition_lock_handling(lpt)) + goto err; + } else if ((alter_info->partition_flags & ALTER_PARTITION_ADD) && (part_info->part_type == RANGE_PARTITION || part_info->part_type == LIST_PARTITION)) diff --git a/sql/sql_partition.h b/sql/sql_partition.h index 57e6d0600ed..e2e5fdf4c4b 100644 --- a/sql/sql_partition.h +++ b/sql/sql_partition.h @@ -55,6 +55,7 @@ typedef struct st_lock_param_type THD *thd; HA_CREATE_INFO *create_info; Alter_info *alter_info; + Alter_table_ctx *alter_ctx; TABLE *table; KEY *key_info_buffer; LEX_CSTRING db; @@ -64,6 +65,7 @@ typedef struct st_lock_param_type uint key_count; uint db_options; size_t pack_frm_len; + // TODO: remove duplicate data: part_info can be accessed via table->part_info partition_info *part_info; } ALTER_PARTITION_PARAM_TYPE; @@ -255,10 +257,9 @@ typedef int (*get_partitions_in_range_iter)(partition_info *part_info, #ifdef WITH_PARTITION_STORAGE_ENGINE uint fast_alter_partition_table(THD *thd, TABLE *table, Alter_info *alter_info, + Alter_table_ctx *alter_ctx, HA_CREATE_INFO *create_info, - TABLE_LIST *table_list, - const LEX_CSTRING *db, - const LEX_CSTRING *table_name); + TABLE_LIST *table_list); bool set_part_state(Alter_info *alter_info, partition_info *tab_part_info, enum partition_state part_state); uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info, @@ -279,6 +280,10 @@ bool verify_data_with_partition(TABLE *table, TABLE *part_table, bool compare_partition_options(HA_CREATE_INFO *table_create_info, partition_element *part_elem); 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 diff --git a/sql/sql_table.cc b/sql/sql_table.cc index b2bc1e620d9..ec636c28b6a 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -667,10 +667,12 @@ void build_lower_case_table_filename(char *buff, size_t bufflen, */ uint build_table_shadow_filename(char *buff, size_t bufflen, - ALTER_PARTITION_PARAM_TYPE *lpt) + ALTER_PARTITION_PARAM_TYPE *lpt, + bool backup) { char tmp_name[FN_REFLEN]; - my_snprintf(tmp_name, sizeof (tmp_name), "%s-shadow-%lx-%s", tmp_file_prefix, + my_snprintf(tmp_name, sizeof (tmp_name), "%s-%s-%lx-%s", tmp_file_prefix, + backup ? "backup" : "shadow", (ulong) current_thd->thread_id, lpt->table_name.str); return build_table_filename(buff, bufflen, lpt->db.str, tmp_name, "", FN_IS_TMP); @@ -704,6 +706,11 @@ uint build_table_shadow_filename(char *buff, size_t bufflen, tables since it only handles partitioned data if it exists. */ + +/* + TODO: Partitioning atomic DDL refactoring: WFRM_WRITE_SHADOW and + WFRM_WRITE_EXTRACTED should be merged with create_table_impl(frm_only == true). +*/ bool mysql_write_frm(ALTER_PARTITION_PARAM_TYPE *lpt, uint flags) { /* @@ -715,10 +722,13 @@ bool mysql_write_frm(ALTER_PARTITION_PARAM_TYPE *lpt, uint flags) char path[FN_REFLEN+1]; char shadow_path[FN_REFLEN+1]; char shadow_frm_name[FN_REFLEN+1]; + char bak_path[FN_REFLEN+1]; + char bak_frm_name[FN_REFLEN+1]; char frm_name[FN_REFLEN+1]; #ifdef WITH_PARTITION_STORAGE_ENGINE char *part_syntax_buf; uint syntax_len; + partition_info *part_info= lpt->part_info; #endif DBUG_ENTER("mysql_write_frm"); @@ -777,6 +787,98 @@ bool mysql_write_frm(ALTER_PARTITION_PARAM_TYPE *lpt, uint flags) goto end; } } +#ifdef WITH_PARTITION_STORAGE_ENGINE + if (flags & WFRM_WRITE_CONVERTED_TO) + { + THD *thd= lpt->thd; + Alter_table_ctx *alter_ctx= lpt->alter_ctx; + HA_CREATE_INFO *create_info= lpt->create_info; + + LEX_CSTRING new_path= { alter_ctx->get_new_path(), 0 }; + partition_info *work_part_info= thd->work_part_info; + handlerton *db_type= create_info->db_type; + DBUG_ASSERT(lpt->table->part_info); + DBUG_ASSERT(lpt->table->part_info == part_info); + handler *file= ((ha_partition *)(lpt->table->file))->get_child_handlers()[0]; + DBUG_ASSERT(file); + new_path.length= strlen(new_path.str); + strxnmov(frm_name, sizeof(frm_name) - 1, new_path.str, reg_ext, NullS); + create_info->alias= alter_ctx->table_name; + thd->work_part_info= NULL; + create_info->db_type= work_part_info->default_engine_type; + /* NOTE: partitioned temporary tables are not supported. */ + DBUG_ASSERT(!create_info->tmp_table()); + if (ddl_log_create_table(thd, part_info, create_info->db_type, &new_path, + &alter_ctx->new_db, &alter_ctx->new_name, true) || + ERROR_INJECT_ERROR("fail_create_before_create_frm")) + DBUG_RETURN(TRUE); + + debug_crash_here("ddl_log_create_before_create_frm"); + if (mysql_prepare_create_table(thd, create_info, lpt->alter_info, + &lpt->db_options, file, + &lpt->key_info_buffer, &lpt->key_count, + C_ALTER_TABLE, alter_ctx->new_db, + alter_ctx->new_name)) + DBUG_RETURN(TRUE); + + lpt->create_info->table_options= lpt->db_options; + LEX_CUSTRING frm= build_frm_image(thd, alter_ctx->new_name, create_info, + lpt->alter_info->create_list, + lpt->key_count, lpt->key_info_buffer, + file); + if (unlikely(!frm.str)) + DBUG_RETURN(TRUE); + + thd->work_part_info= work_part_info; + create_info->db_type= db_type; + + debug_crash_here("ddl_log_alter_partition_after_create_frm"); + + error= writefile(frm_name, alter_ctx->new_db.str, alter_ctx->new_name.str, + create_info->tmp_table(), frm.str, frm.length); + my_free((void *) frm.str); + if (unlikely(error) || ERROR_INJECT_ERROR("fail_alter_partition_after_write_frm")) + { + mysql_file_delete(key_file_frm, frm_name, MYF(0)); + DBUG_RETURN(TRUE); + } + + debug_crash_here("ddl_log_alter_partition_after_write_frm"); + DBUG_RETURN(false); + } + if (flags & WFRM_BACKUP_ORIGINAL) + { + build_table_filename(path, sizeof(path) - 1, lpt->db.str, + lpt->table_name.str, "", 0); + strxnmov(frm_name, sizeof(frm_name), path, reg_ext, NullS); + + build_table_shadow_filename(bak_path, sizeof(bak_path) - 1, lpt, true); + strxmov(bak_frm_name, bak_path, reg_ext, NullS); + + DDL_LOG_MEMORY_ENTRY *main_entry= part_info->main_entry; + mysql_mutex_lock(&LOCK_gdl); + if (write_log_replace_frm(lpt, part_info->list->entry_pos, + (const char*) bak_path, + (const char*) path) || + ddl_log_write_execute_entry(part_info->list->entry_pos, + &part_info->execute_entry)) + { + mysql_mutex_unlock(&LOCK_gdl); + DBUG_RETURN(TRUE); + } + mysql_mutex_unlock(&LOCK_gdl); + part_info->main_entry= main_entry; + if (mysql_file_rename(key_file_frm, frm_name, bak_frm_name, MYF(MY_WME))) + DBUG_RETURN(TRUE); + if (lpt->table->file->ha_create_partitioning_metadata(bak_path, path, + CHF_RENAME_FLAG)) + DBUG_RETURN(TRUE); + } +#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) { #ifdef WITH_PARTITION_STORAGE_ENGINE @@ -798,20 +900,25 @@ bool mysql_write_frm(ALTER_PARTITION_PARAM_TYPE *lpt, uint flags) completing this we write a new phase to the log entry that will deactivate it. */ - if (mysql_file_delete(key_file_frm, frm_name, MYF(MY_WME)) || + if (!(flags & WFRM_BACKUP_ORIGINAL) && ( + mysql_file_delete(key_file_frm, frm_name, MYF(MY_WME)) #ifdef WITH_PARTITION_STORAGE_ENGINE - lpt->table->file->ha_create_partitioning_metadata(path, shadow_path, + || lpt->table->file->ha_create_partitioning_metadata(path, shadow_path, CHF_DELETE_FLAG) || ddl_log_increment_phase(part_info->main_entry->entry_pos) || - (ddl_log_sync(), FALSE) || - mysql_file_rename(key_file_frm, - shadow_frm_name, frm_name, MYF(MY_WME)) || - lpt->table->file->ha_create_partitioning_metadata(path, shadow_path, - CHF_RENAME_FLAG)) -#else - mysql_file_rename(key_file_frm, - shadow_frm_name, frm_name, MYF(MY_WME))) + (ddl_log_sync(), FALSE) #endif + )) + { + error= 1; + goto err; + } + if (mysql_file_rename(key_file_frm, shadow_frm_name, frm_name, MYF(MY_WME)) +#ifdef WITH_PARTITION_STORAGE_ENGINE + || lpt->table->file->ha_create_partitioning_metadata(path, shadow_path, + CHF_RENAME_FLAG) +#endif + ) { error= 1; goto err; @@ -4161,7 +4268,6 @@ err: @retval -1 table existed but IF NOT EXISTS was used */ -static int create_table_impl(THD *thd, DDL_LOG_STATE *ddl_log_state_create, DDL_LOG_STATE *ddl_log_state_rm, @@ -9892,10 +9998,8 @@ do_continue:; } // In-place execution of ALTER TABLE for partitioning. - DBUG_RETURN(fast_alter_partition_table(thd, table, alter_info, - create_info, table_list, - &alter_ctx.db, - &alter_ctx.table_name)); + DBUG_RETURN(fast_alter_partition_table(thd, table, alter_info, &alter_ctx, + create_info, table_list)); } #endif diff --git a/sql/sql_table.h b/sql/sql_table.h index aacb6c99f15..a925e32b573 100644 --- a/sql/sql_table.h +++ b/sql/sql_table.h @@ -20,6 +20,11 @@ #include // pthread_mutex_t #include "m_string.h" // LEX_CUSTRING +#define ERROR_INJECT_CRASH(code) \ + (DBUG_IF(code) && (DBUG_SUICIDE(), false)) +#define ERROR_INJECT_ERROR(code) \ + (DBUG_IF(code) && (my_error(ER_UNKNOWN_ERROR, MYF(0)), 1)) + class Alter_info; class Alter_table_ctx; class Column_definition; @@ -53,6 +58,9 @@ enum enum_explain_filename_mode #define WFRM_WRITE_SHADOW 1 #define WFRM_INSTALL_SHADOW 2 #define WFRM_KEEP_SHARE 4 +#define WFRM_WRITE_CONVERTED_TO 8 +#define WFRM_BACKUP_ORIGINAL 16 +#define WFRM_DROP_BACKUP 32 /* Flags for conversion functions. */ static const uint FN_FROM_IS_TMP= 1 << 0; @@ -77,7 +85,8 @@ bool check_mysql50_prefix(const char *name); uint build_table_filename(char *buff, size_t bufflen, const char *db, const char *table, const char *ext, uint flags); uint build_table_shadow_filename(char *buff, size_t bufflen, - ALTER_PARTITION_PARAM_TYPE *lpt); + ALTER_PARTITION_PARAM_TYPE *lpt, + bool backup= false); void build_lower_case_table_filename(char *buff, size_t bufflen, const LEX_CSTRING *db, const LEX_CSTRING *table, diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 11f64a58057..20f69c29a15 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -7279,6 +7279,17 @@ alter_commands: if (Lex->stmt_alter_table_exchange_partition($6)) MYSQL_YYABORT; } + | CONVERT_SYM PARTITION_SYM alt_part_name_item + TO_SYM TABLE_SYM table_ident have_partitioning + { + LEX *lex= Lex; + if (Lex->stmt_alter_table($6)) + MYSQL_YYABORT; + lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_alter_table(); + if (unlikely(lex->m_sql_cmd == NULL)) + MYSQL_YYABORT; + lex->alter_info.partition_flags|= ALTER_PARTITION_CONVERT_OUT; + } ; remove_partitioning: @@ -7527,17 +7538,9 @@ alter_list_item: } | RENAME opt_to table_ident { - LEX *lex=Lex; - lex->first_select_lex()->db= $3->db; - if (lex->first_select_lex()->db.str == NULL && - lex->copy_db_to(&lex->first_select_lex()->db)) + if (Lex->stmt_alter_table($3)) MYSQL_YYABORT; - if (unlikely(check_table_name($3->table.str,$3->table.length, - FALSE)) || - ($3->db.str && unlikely(check_db_name((LEX_STRING*) &$3->db)))) - my_yyabort_error((ER_WRONG_TABLE_NAME, MYF(0), $3->table.str)); - lex->name= $3->table; - lex->alter_info.flags|= ALTER_RENAME; + Lex->alter_info.flags|= ALTER_RENAME; } | RENAME COLUMN_SYM opt_if_exists_table_element ident TO_SYM ident {