Merging with mysql-5.1-bugteam
This commit is contained in:
commit
96d4a03846
15
mysql-test/suite/rpl/r/rpl_typeconv_innodb.result
Normal file
15
mysql-test/suite/rpl/r/rpl_typeconv_innodb.result
Normal file
@ -0,0 +1,15 @@
|
||||
stop slave;
|
||||
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
|
||||
reset master;
|
||||
reset slave;
|
||||
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
|
||||
start slave;
|
||||
**** Resetting master and slave ****
|
||||
include/stop_slave.inc
|
||||
RESET SLAVE;
|
||||
RESET MASTER;
|
||||
include/start_slave.inc
|
||||
CREATE TABLE t1(b1 BIT(1), b2 BIT(2), b3 BIT(3)) ENGINE=InnoDB;
|
||||
INSERT INTO t1 VALUES (b'0', b'01', b'101');
|
||||
Comparing tables master:test.t1 and slave:test.t1
|
||||
DROP TABLE t1;
|
1
mysql-test/suite/rpl/t/rpl_typeconv-slave.opt
Normal file
1
mysql-test/suite/rpl/t/rpl_typeconv-slave.opt
Normal file
@ -0,0 +1 @@
|
||||
--innodb
|
22
mysql-test/suite/rpl/t/rpl_typeconv_innodb.test
Normal file
22
mysql-test/suite/rpl/t/rpl_typeconv_innodb.test
Normal file
@ -0,0 +1,22 @@
|
||||
--source include/have_binlog_format_row.inc
|
||||
--source include/have_innodb.inc
|
||||
--source include/master-slave.inc
|
||||
|
||||
#
|
||||
# BUG#49618: Field length stored incorrectly in binary log for InnoDB
|
||||
#
|
||||
|
||||
source include/reset_master_and_slave.inc;
|
||||
|
||||
connection master;
|
||||
CREATE TABLE t1(b1 BIT(1), b2 BIT(2), b3 BIT(3)) ENGINE=InnoDB;
|
||||
INSERT INTO t1 VALUES (b'0', b'01', b'101');
|
||||
sync_slave_with_master;
|
||||
|
||||
let $diff_table_1=master:test.t1;
|
||||
let $diff_table_2=slave:test.t1;
|
||||
source include/diff_tables.inc;
|
||||
|
||||
connection master;
|
||||
DROP TABLE t1;
|
||||
sync_slave_with_master;
|
53
sql/field.cc
53
sql/field.cc
@ -1373,12 +1373,14 @@ bool Field::send_binary(Protocol *protocol)
|
||||
to the size of this field (the slave or destination).
|
||||
|
||||
@param field_metadata Encoded size in field metadata
|
||||
@param mflags Flags from the table map event for the table.
|
||||
|
||||
@retval 0 if this field's size is < the source field's size
|
||||
@retval 1 if this field's size is >= the source field's size
|
||||
*/
|
||||
int Field::compatible_field_size(uint field_metadata,
|
||||
const Relay_log_info *rli_arg __attribute__((unused)))
|
||||
const Relay_log_info *rli_arg __attribute__((unused)),
|
||||
uint16 mflags __attribute__((unused)))
|
||||
{
|
||||
uint const source_size= pack_length_from_metadata(field_metadata);
|
||||
uint const destination_size= row_pack_length();
|
||||
@ -2879,7 +2881,8 @@ uint Field_new_decimal::pack_length_from_metadata(uint field_metadata)
|
||||
@retval 1 if this field's size is >= the source field's size
|
||||
*/
|
||||
int Field_new_decimal::compatible_field_size(uint field_metadata,
|
||||
const Relay_log_info * __attribute__((unused)))
|
||||
const Relay_log_info * __attribute__((unused)),
|
||||
uint16 mflags __attribute__((unused)))
|
||||
{
|
||||
int compatible= 0;
|
||||
uint const source_precision= (field_metadata >> 8U) & 0x00ff;
|
||||
@ -6655,7 +6658,8 @@ check_field_for_37426(const void *param_arg)
|
||||
#endif
|
||||
|
||||
int Field_string::compatible_field_size(uint field_metadata,
|
||||
const Relay_log_info *rli_arg)
|
||||
const Relay_log_info *rli_arg,
|
||||
uint16 mflags __attribute__((unused)))
|
||||
{
|
||||
#ifdef HAVE_REPLICATION
|
||||
const Check_field_param check_param = { this };
|
||||
@ -6663,7 +6667,7 @@ int Field_string::compatible_field_size(uint field_metadata,
|
||||
check_field_for_37426, &check_param))
|
||||
return FALSE; // Not compatible field sizes
|
||||
#endif
|
||||
return Field::compatible_field_size(field_metadata, rli_arg);
|
||||
return Field::compatible_field_size(field_metadata, rli_arg, mflags);
|
||||
}
|
||||
|
||||
|
||||
@ -9213,8 +9217,13 @@ uint Field_bit::get_key_image(uchar *buff, uint length, imagetype type_arg)
|
||||
*/
|
||||
int Field_bit::do_save_field_metadata(uchar *metadata_ptr)
|
||||
{
|
||||
*metadata_ptr= bit_len;
|
||||
*(metadata_ptr + 1)= bytes_in_rec;
|
||||
/*
|
||||
Since this class and Field_bit_as_char have different ideas of
|
||||
what should be stored here, we compute the values of the metadata
|
||||
explicitly using the field_length.
|
||||
*/
|
||||
metadata_ptr[0]= field_length % 8;
|
||||
metadata_ptr[1]= field_length / 8;
|
||||
return 2;
|
||||
}
|
||||
|
||||
@ -9254,20 +9263,26 @@ uint Field_bit::pack_length_from_metadata(uint field_metadata)
|
||||
@retval 1 if this field's size is >= the source field's size
|
||||
*/
|
||||
int Field_bit::compatible_field_size(uint field_metadata,
|
||||
const Relay_log_info * __attribute__((unused)))
|
||||
const Relay_log_info * __attribute__((unused)),
|
||||
uint16 mflags)
|
||||
{
|
||||
int compatible= 0;
|
||||
uint const source_size= pack_length_from_metadata(field_metadata);
|
||||
uint const destination_size= row_pack_length();
|
||||
uint const from_bit_len= field_metadata & 0x00ff;
|
||||
uint const from_len= (field_metadata >> 8U) & 0x00ff;
|
||||
if ((bit_len == 0) || (from_bit_len == 0))
|
||||
compatible= (source_size <= destination_size);
|
||||
else if (from_bit_len > bit_len)
|
||||
compatible= (from_len < bytes_in_rec);
|
||||
else
|
||||
compatible= ((from_bit_len <= bit_len) && (from_len <= bytes_in_rec));
|
||||
return (compatible);
|
||||
uint from_bit_len= 8 * (field_metadata >> 8) + (field_metadata & 0xff);
|
||||
uint to_bit_len= max_display_length();
|
||||
|
||||
/*
|
||||
If the bit length exact flag is clear, we are dealing with an old
|
||||
master, so we allow some less strict behaviour if replicating by
|
||||
moving both bit lengths to an even multiple of 8.
|
||||
|
||||
We do this by computing the number of bytes to store the field
|
||||
instead, and then compare the result.
|
||||
*/
|
||||
if (!(mflags & Table_map_log_event::TM_BIT_LEN_EXACT_F)) {
|
||||
from_bit_len= (from_bit_len + 7) / 8;
|
||||
to_bit_len= (to_bit_len + 7) / 8;
|
||||
}
|
||||
|
||||
return from_bit_len <= to_bit_len;
|
||||
}
|
||||
|
||||
|
||||
|
@ -169,7 +169,7 @@ public:
|
||||
*/
|
||||
virtual uint32 pack_length_in_rec() const { return pack_length(); }
|
||||
virtual int compatible_field_size(uint field_metadata,
|
||||
const Relay_log_info *);
|
||||
const Relay_log_info *, uint16 mflags);
|
||||
virtual uint pack_length_from_metadata(uint field_metadata)
|
||||
{ return field_metadata; }
|
||||
/*
|
||||
@ -810,7 +810,7 @@ public:
|
||||
uint pack_length_from_metadata(uint field_metadata);
|
||||
uint row_pack_length() { return pack_length(); }
|
||||
int compatible_field_size(uint field_metadata,
|
||||
const Relay_log_info *rli);
|
||||
const Relay_log_info *rli, uint16 mflags);
|
||||
uint is_equal(Create_field *new_field);
|
||||
virtual const uchar *unpack(uchar* to, const uchar *from,
|
||||
uint param_data, bool low_byte_first);
|
||||
@ -1506,7 +1506,7 @@ public:
|
||||
return (((field_metadata >> 4) & 0x300) ^ 0x300) + (field_metadata & 0x00ff);
|
||||
}
|
||||
int compatible_field_size(uint field_metadata,
|
||||
const Relay_log_info *rli);
|
||||
const Relay_log_info *rli, uint16 mflags);
|
||||
uint row_pack_length() { return (field_length + 1); }
|
||||
int pack_cmp(const uchar *a,const uchar *b,uint key_length,
|
||||
my_bool insert_or_update);
|
||||
@ -1975,7 +1975,7 @@ public:
|
||||
uint row_pack_length()
|
||||
{ return (bytes_in_rec + ((bit_len > 0) ? 1 : 0)); }
|
||||
int compatible_field_size(uint field_metadata,
|
||||
const Relay_log_info *rli);
|
||||
const Relay_log_info *rli, uint16 mflags);
|
||||
void sql_type(String &str) const;
|
||||
virtual uchar *pack(uchar *to, const uchar *from,
|
||||
uint max_length, bool low_byte_first);
|
||||
|
@ -4062,11 +4062,8 @@ int THD::binlog_write_table_map(TABLE *table, bool is_trans)
|
||||
DBUG_ASSERT(current_stmt_binlog_row_based && mysql_bin_log.is_open());
|
||||
DBUG_ASSERT(table->s->table_map_id != ULONG_MAX);
|
||||
|
||||
Table_map_log_event::flag_set const
|
||||
flags= Table_map_log_event::TM_NO_FLAGS;
|
||||
|
||||
Table_map_log_event
|
||||
the_event(this, table, table->s->table_map_id, is_trans, flags);
|
||||
the_event(this, table, table->s->table_map_id, is_trans);
|
||||
|
||||
if (is_trans && binlog_table_maps == 0)
|
||||
binlog_start_trans_and_stmt();
|
||||
|
@ -7896,7 +7896,7 @@ int Table_map_log_event::save_field_metadata()
|
||||
*/
|
||||
#if !defined(MYSQL_CLIENT)
|
||||
Table_map_log_event::Table_map_log_event(THD *thd, TABLE *tbl, ulong tid,
|
||||
bool is_transactional, uint16 flags)
|
||||
bool is_transactional)
|
||||
: Log_event(thd, 0, true),
|
||||
m_table(tbl),
|
||||
m_dbnam(tbl->s->db.str),
|
||||
@ -7906,7 +7906,7 @@ Table_map_log_event::Table_map_log_event(THD *thd, TABLE *tbl, ulong tid,
|
||||
m_colcnt(tbl->s->fields),
|
||||
m_memory(NULL),
|
||||
m_table_id(tid),
|
||||
m_flags(flags),
|
||||
m_flags(TM_BIT_LEN_EXACT_F),
|
||||
m_data_size(0),
|
||||
m_field_metadata(0),
|
||||
m_field_metadata_size(0),
|
||||
@ -8164,8 +8164,10 @@ int Table_map_log_event::do_apply_event(Relay_log_info const *rli)
|
||||
inside Relay_log_info::clear_tables_to_lock() by calling the
|
||||
table_def destructor explicitly.
|
||||
*/
|
||||
new (&table_list->m_tabledef) table_def(m_coltype, m_colcnt,
|
||||
m_field_metadata, m_field_metadata_size, m_null_bits);
|
||||
new (&table_list->m_tabledef)
|
||||
table_def(m_coltype, m_colcnt,
|
||||
m_field_metadata, m_field_metadata_size,
|
||||
m_null_bits, m_flags);
|
||||
table_list->m_tabledef_valid= TRUE;
|
||||
|
||||
/*
|
||||
|
@ -3298,16 +3298,14 @@ public:
|
||||
/* Special constants representing sets of flags */
|
||||
enum
|
||||
{
|
||||
TM_NO_FLAGS = 0U
|
||||
TM_NO_FLAGS = 0U,
|
||||
TM_BIT_LEN_EXACT_F = (1U << 0)
|
||||
};
|
||||
|
||||
void set_flags(flag_set flag) { m_flags |= flag; }
|
||||
void clear_flags(flag_set flag) { m_flags &= ~flag; }
|
||||
flag_set get_flags(flag_set flag) const { return m_flags & flag; }
|
||||
|
||||
#ifndef MYSQL_CLIENT
|
||||
Table_map_log_event(THD *thd, TABLE *tbl, ulong tid,
|
||||
bool is_transactional, uint16 flags);
|
||||
Table_map_log_event(THD *thd, TABLE *tbl, ulong tid, bool is_transactional);
|
||||
#endif
|
||||
#ifdef HAVE_REPLICATION
|
||||
Table_map_log_event(const char *buf, uint event_len,
|
||||
@ -3320,7 +3318,7 @@ public:
|
||||
table_def *create_table_def()
|
||||
{
|
||||
return new table_def(m_coltype, m_colcnt, m_field_metadata,
|
||||
m_field_metadata_size, m_null_bits);
|
||||
m_field_metadata_size, m_null_bits, m_flags);
|
||||
}
|
||||
ulong get_table_id() const { return m_table_id; }
|
||||
const char *get_table_name() const { return m_tblnam; }
|
||||
|
@ -206,7 +206,7 @@ table_def::compatible_with(Relay_log_info const *rli_arg, TABLE *table)
|
||||
Check the slave's field size against that of the master.
|
||||
*/
|
||||
if (!error &&
|
||||
!field->compatible_field_size(field_metadata(col), rli_arg))
|
||||
!field->compatible_field_size(field_metadata(col), rli_arg, m_flags))
|
||||
{
|
||||
error= 1;
|
||||
char buf[256];
|
||||
|
@ -32,12 +32,6 @@ class Relay_log_info;
|
||||
- Extract and decode table definition data from the table map event
|
||||
- Check if table definition in table map is compatible with table
|
||||
definition on slave
|
||||
|
||||
Currently, the only field type data available is an array of the
|
||||
type operators that are present in the table map event.
|
||||
|
||||
@todo Add type operands to this structure to allow detection of
|
||||
difference between, e.g., BIT(5) and BIT(10).
|
||||
*/
|
||||
|
||||
class table_def
|
||||
@ -59,9 +53,9 @@ public:
|
||||
@param null_bitmap The bitmap of fields that can be null
|
||||
*/
|
||||
table_def(field_type *types, ulong size, uchar *field_metadata,
|
||||
int metadata_size, uchar *null_bitmap)
|
||||
int metadata_size, uchar *null_bitmap, uint16 flags)
|
||||
: m_size(size), m_type(0), m_field_metadata_size(metadata_size),
|
||||
m_field_metadata(0), m_null_bits(0), m_memory(NULL)
|
||||
m_field_metadata(0), m_null_bits(0), m_flags(flags), m_memory(NULL)
|
||||
{
|
||||
m_memory= (uchar *)my_multi_malloc(MYF(MY_WME),
|
||||
&m_type, size,
|
||||
@ -247,6 +241,7 @@ private:
|
||||
uint m_field_metadata_size;
|
||||
uint16 *m_field_metadata;
|
||||
uchar *m_null_bits;
|
||||
uint16 m_flags; // Table flags
|
||||
uchar *m_memory;
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user