diff options
author | Mats Kindahl <mats@mysql.com> | 2008-06-30 22:11:18 +0200 |
---|---|---|
committer | Mats Kindahl <mats@mysql.com> | 2008-06-30 22:11:18 +0200 |
commit | 2a089557a68107925f1f1e197db65d04b5bf377b (patch) | |
tree | 99d0103a1bedf9e6a2c68aa7ca343d20d8dafc6d /sql/rpl_utility.cc | |
parent | 5672b953cca4ba36b2ba1b61aeeeecbbf99815bd (diff) | |
download | mariadb-git-2a089557a68107925f1f1e197db65d04b5bf377b.tar.gz |
BUG#37426: RBR breaks for CHAR() UTF-8 fields > 85 chars
In order to handle CHAR() fields, 8 bits were reserved for
the size of the CHAR field. However, instead of denoting the
number of characters in the field, field_length was used which
denotes the number of bytes in the field.
Since UTF-8 fields can have three bytes per character (and
has been extended to have four bytes per character in 6.0),
an extra two bits have been encoded in the field metadata
work for fields of type Field_string (i.e., CHAR fields).
Since the metadata word is filled, the extra bits have been
encoded in the upper 4 bits of the real type (the most
significant byte of the metadata word) by computing the
bitwise xor of the extra two bits. Since the upper 4 bits
of the real type always is 1111 for Field_string, this
means that for fields of length <256, the encoding is
identical to the encoding used in pre-5.1.26 servers, but
for lengths of 256 or more, an unrecognized type is formed,
causing an old slave (that does not handle lengths of 256
or more) to stop.
Diffstat (limited to 'sql/rpl_utility.cc')
-rw-r--r-- | sql/rpl_utility.cc | 16 |
1 files changed, 8 insertions, 8 deletions
diff --git a/sql/rpl_utility.cc b/sql/rpl_utility.cc index 4f4083d9b8f..e34f8561051 100644 --- a/sql/rpl_utility.cc +++ b/sql/rpl_utility.cc @@ -188,7 +188,8 @@ table_def::compatible_with(Relay_log_info const *rli_arg, TABLE *table) for (uint col= 0 ; col < cols_to_check ; ++col) { - if (table->field[col]->type() != type(col)) + Field *const field= table->field[col]; + if (field->type() != type(col)) { DBUG_ASSERT(col < size() && col < tsh->fields); DBUG_ASSERT(tsh->db.str && tsh->table_name.str); @@ -197,15 +198,15 @@ table_def::compatible_with(Relay_log_info const *rli_arg, TABLE *table) my_snprintf(buf, sizeof(buf), "Column %d type mismatch - " "received type %d, %s.%s has type %d", col, type(col), tsh->db.str, tsh->table_name.str, - table->field[col]->type()); + field->type()); rli->report(ERROR_LEVEL, ER_BINLOG_ROW_WRONG_TABLE_DEF, ER(ER_BINLOG_ROW_WRONG_TABLE_DEF), buf); } /* Check the slave's field size against that of the master. */ - if (!error && - !table->field[col]->compatible_field_size(field_metadata(col))) + if (!error && + !field->compatible_field_size(field_metadata(col), rli_arg)) { error= 1; char buf[256]; @@ -213,10 +214,9 @@ table_def::compatible_with(Relay_log_info const *rli_arg, TABLE *table) "master has size %d, %s.%s on slave has size %d." " Master's column size should be <= the slave's " "column size.", col, - table->field[col]->pack_length_from_metadata( - m_field_metadata[col]), - tsh->db.str, tsh->table_name.str, - table->field[col]->row_pack_length()); + field->pack_length_from_metadata(m_field_metadata[col]), + tsh->db.str, tsh->table_name.str, + field->row_pack_length()); rli->report(ERROR_LEVEL, ER_BINLOG_ROW_WRONG_TABLE_DEF, ER(ER_BINLOG_ROW_WRONG_TABLE_DEF), buf); } |