summaryrefslogtreecommitdiff
path: root/sql/field.h
diff options
context:
space:
mode:
authorMats Kindahl <mats@sun.com>2009-12-15 16:11:44 +0100
committerMats Kindahl <mats@sun.com>2009-12-15 16:11:44 +0100
commitf43ca0254ee4d8aa5943833e61ef17f7c2a09ead (patch)
treefab9c04efb15be30737eabf84a75edf8323de3fe /sql/field.h
parentc701fe6a06a95db92cc01b37ecf504246aab73f2 (diff)
downloadmariadb-git-f43ca0254ee4d8aa5943833e61ef17f7c2a09ead.tar.gz
BUG#49618: Field length stored incorrectly in binary log
for InnoDB The class Field_bit_as_char stores the metadata for the field incorrecly because bytes_in_rec and bit_len are set to (field_length + 7 ) / 8 and 0 respectively, while Field_bit has the correct values field_length / 8 and field_length % 8. Solved the problem by re-computing the values for the metadata based on the field_length instead of using the bytes_in_rec and bit_len variables. To handle compatibility with old server, a table map flag was added to indicate that the bit computation is exact. If the flag is clear, the slave computes the number of bytes required to store the bit field and compares that instead, effectively allowing replication *without conversion* from any field length that require the same number of bytes to store.
Diffstat (limited to 'sql/field.h')
-rw-r--r--sql/field.h8
1 files changed, 4 insertions, 4 deletions
diff --git a/sql/field.h b/sql/field.h
index cfa3e57d2a0..12ee9b46d03 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -165,7 +165,7 @@ public:
*/
virtual uint32 pack_length_in_rec() const { return pack_length(); }
virtual bool compatible_field_size(uint metadata, Relay_log_info *rli,
- int *order);
+ uint16 mflags, int *order);
virtual uint pack_length_from_metadata(uint field_metadata)
{
DBUG_ENTER("Field::pack_length_from_metadata");
@@ -805,7 +805,7 @@ public:
uint pack_length_from_metadata(uint field_metadata);
uint row_pack_length() { return pack_length(); }
bool compatible_field_size(uint field_metadata, Relay_log_info *rli,
- int *order_var);
+ uint16 mflags, int *order_var);
uint is_equal(Create_field *new_field);
virtual const uchar *unpack(uchar* to, const uchar *from,
uint param_data, bool low_byte_first);
@@ -1500,7 +1500,7 @@ public:
return (((field_metadata >> 4) & 0x300) ^ 0x300) + (field_metadata & 0x00ff);
}
bool compatible_field_size(uint field_metadata, Relay_log_info *rli,
- int *order_var);
+ uint16 mflags, int *order_var);
uint row_pack_length() { return field_length; }
int pack_cmp(const uchar *a,const uchar *b,uint key_length,
my_bool insert_or_update);
@@ -1964,7 +1964,7 @@ public:
uint row_pack_length()
{ return (bytes_in_rec + ((bit_len > 0) ? 1 : 0)); }
bool compatible_field_size(uint metadata, Relay_log_info *rli,
- int *order_var);
+ uint16 mflags, int *order_var);
void sql_type(String &str) const;
virtual uchar *pack(uchar *to, const uchar *from,
uint max_length, bool low_byte_first);