Bug#22645 LC_TIME_NAMES: Statement not replicated
Problem: replication of LC_TIME_NAMES didn't work. Thus, INSERTS or UPDATES using date_format() always worked with en_US on the slave side. Fix: adding ONE_SHOT implementation for LC_TIME_NAMES.
This commit is contained in:
parent
fb419c4241
commit
224660d14a
16
mysql-test/r/rpl_locale.result
Normal file
16
mysql-test/r/rpl_locale.result
Normal file
@ -0,0 +1,16 @@
|
||||
stop slave;
|
||||
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
|
||||
reset master;
|
||||
reset slave;
|
||||
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
|
||||
start slave;
|
||||
create table t1 (s1 char(10));
|
||||
set lc_time_names= 'de_DE';
|
||||
insert into t1 values (date_format('2001-01-01','%W'));
|
||||
select * from t1;
|
||||
s1
|
||||
Montag
|
||||
select * from t1;
|
||||
s1
|
||||
Montag
|
||||
drop table t1;
|
@ -499,6 +499,63 @@ set names latin1;
|
||||
select @@have_innodb;
|
||||
@@have_innodb
|
||||
#
|
||||
*** Various tests with LC_TIME_NAMES
|
||||
*** LC_TIME_NAMES: testing case insensitivity
|
||||
set @@lc_time_names='ru_ru';
|
||||
select @@lc_time_names;
|
||||
@@lc_time_names
|
||||
ru_RU
|
||||
*** LC_TIME_NAMES: testing with a user variable
|
||||
set @lc='JA_JP';
|
||||
set @@lc_time_names=@lc;
|
||||
select @@lc_time_names;
|
||||
@@lc_time_names
|
||||
ja_JP
|
||||
*** LC_TIME_NAMES: testing with string expressions
|
||||
set lc_time_names=concat('de','_','DE');
|
||||
select @@lc_time_names;
|
||||
@@lc_time_names
|
||||
de_DE
|
||||
set lc_time_names=concat('de','+','DE');
|
||||
ERROR HY000: Unknown locale: 'de+DE'
|
||||
select @@lc_time_names;
|
||||
@@lc_time_names
|
||||
de_DE
|
||||
LC_TIME_NAMES: testing with numeric expressions
|
||||
set @@lc_time_names=1+2;
|
||||
select @@lc_time_names;
|
||||
@@lc_time_names
|
||||
sv_SE
|
||||
set @@lc_time_names=1/0;
|
||||
ERROR 42000: Incorrect argument type to variable 'lc_time_names'
|
||||
select @@lc_time_names;
|
||||
@@lc_time_names
|
||||
sv_SE
|
||||
set lc_time_names=en_US;
|
||||
LC_TIME_NAMES: testing NULL and a negative number:
|
||||
set lc_time_names=NULL;
|
||||
ERROR 42000: Variable 'lc_time_names' can't be set to the value of 'NULL'
|
||||
set lc_time_names=-1;
|
||||
ERROR HY000: Unknown locale: '-1'
|
||||
select @@lc_time_names;
|
||||
@@lc_time_names
|
||||
en_US
|
||||
LC_TIME_NAMES: testing locale with the last ID:
|
||||
set lc_time_names=108;
|
||||
select @@lc_time_names;
|
||||
@@lc_time_names
|
||||
zh_HK
|
||||
LC_TIME_NAMES: testing a number beyond the valid ID range:
|
||||
set lc_time_names=109;
|
||||
ERROR HY000: Unknown locale: '109'
|
||||
select @@lc_time_names;
|
||||
@@lc_time_names
|
||||
zh_HK
|
||||
LC_TIME_NAMES: testing that 0 is en_US:
|
||||
set lc_time_names=0;
|
||||
select @@lc_time_names;
|
||||
@@lc_time_names
|
||||
en_US
|
||||
set @test = @@query_prealloc_size;
|
||||
set @@query_prealloc_size = @test;
|
||||
select @@query_prealloc_size = @test;
|
||||
|
22
mysql-test/t/rpl_locale.test
Normal file
22
mysql-test/t/rpl_locale.test
Normal file
@ -0,0 +1,22 @@
|
||||
# Replication of locale variables
|
||||
|
||||
source include/master-slave.inc;
|
||||
|
||||
#
|
||||
# Bug#22645 LC_TIME_NAMES: Statement not replicated
|
||||
#
|
||||
connection master;
|
||||
create table t1 (s1 char(10));
|
||||
set lc_time_names= 'de_DE';
|
||||
insert into t1 values (date_format('2001-01-01','%W'));
|
||||
select * from t1;
|
||||
sync_slave_with_master;
|
||||
connection slave;
|
||||
select * from t1;
|
||||
connection master;
|
||||
drop table t1;
|
||||
sync_slave_with_master;
|
||||
|
||||
# End of 4.1 tests
|
||||
|
||||
|
@ -396,6 +396,50 @@ set names latin1;
|
||||
--replace_column 1 #
|
||||
select @@have_innodb;
|
||||
|
||||
#
|
||||
# Tests for lc_time_names
|
||||
# Note, when adding new locales, please fix ID accordingly:
|
||||
# - to test the last ID (currently 108)
|
||||
# - and the next after the last (currently 109)
|
||||
#
|
||||
--echo *** Various tests with LC_TIME_NAMES
|
||||
--echo *** LC_TIME_NAMES: testing case insensitivity
|
||||
set @@lc_time_names='ru_ru';
|
||||
select @@lc_time_names;
|
||||
--echo *** LC_TIME_NAMES: testing with a user variable
|
||||
set @lc='JA_JP';
|
||||
set @@lc_time_names=@lc;
|
||||
select @@lc_time_names;
|
||||
--echo *** LC_TIME_NAMES: testing with string expressions
|
||||
set lc_time_names=concat('de','_','DE');
|
||||
select @@lc_time_names;
|
||||
--error 1105
|
||||
set lc_time_names=concat('de','+','DE');
|
||||
select @@lc_time_names;
|
||||
--echo LC_TIME_NAMES: testing with numeric expressions
|
||||
set @@lc_time_names=1+2;
|
||||
select @@lc_time_names;
|
||||
--error 1232
|
||||
set @@lc_time_names=1/0;
|
||||
select @@lc_time_names;
|
||||
set lc_time_names=en_US;
|
||||
--echo LC_TIME_NAMES: testing NULL and a negative number:
|
||||
--error 1231
|
||||
set lc_time_names=NULL;
|
||||
--error 1105
|
||||
set lc_time_names=-1;
|
||||
select @@lc_time_names;
|
||||
--echo LC_TIME_NAMES: testing locale with the last ID:
|
||||
set lc_time_names=108;
|
||||
select @@lc_time_names;
|
||||
--echo LC_TIME_NAMES: testing a number beyond the valid ID range:
|
||||
--error 1105
|
||||
set lc_time_names=109;
|
||||
select @@lc_time_names;
|
||||
--echo LC_TIME_NAMES: testing that 0 is en_US:
|
||||
set lc_time_names=0;
|
||||
select @@lc_time_names;
|
||||
|
||||
#
|
||||
# Bug #13334: query_prealloc_size default less than minimum
|
||||
#
|
||||
|
15
sql/log.cc
15
sql/log.cc
@ -1350,6 +1350,21 @@ COLLATION_CONNECTION=%u,COLLATION_DATABASE=%u,COLLATION_SERVER=%u",
|
||||
if (e.write(file))
|
||||
goto err;
|
||||
}
|
||||
/*
|
||||
Use the same ONE_SHOT trick for making replication of lc_time_names.
|
||||
*/
|
||||
if (thd->variables.lc_time_names->number) // Not en_US
|
||||
{
|
||||
char buf[32];
|
||||
uint length= my_snprintf(buf, sizeof(buf),
|
||||
"SET ONE_SHOT LC_TIME_NAMES=%u",
|
||||
(uint) thd->variables.lc_time_names->number);
|
||||
Query_log_event e(thd, buf, length, 0, FALSE);
|
||||
e.set_log_pos(this);
|
||||
e.error_code= 0; // This statement cannot fail (see [1]).
|
||||
if (e.write(file))
|
||||
goto err;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (thd->last_insert_id_used)
|
||||
|
@ -71,6 +71,7 @@ extern CHARSET_INFO *national_charset_info, *table_alias_charset;
|
||||
|
||||
typedef struct my_locale_st
|
||||
{
|
||||
uint number;
|
||||
const char *name;
|
||||
const char *description;
|
||||
const bool is_ascii;
|
||||
@ -84,6 +85,7 @@ extern MY_LOCALE my_locale_en_US;
|
||||
extern MY_LOCALE *my_locales[];
|
||||
|
||||
MY_LOCALE *my_locale_by_name(const char *name);
|
||||
MY_LOCALE *my_locale_by_number(uint number);
|
||||
|
||||
/***************************************************************************
|
||||
Configuration parameters
|
||||
|
@ -2576,19 +2576,38 @@ void sys_var_thd_time_zone::set_default(THD *thd, enum_var_type type)
|
||||
|
||||
bool sys_var_thd_lc_time_names::check(THD *thd, set_var *var)
|
||||
{
|
||||
char *locale_str =var->value->str_value.c_ptr();
|
||||
MY_LOCALE *locale_match= my_locale_by_name(locale_str);
|
||||
MY_LOCALE *locale_match;
|
||||
|
||||
if(locale_match == NULL)
|
||||
if (var->value->result_type() == INT_RESULT)
|
||||
{
|
||||
my_printf_error(ER_UNKNOWN_ERROR, "Unknown locale: '%s'", MYF(0), locale_str);
|
||||
return 1;
|
||||
if (!(locale_match= my_locale_by_number((uint) var->value->val_int())))
|
||||
{
|
||||
char buf[20];
|
||||
int10_to_str((int) var->value->val_int(), buf, -10);
|
||||
my_printf_error(ER_UNKNOWN_ERROR, "Unknown locale: '%s'", MYF(0), buf);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
else // STRING_RESULT
|
||||
{
|
||||
var->save_result.locale_value= locale_match;
|
||||
return 0;
|
||||
char buff[6];
|
||||
String str(buff, sizeof(buff), &my_charset_latin1), *res;
|
||||
if (!(res=var->value->val_str(&str)))
|
||||
{
|
||||
my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, "NULL");
|
||||
return 1;
|
||||
}
|
||||
const char *locale_str= res->c_ptr();
|
||||
if (!(locale_match= my_locale_by_name(locale_str)))
|
||||
{
|
||||
my_printf_error(ER_UNKNOWN_ERROR,
|
||||
"Unknown locale: '%s'", MYF(0), locale_str);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
var->save_result.locale_value= locale_match;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -764,12 +764,16 @@ class sys_var_thd_lc_time_names :public sys_var_thd
|
||||
public:
|
||||
sys_var_thd_lc_time_names(const char *name_arg):
|
||||
sys_var_thd(name_arg)
|
||||
{}
|
||||
{
|
||||
#if MYSQL_VERSION_ID < 50000
|
||||
no_support_one_shot= 0;
|
||||
#endif
|
||||
}
|
||||
bool check(THD *thd, set_var *var);
|
||||
SHOW_TYPE type() { return SHOW_CHAR; }
|
||||
bool check_update_type(Item_result type)
|
||||
{
|
||||
return type != STRING_RESULT; /* Only accept strings */
|
||||
return ((type != STRING_RESULT) && (type != INT_RESULT));
|
||||
}
|
||||
bool check_default(enum_var_type type) { return 0; }
|
||||
bool update(THD *thd, set_var *var);
|
||||
|
1245
sql/sql_locale.cc
1245
sql/sql_locale.cc
File diff suppressed because it is too large
Load Diff
@ -1958,6 +1958,7 @@ static void reset_one_shot_variables(THD *thd)
|
||||
thd->update_charset();
|
||||
thd->variables.time_zone=
|
||||
global_system_variables.time_zone;
|
||||
thd->variables.lc_time_names= &my_locale_en_US;
|
||||
thd->one_shot_set= 0;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user