summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <gkodinov/kgeorge@magare.gmz>2007-08-06 04:57:28 -0700
committerunknown <gkodinov/kgeorge@magare.gmz>2007-08-06 04:57:28 -0700
commit1f83b351818fca51a14bc34a224c4a80e14c9476 (patch)
treef1023c618054e8ed26dac043765fd501153cde4d
parent71c3c0cfd57e1d37e4f04427388f8c473283540c (diff)
downloadmariadb-git-1f83b351818fca51a14bc34a224c4a80e14c9476.tar.gz
Bug #29536: timestamp inconsistent in replication around 1970
MySQL replicates the time zone only when operations that involve it are performed. This is controlled by a flag. But this flag is set only on successful operation. The flag must be set also when there is an error that involves a timezone (so the master would replicate the error to the slaves). Fixed by moving the setting of the flag before the operation (so it apples to errors as well). mysql-test/r/rpl_timezone.result: Bug #29536: test case mysql-test/t/rpl_timezone.test: Bug #29536: test case sql/field.cc: Bug #29536: move setting of the flag before the operation (so it apples to errors as well). sql/time.cc: Bug #29536: move setting of the flag before the operation (so it apples to errors as well).
-rw-r--r--mysql-test/r/rpl_timezone.result18
-rw-r--r--mysql-test/t/rpl_timezone.test29
-rw-r--r--sql/field.cc6
-rw-r--r--sql/time.cc2
4 files changed, 49 insertions, 6 deletions
diff --git a/mysql-test/r/rpl_timezone.result b/mysql-test/r/rpl_timezone.result
index 10dc8eb7e3c..7a18a26afd3 100644
--- a/mysql-test/r/rpl_timezone.result
+++ b/mysql-test/r/rpl_timezone.result
@@ -130,3 +130,21 @@ t
2005-01-01 08:00:00
drop table t1, t2;
set global time_zone= @my_time_zone;
+End of 4.1 tests
+CREATE TABLE t1 (a INT, b TIMESTAMP);
+INSERT INTO t1 VALUES (1, NOW());
+SET @@session.time_zone='Japan';
+UPDATE t1 SET b= '1970-01-01 08:59:59' WHERE a= 1;
+Warnings:
+Warning 1264 Out of range value adjusted for column 'b' at row 1
+SELECT * FROM t1 ORDER BY a;
+a b
+1 0000-00-00 00:00:00
+SET @@session.time_zone='Japan';
+SELECT * FROM t1 ORDER BY a;
+a b
+1 0000-00-00 00:00:00
+SET @@session.time_zone = default;
+DROP TABLE t1;
+SET @@session.time_zone = default;
+End of 5.0 tests
diff --git a/mysql-test/t/rpl_timezone.test b/mysql-test/t/rpl_timezone.test
index 6ed5b21ace0..28ca250340e 100644
--- a/mysql-test/t/rpl_timezone.test
+++ b/mysql-test/t/rpl_timezone.test
@@ -126,8 +126,33 @@ connection master;
drop table t1, t2;
sync_slave_with_master;
-# End of 4.1 tests
-
# Restore original timezone
connection master;
set global time_zone= @my_time_zone;
+
+--echo End of 4.1 tests
+
+#
+# Bug #29536: timestamp inconsistent in replication around 1970
+#
+connection master;
+
+CREATE TABLE t1 (a INT, b TIMESTAMP);
+INSERT INTO t1 VALUES (1, NOW());
+
+SET @@session.time_zone='Japan';
+UPDATE t1 SET b= '1970-01-01 08:59:59' WHERE a= 1;
+SELECT * FROM t1 ORDER BY a;
+
+sync_slave_with_master;
+SET @@session.time_zone='Japan';
+# must procdure the same result as the SELECT on the master
+SELECT * FROM t1 ORDER BY a;
+
+SET @@session.time_zone = default;
+connection master;
+DROP TABLE t1;
+SET @@session.time_zone = default;
+
+
+--echo End of 5.0 tests
diff --git a/sql/field.cc b/sql/field.cc
index 3f74210807b..8191d885a27 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -4462,6 +4462,7 @@ longlong Field_timestamp::val_int(void)
MYSQL_TIME time_tmp;
THD *thd= table ? table->in_use : current_thd;
+ thd->time_zone_used= 1;
#ifdef WORDS_BIGENDIAN
if (table && table->s->db_low_byte_first)
temp=uint4korr(ptr);
@@ -4473,7 +4474,6 @@ longlong Field_timestamp::val_int(void)
return(0); /* purecov: inspected */
thd->variables.time_zone->gmt_sec_to_TIME(&time_tmp, (my_time_t)temp);
- thd->time_zone_used= 1;
return time_tmp.year * LL(10000000000) + time_tmp.month * LL(100000000) +
time_tmp.day * 1000000L + time_tmp.hour * 10000L +
@@ -4492,6 +4492,7 @@ String *Field_timestamp::val_str(String *val_buffer, String *val_ptr)
to= (char*) val_buffer->ptr();
val_buffer->length(field_length);
+ thd->time_zone_used= 1;
#ifdef WORDS_BIGENDIAN
if (table && table->s->db_low_byte_first)
temp=uint4korr(ptr);
@@ -4507,7 +4508,6 @@ String *Field_timestamp::val_str(String *val_buffer, String *val_ptr)
val_buffer->set_charset(&my_charset_bin); // Safety
thd->variables.time_zone->gmt_sec_to_TIME(&time_tmp,(my_time_t)temp);
- thd->time_zone_used= 1;
temp= time_tmp.year % 100;
if (temp < YY_PART_YEAR - 1)
@@ -4557,6 +4557,7 @@ bool Field_timestamp::get_date(MYSQL_TIME *ltime, uint fuzzydate)
{
long temp;
THD *thd= table ? table->in_use : current_thd;
+ thd->time_zone_used= 1;
#ifdef WORDS_BIGENDIAN
if (table && table->s->db_low_byte_first)
temp=uint4korr(ptr);
@@ -4572,7 +4573,6 @@ bool Field_timestamp::get_date(MYSQL_TIME *ltime, uint fuzzydate)
else
{
thd->variables.time_zone->gmt_sec_to_TIME(ltime, (my_time_t)temp);
- thd->time_zone_used= 1;
}
return 0;
}
diff --git a/sql/time.cc b/sql/time.cc
index b4a8b047998..fb8a51fd0eb 100644
--- a/sql/time.cc
+++ b/sql/time.cc
@@ -228,11 +228,11 @@ my_time_t TIME_to_timestamp(THD *thd, const MYSQL_TIME *t, my_bool *in_dst_time_
my_time_t timestamp;
*in_dst_time_gap= 0;
+ thd->time_zone_used= 1;
timestamp= thd->variables.time_zone->TIME_to_gmt_sec(t, in_dst_time_gap);
if (timestamp)
{
- thd->time_zone_used= 1;
return timestamp;
}