1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-27 18:02:13 +03:00

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.
This commit is contained in:
Monty
2015-07-17 00:06:27 +03:00
parent bc300464f1
commit 00d3b20fbb
3 changed files with 175 additions and 4 deletions

View File

@ -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;