Commit 954fba47 authored by Gleb Shchepa's avatar Gleb Shchepa
Browse files

Fixed bug #37076: TIMESTAMP/DATETIME/DATE values are not

                  replicated correctly between machines with
                  mixed endiannes
parent 41659299
Loading
Loading
Loading
Loading
+16 −0
Original line number Diff line number Diff line
@@ -265,6 +265,22 @@ eval SELECT "$last_error" AS Last_SQL_Error;
enable_query_log;
query_vertical SELECT COUNT(*) FROM t1 ORDER BY c1,c2;

# BUG#37076: TIMESTAMP/DATETIME values are not replicated correctly
#            between machines with mixed endiannes
#            (regression test)

--echo **** Test for BUG#37076 ****
--echo **** On Master ****
connection master;
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (a TIMESTAMP, b DATETIME, c DATE);
INSERT INTO t1 VALUES(
  '2005-11-14 01:01:01', '2005-11-14 01:01:02', '2005-11-14');

--echo **** On Slave ****
sync_slave_with_master slave;
SELECT * FROM t1;

#
# cleanup
#
+10 −0
Original line number Diff line number Diff line
@@ -440,4 +440,14 @@ Last_SQL_Error
0
SELECT COUNT(*) FROM t1 ORDER BY c1,c2;
COUNT(*)	0
**** Test for BUG#37076 ****
**** On Master ****
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (a TIMESTAMP, b DATETIME, c DATE);
INSERT INTO t1 VALUES(
'2005-11-14 01:01:01', '2005-11-14 01:01:02', '2005-11-14');
**** On Slave ****
SELECT * FROM t1;
a	b	c
2005-11-14 01:01:01	2005-11-14 01:01:02	2005-11-14
DROP TABLE IF EXISTS t1,t2,t3,t4,t5,t6,t7,t8;
+10 −0
Original line number Diff line number Diff line
@@ -440,4 +440,14 @@ Last_SQL_Error
0
SELECT COUNT(*) FROM t1 ORDER BY c1,c2;
COUNT(*)	0
**** Test for BUG#37076 ****
**** On Master ****
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (a TIMESTAMP, b DATETIME, c DATE);
INSERT INTO t1 VALUES(
'2005-11-14 01:01:01', '2005-11-14 01:01:02', '2005-11-14');
**** On Slave ****
SELECT * FROM t1;
a	b	c
2005-11-14 01:01:01	2005-11-14 01:01:02	2005-11-14
DROP TABLE IF EXISTS t1,t2,t3,t4,t5,t6,t7,t8;
+10 −0
Original line number Diff line number Diff line
@@ -440,4 +440,14 @@ Last_SQL_Error
0
SELECT COUNT(*) FROM t1 ORDER BY c1,c2;
COUNT(*)	0
**** Test for BUG#37076 ****
**** On Master ****
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (a TIMESTAMP, b DATETIME, c DATE);
INSERT INTO t1 VALUES(
'2005-11-14 01:01:01', '2005-11-14 01:01:02', '2005-11-14');
**** On Slave ****
SELECT * FROM t1;
a	b	c
2005-11-14 01:01:01	2005-11-14 01:01:02	2005-11-14
DROP TABLE IF EXISTS t1,t2,t3,t4,t5,t6,t7,t8;
+116 −66
Original line number Diff line number Diff line
@@ -529,6 +529,77 @@ class Field
*/
  virtual int do_save_field_metadata(uchar *metadata_ptr)
  { return 0; }

protected:
  /*
    Helper function to pack()/unpack() int32 values
  */
  static void handle_int32(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 = sint4korr(from);
    else
#endif
      longget(val, from);

#ifdef WORDS_BIGENDIAN
    if (low_byte_first_to)
      int4store(to, val);
    else
#endif
      longstore(to, val);
  }

  /*
    Helper function to pack()/unpack() int64 values
  */
  static void handle_int64(uchar* to, const uchar *from,
                           bool low_byte_first_from, bool low_byte_first_to)
  {
    int64 val;
#ifdef WORDS_BIGENDIAN
    if (low_byte_first_from)
      val = sint8korr(from);
    else
#endif
      longlongget(val, from);

#ifdef WORDS_BIGENDIAN
    if (low_byte_first_to)
      int8store(to, val);
    else
#endif
      longlongstore(to, val);
  }

  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);
    return to  + sizeof(int32);
  }

  const uchar *unpack_int32(uchar* to, const uchar *from,
                            bool low_byte_first_from)
  {
    handle_int32(to, from, low_byte_first_from, table->s->db_low_byte_first);
    return from + sizeof(int32);
  }

  uchar *pack_int64(uchar* to, const uchar *from, bool low_byte_first_to)
  {
    handle_int64(to, from, table->s->db_low_byte_first, low_byte_first_to);
    return to + sizeof(int64);
  }

  const uchar *unpack_int64(uchar* to, const uchar *from,
                            bool low_byte_first_from)
  {
    handle_int64(to, from, low_byte_first_from, table->s->db_low_byte_first);
    return from + sizeof(int64);
  }
};


