Commit c423ecc0 authored by unknown's avatar unknown

Bug#22645 LC_TIME_NAMES: Statement not replicated

Implementing event based replication of LC_TIME_NAMES for 5.0
(as a replacement of previously made ONE_SHOT replication)


mysql-test/r/mysqlbinlog.result:
  Fixing results
mysql-test/r/rpl_locale.result:
  Fixing results
mysql-test/t/disabled.def:
  Enabling rpl_locale
mysql-test/t/mysqlbinlog.test:
  Check "mysqlbinlog | mysql" reproduces lc_time_names correctly.
mysql-test/t/rpl_locale.test:
  Adding new test: that setting lc_time_names back to en_US works fine.
sql/log_event.cc:
  Implementing event based replication of LC_TIME_NAMES for 5.0
  (as a replacement of previously made ONE_SHOT replication)
sql/log_event.h:
  Adding new Q_*_CODE
  Adding "lc_time_names_number" members into Query_log_event and PRINT_EVENT_INFO
parent 21b9187a
...@@ -194,4 +194,24 @@ select * from t5 /* must be (1),(1) */; ...@@ -194,4 +194,24 @@ select * from t5 /* must be (1),(1) */;
a a
1 1
1 1
flush logs;
drop table if exists t5;
create table t5 (c1 int, c2 varchar(128) character set latin1 not null);
insert into t5 values (1, date_format('2001-01-01','%W'));
set lc_time_names=de_DE;
insert into t5 values (2, date_format('2001-01-01','%W'));
set lc_time_names=en_US;
insert into t5 values (3, date_format('2001-01-01','%W'));
select * from t5 order by c1;
c1 c2
1 Monday
2 Montag
3 Monday
flush logs;
drop table t5;
select * from t5 order by c1;
c1 c2
1 Monday
2 Montag
3 Monday
drop table t1, t2, t03, t04, t3, t4, t5; drop table t1, t2, t03, t04, t3, t4, t5;
...@@ -7,10 +7,14 @@ start slave; ...@@ -7,10 +7,14 @@ start slave;
create table t1 (s1 char(10)); create table t1 (s1 char(10));
set lc_time_names= 'de_DE'; set lc_time_names= 'de_DE';
insert into t1 values (date_format('2001-01-01','%W')); insert into t1 values (date_format('2001-01-01','%W'));
set lc_time_names= 'en_US';
insert into t1 values (date_format('2001-01-01','%W'));
select * from t1; select * from t1;
s1 s1
Montag Montag
Monday
select * from t1; select * from t1;
s1 s1
Montag Montag
Monday
drop table t1; drop table t1;
...@@ -11,6 +11,5 @@ ...@@ -11,6 +11,5 @@
############################################################################## ##############################################################################
ndb_load : Bug#17233 ndb_load : Bug#17233
rpl_locale : Bug#22645
user_limits : Bug#23921 random failure of user_limits.test user_limits : Bug#23921 random failure of user_limits.test
...@@ -134,6 +134,25 @@ flush logs; ...@@ -134,6 +134,25 @@ flush logs;
--exec $MYSQL_BINLOG --short-form $MYSQLTEST_VARDIR/log/master-bin.000006 | $MYSQL --exec $MYSQL_BINLOG --short-form $MYSQLTEST_VARDIR/log/master-bin.000006 | $MYSQL
select * from t5 /* must be (1),(1) */; select * from t5 /* must be (1),(1) */;
#
# Bug#22645 LC_TIME_NAMES: Statement not replicated
# Check that a dump created by mysqlbinlog reproduces
# lc_time_names dependent values correctly
#
flush logs;
drop table if exists t5;
create table t5 (c1 int, c2 varchar(128) character set latin1 not null);
insert into t5 values (1, date_format('2001-01-01','%W'));
set lc_time_names=de_DE;
insert into t5 values (2, date_format('2001-01-01','%W'));
set lc_time_names=en_US;
insert into t5 values (3, date_format('2001-01-01','%W'));
select * from t5 order by c1;
flush logs;
drop table t5;
--exec $MYSQL_BINLOG --short-form $MYSQLTEST_VARDIR/log/master-bin.000007 | $MYSQL
select * from t5 order by c1;
# clean up # clean up
drop table t1, t2, t03, t04, t3, t4, t5; drop table t1, t2, t03, t04, t3, t4, t5;
......
...@@ -9,6 +9,8 @@ connection master; ...@@ -9,6 +9,8 @@ connection master;
create table t1 (s1 char(10)); create table t1 (s1 char(10));
set lc_time_names= 'de_DE'; set lc_time_names= 'de_DE';
insert into t1 values (date_format('2001-01-01','%W')); insert into t1 values (date_format('2001-01-01','%W'));
set lc_time_names= 'en_US';
insert into t1 values (date_format('2001-01-01','%W'));
select * from t1; select * from t1;
sync_slave_with_master; sync_slave_with_master;
connection slave; connection slave;
......
...@@ -1088,7 +1088,8 @@ bool Query_log_event::write(IO_CACHE* file) ...@@ -1088,7 +1088,8 @@ bool Query_log_event::write(IO_CACHE* file)
1+1+FN_REFLEN+ // code of catalog and catalog length and catalog 1+1+FN_REFLEN+ // code of catalog and catalog length and catalog
1+4+ // code of autoinc and the 2 autoinc variables 1+4+ // code of autoinc and the 2 autoinc variables
1+6+ // code of charset and charset 1+6+ // code of charset and charset
1+1+MAX_TIME_ZONE_NAME_LENGTH // code of tz and tz length and tz name 1+1+MAX_TIME_ZONE_NAME_LENGTH+ // code of tz and tz length and tz name
1+2 // code of lc_time_names and lc_time_names
], *start, *start_of_status; ], *start, *start_of_status;
ulong event_length; ulong event_length;
...@@ -1200,6 +1201,13 @@ bool Query_log_event::write(IO_CACHE* file) ...@@ -1200,6 +1201,13 @@ bool Query_log_event::write(IO_CACHE* file)
memcpy(start, time_zone_str, time_zone_len); memcpy(start, time_zone_str, time_zone_len);
start+= time_zone_len; start+= time_zone_len;
} }
if (lc_time_names_number)
{
DBUG_ASSERT(lc_time_names_number <= 0xFFFF);
*start++= Q_LC_TIME_NAMES_CODE;
int2store(start, lc_time_names_number);
start+= 2;
}
/* /*
Here there could be code like Here there could be code like
if (command-line-option-which-says-"log_this_variable" && inited) if (command-line-option-which-says-"log_this_variable" && inited)
...@@ -1264,7 +1272,8 @@ Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg, ...@@ -1264,7 +1272,8 @@ Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg,
flags2_inited(1), sql_mode_inited(1), charset_inited(1), flags2_inited(1), sql_mode_inited(1), charset_inited(1),
sql_mode(thd_arg->variables.sql_mode), sql_mode(thd_arg->variables.sql_mode),
auto_increment_increment(thd_arg->variables.auto_increment_increment), auto_increment_increment(thd_arg->variables.auto_increment_increment),
auto_increment_offset(thd_arg->variables.auto_increment_offset) auto_increment_offset(thd_arg->variables.auto_increment_offset),
lc_time_names_number(thd_arg->variables.lc_time_names->number)
{ {
time_t end_time; time_t end_time;
time(&end_time); time(&end_time);
...@@ -1334,7 +1343,7 @@ Query_log_event::Query_log_event(const char* buf, uint event_len, ...@@ -1334,7 +1343,7 @@ Query_log_event::Query_log_event(const char* buf, uint event_len,
db(NullS), catalog_len(0), status_vars_len(0), db(NullS), catalog_len(0), status_vars_len(0),
flags2_inited(0), sql_mode_inited(0), charset_inited(0), flags2_inited(0), sql_mode_inited(0), charset_inited(0),
auto_increment_increment(1), auto_increment_offset(1), auto_increment_increment(1), auto_increment_offset(1),
time_zone_len(0) time_zone_len(0), lc_time_names_number(0)
{ {
ulong data_len; ulong data_len;
uint32 tmp; uint32 tmp;
...@@ -1435,6 +1444,10 @@ Query_log_event::Query_log_event(const char* buf, uint event_len, ...@@ -1435,6 +1444,10 @@ Query_log_event::Query_log_event(const char* buf, uint event_len,
pos+= catalog_len+2; // leap over end 0 pos+= catalog_len+2; // leap over end 0
catalog_nz= 0; // catalog has end 0 in event catalog_nz= 0; // catalog has end 0 in event
break; break;
case Q_LC_TIME_NAMES_CODE:
lc_time_names_number= uint2korr(pos);
pos+= 2;
break;
default: default:
/* That's why you must write status vars in growing order of code */ /* That's why you must write status vars in growing order of code */
DBUG_PRINT("info",("Query_log_event has unknown status vars (first has\ DBUG_PRINT("info",("Query_log_event has unknown status vars (first has\
...@@ -1619,6 +1632,11 @@ void Query_log_event::print_query_header(FILE* file, ...@@ -1619,6 +1632,11 @@ void Query_log_event::print_query_header(FILE* file,
memcpy(print_event_info->time_zone_str, time_zone_str, time_zone_len+1); memcpy(print_event_info->time_zone_str, time_zone_str, time_zone_len+1);
} }
} }
if (lc_time_names_number != print_event_info->lc_time_names_number)
{
fprintf(file, "SET @@session.lc_time_names=%d;\n", lc_time_names_number);
print_event_info->lc_time_names_number= lc_time_names_number;
}
} }
...@@ -1771,6 +1789,19 @@ int Query_log_event::exec_event(struct st_relay_log_info* rli, ...@@ -1771,6 +1789,19 @@ int Query_log_event::exec_event(struct st_relay_log_info* rli,
goto compare_errors; goto compare_errors;
} }
} }
if (lc_time_names_number)
{
if (!(thd->variables.lc_time_names=
my_locale_by_number(lc_time_names_number)))
{
my_printf_error(ER_UNKNOWN_ERROR,
"Unknown locale: '%d'", MYF(0), lc_time_names_number);
thd->variables.lc_time_names= &my_locale_en_US;
goto compare_errors;
}
}
else
thd->variables.lc_time_names= &my_locale_en_US;
/* Execute the query (note that we bypass dispatch_command()) */ /* Execute the query (note that we bypass dispatch_command()) */
mysql_parse(thd, thd->query, thd->query_length); mysql_parse(thd, thd->query, thd->query_length);
......
...@@ -271,6 +271,8 @@ struct sql_ex_info ...@@ -271,6 +271,8 @@ struct sql_ex_info
*/ */
#define Q_CATALOG_NZ_CODE 6 #define Q_CATALOG_NZ_CODE 6
#define Q_LC_TIME_NAMES_CODE 7
/* Intvar event post-header */ /* Intvar event post-header */
#define I_TYPE_OFFSET 0 #define I_TYPE_OFFSET 0
...@@ -507,9 +509,11 @@ typedef struct st_print_event_info ...@@ -507,9 +509,11 @@ typedef struct st_print_event_info
bool charset_inited; bool charset_inited;
char charset[6]; // 3 variables, each of them storable in 2 bytes char charset[6]; // 3 variables, each of them storable in 2 bytes
char time_zone_str[MAX_TIME_ZONE_NAME_LENGTH]; char time_zone_str[MAX_TIME_ZONE_NAME_LENGTH];
uint lc_time_names_number;
st_print_event_info() st_print_event_info()
:flags2_inited(0), sql_mode_inited(0), :flags2_inited(0), sql_mode_inited(0),
auto_increment_increment(1),auto_increment_offset(1), charset_inited(0) auto_increment_increment(1),auto_increment_offset(1), charset_inited(0),
lc_time_names_number(0)
{ {
/* /*
Currently we only use static PRINT_EVENT_INFO objects, so zeroed at Currently we only use static PRINT_EVENT_INFO objects, so zeroed at
...@@ -784,6 +788,7 @@ public: ...@@ -784,6 +788,7 @@ public:
char charset[6]; char charset[6];
uint time_zone_len; /* 0 means uninited */ uint time_zone_len; /* 0 means uninited */
const char *time_zone_str; const char *time_zone_str;
uint lc_time_names_number; /* 0 means en_US */
#ifndef MYSQL_CLIENT #ifndef MYSQL_CLIENT
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment