Commit c96be848 authored by Marko Mäkelä's avatar Marko Mäkelä

MDEV-14119 Assertion cmp_rec_rec() in ALTER TABLE

innobase_pk_order_preserved(): Treat an added AUTO_INCREMENT
column in the same way as an added existing column.
In either case, the column values are not guaranteed to
be constant, and thus the ordering may change if such a column
is added before any existing PRIMARY KEY columns.

prepare_inplace_alter_table_dict(): Initialize
dict_table_t::persistent_autoinc before invoking
innobase_pk_order_preserved().
parent de8d57e5
......@@ -263,3 +263,10 @@ create table t1(o1 int, o2 int, o3 int, primary key(o1,o2,o3)) engine = innodb;
insert into t1 values(1,1,2),(2,2,1);
alter table t1 drop primary key, add primary key(o1), lock=none;
drop table t1;
# pk(o1,o2) to pk(o1,o2,autoinc) must not sort
create table t1(o1 int, o2 int, primary key(o1,o2)) engine = innodb;
insert into t1 values(1,1),(2,1);
alter table t1 drop primary key, add column a int unique auto_increment,
add primary key(o1,o2,a), algorithm=inplace;
drop table t1;
......@@ -53,3 +53,10 @@ ALTER TABLE t1 DROP a;
ERROR HY000: Cannot drop index 'a': needed in a foreign key constraint
ALTER TABLE t1 ADD c INT;
DROP TABLE t1, tx;
#
# MDEV-14119 Assertion cmp_rec_rec() on ALTER TABLE
#
CREATE TABLE t1(a INT NOT NULL UNIQUE) ENGINE=InnoDB;
INSERT INTO t1 SELECT * FROM seq_1_to_128;
ALTER TABLE t1 ADD b TINYINT AUTO_INCREMENT PRIMARY KEY, DROP KEY a;
DROP TABLE t1;
......@@ -323,4 +323,9 @@ create table t1(o1 int, o2 int, o3 int, primary key(o1,o2,o3)) engine = innodb;
insert into t1 values(1,1,2),(2,2,1);
alter table t1 drop primary key, add primary key(o1), lock=none;
drop table t1;
create table t1(o1 int, o2 int, primary key(o1,o2)) engine = innodb;
insert into t1 values(1,1),(2,1);
alter table t1 drop primary key, add column a int unique auto_increment,
add primary key(o1,o2,a), algorithm=inplace;
drop table t1;
SET DEBUG_DBUG = @saved_debug_dbug;
......@@ -1903,6 +1903,11 @@ create table t1(o1 int, o2 int, o3 int, primary key(o1,o2,o3)) engine = innodb;
insert into t1 values(1,1,2),(2,2,1);
alter table t1 drop primary key, add primary key(o1), lock=none;
drop table t1;
create table t1(o1 int, o2 int, primary key(o1,o2)) engine = innodb;
insert into t1 values(1,1),(2,1);
alter table t1 drop primary key, add column a int unique auto_increment,
add primary key(o1,o2,a), algorithm=inplace;
drop table t1;
#
# MDEV-15325 Incomplete validation of missing tablespace during recovery
#
......
--source include/have_innodb.inc
--source include/have_sequence.inc
#
# MDEV-11995 ALTER TABLE proceeds despite reporting ER_TOO_LONG_KEY error
#
......@@ -59,3 +60,11 @@ ALTER TABLE t1 ADD b INT;
ALTER TABLE t1 DROP a;
ALTER TABLE t1 ADD c INT;
DROP TABLE t1, tx;
--echo #
--echo # MDEV-14119 Assertion cmp_rec_rec() on ALTER TABLE
--echo #
CREATE TABLE t1(a INT NOT NULL UNIQUE) ENGINE=InnoDB;
INSERT INTO t1 SELECT * FROM seq_1_to_128;
ALTER TABLE t1 ADD b TINYINT AUTO_INCREMENT PRIMARY KEY, DROP KEY a;
DROP TABLE t1;
......@@ -3362,7 +3362,11 @@ innobase_pk_order_preserved(
if (old_pk_column) {
new_field_order = old_field;
} else if (innobase_pk_col_is_existing(new_col_no, col_map,
old_n_cols)) {
old_n_cols)
|| new_clust_index->table->persistent_autoinc
== new_field + 1) {
/* Adding an existing column or an AUTO_INCREMENT
column may change the existing ordering. */
new_field_order = old_n_uniq + existing_field_count++;
} else {
/* Skip newly added column. */
......@@ -4913,12 +4917,6 @@ prepare_inplace_alter_table_dict(
user_table);
dict_index_t* new_clust_index = dict_table_get_first_index(
ctx->new_table);
ctx->skip_pk_sort = innobase_pk_order_preserved(
ctx->col_map, clust_index, new_clust_index);
DBUG_EXECUTE_IF("innodb_alter_table_pk_assert_no_sort",
DBUG_ASSERT(ctx->skip_pk_sort););
DBUG_ASSERT(!ctx->new_table->persistent_autoinc);
if (const Field* ai = altered_table->found_next_number_field) {
const unsigned col_no = innodb_col_no(ai);
......@@ -4937,6 +4935,12 @@ prepare_inplace_alter_table_dict(
}
}
ctx->skip_pk_sort = innobase_pk_order_preserved(
ctx->col_map, clust_index, new_clust_index);
DBUG_EXECUTE_IF("innodb_alter_table_pk_assert_no_sort",
DBUG_ASSERT(ctx->skip_pk_sort););
if (ctx->online) {
/* Allocate a log for online table rebuild. */
rw_lock_x_lock(&clust_index->lock);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment