summaryrefslogtreecommitdiff
path: root/sql/field.h
diff options
context:
space:
mode:
authorMats Kindahl <mats.kindahl@oracle.com>2010-10-06 19:20:18 +0200
committerMats Kindahl <mats.kindahl@oracle.com>2010-10-06 19:20:18 +0200
commit9d249079a8b9ee24f4b3b69fb224d7b0aa664ca3 (patch)
tree2909636aa5d6cef036b49fdc3bb632d2c1580abb /sql/field.h
parentf703a7779fed9a9b677649ba443a6b467f0125d2 (diff)
downloadmariadb-git-9d249079a8b9ee24f4b3b69fb224d7b0aa664ca3.tar.gz
Bug #52131: SET and ENUM stored endian-dependent in binary log
Replication SET and ENUM fields from a big-endian to a little- endian machine (or the opposite) that are represented using more than 1 byte (SET fields with more than 8 members or ENUM fields with more than 256 constants) will fail to replicate correctly when using row-based replication. The reason is that there are no pack() or unpack() functions for Field_set or Field_enum, which make them rely on Field::pack and Field::unpack. These functions pack data as strings, but since Field_set and Field_enum use integral types for representation, the fields are stored incorrectly on big-endian machines. This patch adds Field_enum::pack and Field_enum::unpack functions that store the integral value correctly in the binary log even on big-endian machines. Since Field_set inherits from Field_enum, it will use the same functions for packing and unpacking the field.
Diffstat (limited to 'sql/field.h')
-rw-r--r--sql/field.h106
1 files changed, 76 insertions, 30 deletions
diff --git a/sql/field.h b/sql/field.h
index 7b250c34fe4..d854b78f9a3 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -554,6 +554,48 @@ private:
{ return 0; }
protected:
+ static void handle_int16(uchar *to, const uchar *from,
+ bool low_byte_first_from, bool low_byte_first_to)
+ {
+ int16 val;
+#ifdef WORDS_BIGENDIAN
+ if (low_byte_first_from)
+ val = sint2korr(from);
+ else
+#endif
+ shortget(val, from);
+
+#ifdef WORDS_BIGENDIAN
+ if (low_byte_first_to)
+ int2store(to, val);
+ else
+#endif
+ shortstore(to, val);
+ }
+
+ static void handle_int24(uchar *to, const uchar *from,
+ bool low_byte_first_from, bool low_byte_first_to)
+ {
+ int32 val;
+#ifdef WORDS_BIGENDIAN
+ if (low_byte_first_from)
+ val = sint3korr(from);
+ else
+#endif
+ val= (from[0] << 16) + (from[1] << 8) + from[2];
+
+#ifdef WORDS_BIGENDIAN
+ if (low_byte_first_to)
+ int2store(to, val);
+ else
+#endif
+ {
+ to[0]= 0xFF & (val >> 16);
+ to[1]= 0xFF & (val >> 8);
+ to[2]= 0xFF & val;
+ }
+ }
+
/*
Helper function to pack()/unpack() int32 values
*/
@@ -598,6 +640,32 @@ protected:
longlongstore(to, val);
}
+ uchar *pack_int16(uchar *to, const uchar *from, bool low_byte_first_to)
+ {
+ handle_int16(to, from, table->s->db_low_byte_first, low_byte_first_to);
+ return to + sizeof(int16);
+ }
+
+ const uchar *unpack_int16(uchar* to, const uchar *from,
+ bool low_byte_first_from)
+ {
+ handle_int16(to, from, low_byte_first_from, table->s->db_low_byte_first);
+ return from + sizeof(int16);
+ }
+
+ uchar *pack_int24(uchar *to, const uchar *from, bool low_byte_first_to)
+ {
+ handle_int24(to, from, table->s->db_low_byte_first, low_byte_first_to);
+ return to + 3;
+ }
+
+ const uchar *unpack_int24(uchar* to, const uchar *from,
+ bool low_byte_first_from)
+ {
+ handle_int24(to, from, low_byte_first_from, table->s->db_low_byte_first);
+ return from + 3;
+ }
+
uchar *pack_int32(uchar *to, const uchar *from, bool low_byte_first_to)
{
handle_int32(to, from, table->s->db_low_byte_first, low_byte_first_to);
@@ -918,41 +986,13 @@ public:
virtual uchar *pack(uchar* to, const uchar *from,
uint max_length, bool low_byte_first)
{
- int16 val;
-#ifdef WORDS_BIGENDIAN
- if (table->s->db_low_byte_first)
- val = sint2korr(from);
- else
-#endif
- shortget(val, from);
-
-#ifdef WORDS_BIGENDIAN
- if (low_byte_first)
- int2store(to, val);
- else
-#endif
- shortstore(to, val);
- return to + sizeof(val);
+ return pack_int16(to, from, low_byte_first);
}
virtual const uchar *unpack(uchar* to, const uchar *from,
uint param_data, bool low_byte_first)
{
- int16 val;
-#ifdef WORDS_BIGENDIAN
- if (low_byte_first)
- val = sint2korr(from);
- else
-#endif
- shortget(val, from);
-
-#ifdef WORDS_BIGENDIAN
- if (table->s->db_low_byte_first)
- int2store(to, val);
- else
-#endif
- shortstore(to, val);
- return from + sizeof(val);
+ return unpack_int16(to, from, low_byte_first);
}
};
@@ -1895,6 +1935,12 @@ public:
bool has_charset(void) const { return TRUE; }
/* enum and set are sorted as integers */
CHARSET_INFO *sort_charset(void) const { return &my_charset_bin; }
+
+ virtual uchar *pack(uchar *to, const uchar *from,
+ uint max_length, bool low_byte_first);
+ virtual const uchar *unpack(uchar *to, const uchar *from,
+ uint param_data, bool low_byte_first);
+
private:
int do_save_field_metadata(uchar *first_byte);
uint is_equal(Create_field *new_field);