diff --git a/mysql-test/suite/rpl/r/rpl_alter.result b/mysql-test/suite/rpl/r/rpl_alter.result index 2cffa70d778..7be3bc576f3 100644 --- a/mysql-test/suite/rpl/r/rpl_alter.result +++ b/mysql-test/suite/rpl/r/rpl_alter.result @@ -14,4 +14,109 @@ select * from mysqltest.t3; n 45 drop database mysqltest; +use test; +# +# Test bug where ALTER TABLE MODIFY didn't replicate properly +# +create table t1 (a int unsigned primary key, b int); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(10) unsigned NOT NULL, + `b` int(11) DEFAULT NULL, + PRIMARY KEY (`a`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 (a) values (1),((1<<32)-1); +select * from t1; +a b +1 NULL +4294967295 NULL +alter table t1 modify a bigint; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` bigint(20) NOT NULL DEFAULT '0', + `b` int(11) DEFAULT NULL, + PRIMARY KEY (`a`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +select * from t1; +a b +1 NULL +4294967295 NULL +alter table t1 modify a int unsigned; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(10) unsigned NOT NULL DEFAULT '0', + `b` int(11) DEFAULT NULL, + PRIMARY KEY (`a`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +select * from t1; +a b +1 NULL +4294967295 NULL +alter table t1 modify a bigint unsigned; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` bigint(20) unsigned NOT NULL DEFAULT '0', + `b` int(11) DEFAULT NULL, + PRIMARY KEY (`a`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +select * from t1; +a b +1 NULL +4294967295 NULL +use test; +select * from t1; +a b +1 NULL +4294967295 NULL +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` bigint(20) unsigned NOT NULL DEFAULT '0', + `b` int(11) DEFAULT NULL, + PRIMARY KEY (`a`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +create table t2 (a int unsigned auto_increment primary key, b int); +show create table t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `a` int(10) unsigned NOT NULL AUTO_INCREMENT, + `b` int(11) DEFAULT NULL, + PRIMARY KEY (`a`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +alter table t2 modify a bigint; +show create table t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `a` bigint(20) NOT NULL DEFAULT '0', + `b` int(11) DEFAULT NULL, + PRIMARY KEY (`a`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +alter table t2 modify a bigint auto_increment; +show create table t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `a` bigint(20) NOT NULL AUTO_INCREMENT, + `b` int(11) DEFAULT NULL, + PRIMARY KEY (`a`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1,t2; +# +# MDEV-8432: Slave cannot replicate signed integer-type values +# with high bit set to 1 +# Test replication when we have int on master and bigint on slave +# +create table t1 (a int unsigned primary key, b int); +SET GLOBAL SLAVE_TYPE_CONVERSIONS='ALL_NON_LOSSY'; +alter table t1 modify a bigint unsigned; +insert into t1 (a) values (1),((1<<32)-1); +select * from t1; +a b +1 NULL +4294967295 NULL +SET GLOBAL SLAVE_TYPE_CONVERSIONS=''; +drop table t1; include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_alter.test b/mysql-test/suite/rpl/t/rpl_alter.test index 630197f8637..8b8bcfb3d26 100644 --- a/mysql-test/suite/rpl/t/rpl_alter.test +++ b/mysql-test/suite/rpl/t/rpl_alter.test @@ -15,4 +15,57 @@ drop database mysqltest; sync_slave_with_master; # End of 4.1 tests + +connection master; +use test; + +--echo # +--echo # Test bug where ALTER TABLE MODIFY didn't replicate properly +--echo # + +create table t1 (a int unsigned primary key, b int); +show create table t1; +insert into t1 (a) values (1),((1<<32)-1); +select * from t1; +alter table t1 modify a bigint; +show create table t1; +select * from t1; +alter table t1 modify a int unsigned; +show create table t1; +select * from t1; +alter table t1 modify a bigint unsigned; +show create table t1; +select * from t1; +sync_slave_with_master; +use test; +select * from t1; +show create table t1; +connection master; +# +create table t2 (a int unsigned auto_increment primary key, b int); +show create table t2; +alter table t2 modify a bigint; +show create table t2; +alter table t2 modify a bigint auto_increment; +show create table t2; +drop table t1,t2; + +--echo # +--echo # MDEV-8432: Slave cannot replicate signed integer-type values +--echo # with high bit set to 1 +--echo # Test replication when we have int on master and bigint on slave +--echo # + +create table t1 (a int unsigned primary key, b int); +sync_slave_with_master; +SET GLOBAL SLAVE_TYPE_CONVERSIONS='ALL_NON_LOSSY'; +alter table t1 modify a bigint unsigned; +connection master; +insert into t1 (a) values (1),((1<<32)-1); +sync_slave_with_master; +select * from t1; +SET GLOBAL SLAVE_TYPE_CONVERSIONS=''; +connection master; +drop table t1; + --source include/rpl_end.inc diff --git a/sql/rpl_utility.cc b/sql/rpl_utility.cc index e05ad5a8d43..9a20f71f4f7 100644 --- a/sql/rpl_utility.cc +++ b/sql/rpl_utility.cc @@ -876,6 +876,7 @@ TABLE *table_def::create_conversion_table(THD *thd, Relay_log_info *rli, TABLE * { Create_field *field_def= (Create_field*) alloc_root(thd->mem_root, sizeof(Create_field)); + bool unsigned_flag= 0; if (field_list.push_back(field_def)) DBUG_RETURN(NULL); @@ -885,8 +886,7 @@ TABLE *table_def::create_conversion_table(THD *thd, Relay_log_info *rli, TABLE * uint32 max_length= max_display_length_for_field(type(col), field_metadata(col)); - switch(type(col)) - { + switch(type(col)) { int precision; case MYSQL_TYPE_ENUM: case MYSQL_TYPE_SET: @@ -925,6 +925,18 @@ TABLE *table_def::create_conversion_table(THD *thd, Relay_log_info *rli, TABLE * pack_length= field_metadata(col) & 0x00ff; break; + case MYSQL_TYPE_TINY: + case MYSQL_TYPE_SHORT: + case MYSQL_TYPE_INT24: + case MYSQL_TYPE_LONG: + case MYSQL_TYPE_LONGLONG: + /* + As we don't know if the integer was signed or not on the master, + assume we have same sign on master and slave. This is true when not + using conversions so it should be true also when using conversions. + */ + unsigned_flag= ((Field_num*) target_table->field[col])->unsigned_flag; + break; default: break; } @@ -932,12 +944,13 @@ TABLE *table_def::create_conversion_table(THD *thd, Relay_log_info *rli, TABLE * DBUG_PRINT("debug", ("sql_type: %d, target_field: '%s', max_length: %d, decimals: %d," " maybe_null: %d, unsigned_flag: %d, pack_length: %u", type(col), target_table->field[col]->field_name, - max_length, decimals, TRUE, FALSE, pack_length)); + max_length, decimals, TRUE, unsigned_flag, + pack_length)); field_def->init_for_tmp_table(type(col), max_length, decimals, TRUE, // maybe_null - FALSE, // unsigned_flag + unsigned_flag, pack_length); field_def->charset= target_table->field[col]->charset(); field_def->interval= interval;