diff options
author | Monty <monty@mariadb.org> | 2015-07-17 00:06:27 +0300 |
---|---|---|
committer | Monty <monty@mariadb.org> | 2015-07-17 00:06:27 +0300 |
commit | 00d3b20fbb669840daebf2a4483cead92221d78c (patch) | |
tree | 49e323d47483613cdbea769c74e8bf27d35f0fec /sql/rpl_utility.cc | |
parent | bc300464f1674dc774fd166a87d8894cbe498563 (diff) | |
download | mariadb-git-00d3b20fbb669840daebf2a4483cead92221d78c.tar.gz |
MDEV-8432 Slave cannot replicate signed integer-type values with high bit set to 1
The fix is that if the slave has a different integer size than
the master, then they will assume the master has the same signed/unsigned modifier
as the slave.
This means that one can safely change a coon the slave an int to a bigint
or an unsigned int to an unsigned int. Changing an unsigned int to an
signed bigint will cause replication failures when the high bit of the
unsigned int is set.
We can't give an error if the signess is different on the master and slave
as the binary log doesn't contain the signess of the column on the master.
Diffstat (limited to 'sql/rpl_utility.cc')
-rw-r--r-- | sql/rpl_utility.cc | 21 |
1 files changed, 17 insertions, 4 deletions
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; |