summaryrefslogtreecommitdiff
path: root/sql/rpl_utility.cc
diff options
context:
space:
mode:
authorMonty <monty@mariadb.org>2015-07-17 00:06:27 +0300
committerMonty <monty@mariadb.org>2015-07-17 00:06:27 +0300
commit00d3b20fbb669840daebf2a4483cead92221d78c (patch)
tree49e323d47483613cdbea769c74e8bf27d35f0fec /sql/rpl_utility.cc
parentbc300464f1674dc774fd166a87d8894cbe498563 (diff)
downloadmariadb-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.cc21
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;