@@ -916,43 +987,16 @@ class Field_long :public Field_num {
  void sql_type(String &str) const;
  uint32 max_display_length() { return MY_INT32_NUM_DECIMAL_DIGITS; }
  virtual uchar *pack(uchar* to, const uchar *from,
                      uint max_length, bool low_byte_first)
                      uint max_length __attribute__((unused)),
                      bool low_byte_first)
  {
    int32 val;
#ifdef WORDS_BIGENDIAN
    if (table->s->db_low_byte_first)
      val = sint4korr(from);
    else
#endif
      longget(val, from);

#ifdef WORDS_BIGENDIAN
    if (low_byte_first)
      int4store(to, val);
    else
#endif
      longstore(to, val);
    return to + sizeof(val);
    return pack_int32(to, from, low_byte_first);
  }

  virtual const uchar *unpack(uchar* to, const uchar *from,
                              uint param_data, bool low_byte_first)
                              uint param_data __attribute__((unused)),
                              bool low_byte_first)
  {
    int32 val;
#ifdef WORDS_BIGENDIAN
    if (low_byte_first)
      val = sint4korr(from);
    else
#endif
      longget(val, from);

#ifdef WORDS_BIGENDIAN
    if (table->s->db_low_byte_first)
      int4store(to, val);
    else
#endif
      longstore(to, val);
    return from + sizeof(val);
    return unpack_int32(to, from, low_byte_first);
  }
};

@@ -997,43 +1041,16 @@ class Field_longlong :public Field_num {
  bool can_be_compared_as_longlong() const { return TRUE; }
  uint32 max_display_length() { return 20; }
  virtual uchar *pack(uchar* to, const uchar *from,
                      uint max_length, bool low_byte_first)
                      uint max_length  __attribute__((unused)),
                      bool low_byte_first)
  {
    int64 val;
#ifdef WORDS_BIGENDIAN
    if (table->s->db_low_byte_first)
      val = sint8korr(from);
    else
#endif
      longlongget(val, from);

#ifdef WORDS_BIGENDIAN
    if (low_byte_first)
      int8store(to, val);
    else
#endif
      longlongstore(to, val);
    return to + sizeof(val);
    return pack_int64(to, from, low_byte_first);
  }

  virtual const uchar *unpack(uchar* to, const uchar *from,
                              uint param_data, bool low_byte_first)
                              uint param_data __attribute__((unused)),
                              bool low_byte_first)
  {
    int64 val;
#ifdef WORDS_BIGENDIAN
    if (low_byte_first)
      val = sint8korr(from);
    else
#endif
      longlongget(val, from);

#ifdef WORDS_BIGENDIAN
    if (table->s->db_low_byte_first)
      int8store(to, val);
    else
#endif
      longlongstore(to, val);
    return from + sizeof(val);
    return unpack_int64(to, from, low_byte_first);
  }
};
#endif
@@ -1207,6 +1224,17 @@ class Field_timestamp :public Field_str {
  bool get_date(MYSQL_TIME *ltime,uint fuzzydate);
  bool get_time(MYSQL_TIME *ltime);
  timestamp_auto_set_type get_auto_set_type() const;
  uchar *pack(uchar *to, const uchar *from,
              uint max_length __attribute__((unused)), bool low_byte_first)
  {
    return pack_int32(to, from, low_byte_first);
  }
  const uchar *unpack(uchar* to, const uchar *from,
                      uint param_data __attribute__((unused)),
                      bool low_byte_first)
  {
    return unpack_int32(to, from, low_byte_first);
  }
};


@@ -1261,6 +1289,17 @@ class Field_date :public Field_str {
  void sql_type(String &str) const;
  bool can_be_compared_as_longlong() const { return TRUE; }
  bool zero_pack() const { return 1; }
  uchar *pack(uchar* to, const uchar *from,
              uint max_length __attribute__((unused)), bool low_byte_first)
  {
    return pack_int32(to, from, low_byte_first);
  }
  const uchar *unpack(uchar* to, const uchar *from,
                      uint param_data __attribute__((unused)),
                      bool low_byte_first)
  {
    return unpack_int32(to, from, low_byte_first);
  }
};


@@ -1374,6 +1413,17 @@ class Field_datetime :public Field_str {
  bool zero_pack() const { return 1; }
  bool get_date(MYSQL_TIME *ltime,uint fuzzydate);
  bool get_time(MYSQL_TIME *ltime);
  uchar *pack(uchar* to, const uchar *from,
              uint max_length __attribute__((unused)), bool low_byte_first)
  {
    return pack_int64(to, from, low_byte_first);
  }
  const uchar *unpack(uchar* to, const uchar *from,
                      uint param_data __attribute__((unused)),
                      bool low_byte_first)
  {
    return unpack_int64(to, from, low_byte_first);
  }
};