Commit 429409eb authored by Sergey Glukhov's avatar Sergey Glukhov

5.0-bugteam->5.1-bugteam merge

parents adf8aaca 26e804d0
...@@ -472,6 +472,7 @@ my_bool my_propagate_complex(CHARSET_INFO *cs, const uchar *str, size_t len); ...@@ -472,6 +472,7 @@ my_bool my_propagate_complex(CHARSET_INFO *cs, const uchar *str, size_t len);
uint my_string_repertoire(CHARSET_INFO *cs, const char *str, ulong len); uint my_string_repertoire(CHARSET_INFO *cs, const char *str, ulong len);
my_bool my_charset_is_ascii_based(CHARSET_INFO *cs); my_bool my_charset_is_ascii_based(CHARSET_INFO *cs);
my_bool my_charset_is_8bit_pure_ascii(CHARSET_INFO *cs); my_bool my_charset_is_8bit_pure_ascii(CHARSET_INFO *cs);
uint my_charset_repertoire(CHARSET_INFO *cs);
#define _MY_U 01 /* Upper case */ #define _MY_U 01 /* Upper case */
......
...@@ -1157,4 +1157,57 @@ set names latin1; ...@@ -1157,4 +1157,57 @@ set names latin1;
select hex(char(0x41 using ucs2)); select hex(char(0x41 using ucs2));
hex(char(0x41 using ucs2)) hex(char(0x41 using ucs2))
0041 0041
SET character_set_connection=ucs2;
SELECT CHARSET(DAYNAME(19700101));
CHARSET(DAYNAME(19700101))
ucs2
SELECT CHARSET(MONTHNAME(19700101));
CHARSET(MONTHNAME(19700101))
ucs2
SELECT LOWER(DAYNAME(19700101));
LOWER(DAYNAME(19700101))
thursday
SELECT LOWER(MONTHNAME(19700101));
LOWER(MONTHNAME(19700101))
january
SELECT UPPER(DAYNAME(19700101));
UPPER(DAYNAME(19700101))
THURSDAY
SELECT UPPER(MONTHNAME(19700101));
UPPER(MONTHNAME(19700101))
JANUARY
SELECT HEX(MONTHNAME(19700101));
HEX(MONTHNAME(19700101))
004A0061006E0075006100720079
SELECT HEX(DAYNAME(19700101));
HEX(DAYNAME(19700101))
00540068007500720073006400610079
SET LC_TIME_NAMES=ru_RU;
SET NAMES utf8;
SET character_set_connection=ucs2;
SELECT CHARSET(DAYNAME(19700101));
CHARSET(DAYNAME(19700101))
ucs2
SELECT CHARSET(MONTHNAME(19700101));
CHARSET(MONTHNAME(19700101))
ucs2
SELECT LOWER(DAYNAME(19700101));
LOWER(DAYNAME(19700101))
четверг
SELECT LOWER(MONTHNAME(19700101));
LOWER(MONTHNAME(19700101))
января
SELECT UPPER(DAYNAME(19700101));
UPPER(DAYNAME(19700101))
ЧЕТВЕРГ
SELECT UPPER(MONTHNAME(19700101));
UPPER(MONTHNAME(19700101))
ЯНВАРЯ
SELECT HEX(MONTHNAME(19700101));
HEX(MONTHNAME(19700101))
042F043D043204300440044F
SELECT HEX(DAYNAME(19700101));
HEX(DAYNAME(19700101))
0427043504420432043504400433
SET character_set_connection=latin1;
End of 5.0 tests End of 5.0 tests
...@@ -592,6 +592,21 @@ unix_timestamp('1970-01-01 03:00:01') ...@@ -592,6 +592,21 @@ unix_timestamp('1970-01-01 03:00:01')
select unix_timestamp('2038-01-19 07:14:07'); select unix_timestamp('2038-01-19 07:14:07');
unix_timestamp('2038-01-19 07:14:07') unix_timestamp('2038-01-19 07:14:07')
0 0
SELECT CHARSET(DAYNAME(19700101));
CHARSET(DAYNAME(19700101))
latin1
SELECT CHARSET(MONTHNAME(19700101));
CHARSET(MONTHNAME(19700101))
latin1
SELECT LOWER(DAYNAME(19700101));
LOWER(DAYNAME(19700101))
thursday
SELECT LOWER(MONTHNAME(19700101));
LOWER(MONTHNAME(19700101))
january
SELECT COERCIBILITY(MONTHNAME('1970-01-01')),COERCIBILITY(DAYNAME('1970-01-01'));
COERCIBILITY(MONTHNAME('1970-01-01')) COERCIBILITY(DAYNAME('1970-01-01'))
4 4
CREATE TABLE t1 (datetime datetime, timestamp timestamp, date date, time time); CREATE TABLE t1 (datetime datetime, timestamp timestamp, date date, time time);
INSERT INTO t1 values ("2001-01-02 03:04:05", "2002-01-02 03:04:05", "2003-01-02", "06:07:08"); INSERT INTO t1 values ("2001-01-02 03:04:05", "2002-01-02 03:04:05", "2003-01-02", "06:07:08");
SELECT * from t1; SELECT * from t1;
......
...@@ -697,4 +697,29 @@ set names latin1; ...@@ -697,4 +697,29 @@ set names latin1;
# #
select hex(char(0x41 using ucs2)); select hex(char(0x41 using ucs2));
#
# Bug#37575: UCASE fails on monthname
#
SET character_set_connection=ucs2;
SELECT CHARSET(DAYNAME(19700101));
SELECT CHARSET(MONTHNAME(19700101));
SELECT LOWER(DAYNAME(19700101));
SELECT LOWER(MONTHNAME(19700101));
SELECT UPPER(DAYNAME(19700101));
SELECT UPPER(MONTHNAME(19700101));
SELECT HEX(MONTHNAME(19700101));
SELECT HEX(DAYNAME(19700101));
SET LC_TIME_NAMES=ru_RU;
SET NAMES utf8;
SET character_set_connection=ucs2;
SELECT CHARSET(DAYNAME(19700101));
SELECT CHARSET(MONTHNAME(19700101));
SELECT LOWER(DAYNAME(19700101));
SELECT LOWER(MONTHNAME(19700101));
SELECT UPPER(DAYNAME(19700101));
SELECT UPPER(MONTHNAME(19700101));
SELECT HEX(MONTHNAME(19700101));
SELECT HEX(DAYNAME(19700101));
SET character_set_connection=latin1;
--echo End of 5.0 tests --echo End of 5.0 tests
...@@ -304,6 +304,15 @@ select unix_timestamp('1970-01-01 03:00:01'); ...@@ -304,6 +304,15 @@ select unix_timestamp('1970-01-01 03:00:01');
# check bad date, close to the boundary (we cut them off in the very end) # check bad date, close to the boundary (we cut them off in the very end)
select unix_timestamp('2038-01-19 07:14:07'); select unix_timestamp('2038-01-19 07:14:07');
#
# Bug #28759: DAYNAME() and MONTHNAME() return binary string
#
SELECT CHARSET(DAYNAME(19700101));
SELECT CHARSET(MONTHNAME(19700101));
SELECT LOWER(DAYNAME(19700101));
SELECT LOWER(MONTHNAME(19700101));
SELECT COERCIBILITY(MONTHNAME('1970-01-01')),COERCIBILITY(DAYNAME('1970-01-01'));
# #
# Test types from + INTERVAL # Test types from + INTERVAL
......
...@@ -1033,12 +1033,25 @@ longlong Item_func_month::val_int() ...@@ -1033,12 +1033,25 @@ longlong Item_func_month::val_int()
} }
void Item_func_monthname::fix_length_and_dec()
{
THD* thd= current_thd;
CHARSET_INFO *cs= thd->variables.collation_connection;
uint32 repertoire= my_charset_repertoire(cs);
locale= thd->variables.lc_time_names;
collation.set(cs, DERIVATION_COERCIBLE, repertoire);
decimals=0;
max_length= locale->max_month_name_length * collation.collation->mbmaxlen;
maybe_null=1;
}
String* Item_func_monthname::val_str(String* str) String* Item_func_monthname::val_str(String* str)
{ {
DBUG_ASSERT(fixed == 1); DBUG_ASSERT(fixed == 1);
const char *month_name; const char *month_name;
uint month= (uint) val_int(); uint month= (uint) val_int();
THD *thd= current_thd; uint err;
if (null_value || !month) if (null_value || !month)
{ {
...@@ -1046,8 +1059,9 @@ String* Item_func_monthname::val_str(String* str) ...@@ -1046,8 +1059,9 @@ String* Item_func_monthname::val_str(String* str)
return (String*) 0; return (String*) 0;
} }
null_value=0; null_value=0;
month_name= thd->variables.lc_time_names->month_names->type_names[month-1]; month_name= locale->month_names->type_names[month-1];
str->set(month_name, strlen(month_name), system_charset_info); str->copy(month_name, strlen(month_name), &my_charset_utf8_bin,
collation.collation, &err);
return str; return str;
} }
...@@ -1172,19 +1186,32 @@ longlong Item_func_weekday::val_int() ...@@ -1172,19 +1186,32 @@ longlong Item_func_weekday::val_int()
odbc_type) + test(odbc_type); odbc_type) + test(odbc_type);
} }
void Item_func_dayname::fix_length_and_dec()
{
THD* thd= current_thd;
CHARSET_INFO *cs= thd->variables.collation_connection;
uint32 repertoire= my_charset_repertoire(cs);
locale= thd->variables.lc_time_names;
collation.set(cs, DERIVATION_COERCIBLE, repertoire);
decimals=0;
max_length= locale->max_day_name_length * collation.collation->mbmaxlen;
maybe_null=1;
}
String* Item_func_dayname::val_str(String* str) String* Item_func_dayname::val_str(String* str)
{ {
DBUG_ASSERT(fixed == 1); DBUG_ASSERT(fixed == 1);
uint weekday=(uint) val_int(); // Always Item_func_daynr() uint weekday=(uint) val_int(); // Always Item_func_daynr()
const char *day_name; const char *day_name;
THD *thd= current_thd; uint err;
if (null_value) if (null_value)
return (String*) 0; return (String*) 0;
day_name= thd->variables.lc_time_names->day_names->type_names[weekday]; day_name= locale->day_names->type_names[weekday];
str->set(day_name, strlen(day_name), system_charset_info); str->copy(day_name, strlen(day_name), &my_charset_utf8_bin,
collation.collation, &err);
return str; return str;
} }
......
...@@ -116,18 +116,13 @@ class Item_func_month :public Item_func ...@@ -116,18 +116,13 @@ class Item_func_month :public Item_func
class Item_func_monthname :public Item_func_month class Item_func_monthname :public Item_func_month
{ {
MY_LOCALE *locale;
public: public:
Item_func_monthname(Item *a) :Item_func_month(a) {} Item_func_monthname(Item *a) :Item_func_month(a) {}
const char *func_name() const { return "monthname"; } const char *func_name() const { return "monthname"; }
String *val_str(String *str); String *val_str(String *str);
enum Item_result result_type () const { return STRING_RESULT; } enum Item_result result_type () const { return STRING_RESULT; }
void fix_length_and_dec() void fix_length_and_dec();
{
collation.set(&my_charset_bin);
decimals=0;
max_length=10*my_charset_bin.mbmaxlen;
maybe_null=1;
}
bool check_partition_func_processor(uchar *int_arg) {return TRUE;} bool check_partition_func_processor(uchar *int_arg) {return TRUE;}
}; };
...@@ -291,18 +286,13 @@ class Item_func_weekday :public Item_func ...@@ -291,18 +286,13 @@ class Item_func_weekday :public Item_func
class Item_func_dayname :public Item_func_weekday class Item_func_dayname :public Item_func_weekday
{ {
MY_LOCALE *locale;
public: public:
Item_func_dayname(Item *a) :Item_func_weekday(a,0) {} Item_func_dayname(Item *a) :Item_func_weekday(a,0) {}
const char *func_name() const { return "dayname"; } const char *func_name() const { return "dayname"; }
String *val_str(String *str); String *val_str(String *str);
enum Item_result result_type () const { return STRING_RESULT; } enum Item_result result_type () const { return STRING_RESULT; }
void fix_length_and_dec() void fix_length_and_dec();
{
collation.set(&my_charset_bin);
decimals=0;
max_length=9*MY_CHARSET_BIN_MB_MAXLEN;
maybe_null=1;
}
bool check_partition_func_processor(uchar *int_arg) {return TRUE;} bool check_partition_func_processor(uchar *int_arg) {return TRUE;}
}; };
......
...@@ -148,15 +148,20 @@ typedef struct my_locale_st ...@@ -148,15 +148,20 @@ typedef struct my_locale_st
TYPELIB *ab_month_names; TYPELIB *ab_month_names;
TYPELIB *day_names; TYPELIB *day_names;
TYPELIB *ab_day_names; TYPELIB *ab_day_names;
uint max_month_name_length;
uint max_day_name_length;
#ifdef __cplusplus #ifdef __cplusplus
my_locale_st(uint number_par, my_locale_st(uint number_par,
const char *name_par, const char *descr_par, bool is_ascii_par, const char *name_par, const char *descr_par, bool is_ascii_par,
TYPELIB *month_names_par, TYPELIB *ab_month_names_par, TYPELIB *month_names_par, TYPELIB *ab_month_names_par,
TYPELIB *day_names_par, TYPELIB *ab_day_names_par) : TYPELIB *day_names_par, TYPELIB *ab_day_names_par,
uint max_month_name_length_par, uint max_day_name_length_par) :
number(number_par), number(number_par),
name(name_par), description(descr_par), is_ascii(is_ascii_par), name(name_par), description(descr_par), is_ascii(is_ascii_par),
month_names(month_names_par), ab_month_names(ab_month_names_par), month_names(month_names_par), ab_month_names(ab_month_names_par),
day_names(day_names_par), ab_day_names(ab_day_names_par) day_names(day_names_par), ab_day_names(ab_day_names_par),
max_month_name_length(max_month_name_length_par),
max_day_name_length(max_day_name_length_par)
{} {}
#endif #endif
} MY_LOCALE; } MY_LOCALE;
......
...@@ -4128,6 +4128,44 @@ void decrement_handler_count() ...@@ -4128,6 +4128,44 @@ void decrement_handler_count()
#endif /* defined(__NT__) || defined(HAVE_SMEM) */ #endif /* defined(__NT__) || defined(HAVE_SMEM) */
#ifndef DBUG_OFF
/*
Debugging helper function to keep the locale database
(see sql_locale.cc) and max_month_name_length and
max_day_name_length variable values in consistent state.
*/
static void test_lc_time_sz()
{
DBUG_ENTER("test_lc_time_sz");
for (MY_LOCALE **loc= my_locales; *loc; loc++)
{
uint max_month_len= 0;
uint max_day_len = 0;
for (const char **month= (*loc)->month_names->type_names; *month; month++)
{
set_if_bigger(max_month_len,
my_numchars_mb(&my_charset_utf8_general_ci,
*month, *month + strlen(*month)));
}
for (const char **day= (*loc)->day_names->type_names; *day; day++)
{
set_if_bigger(max_day_len,
my_numchars_mb(&my_charset_utf8_general_ci,
*day, *day + strlen(*day)));
}
if ((*loc)->max_month_name_length != max_month_len ||
(*loc)->max_day_name_length != max_day_len)
{
DBUG_PRINT("Wrong max day name(or month name) length for locale:",
("%s", (*loc)->name));
DBUG_ASSERT(0);
}
}
DBUG_VOID_RETURN;
}
#endif//DBUG_OFF
#ifndef EMBEDDED_LIBRARY #ifndef EMBEDDED_LIBRARY
#ifdef __WIN__ #ifdef __WIN__
int win_main(int argc, char **argv) int win_main(int argc, char **argv)
...@@ -4229,6 +4267,10 @@ int main(int argc, char **argv) ...@@ -4229,6 +4267,10 @@ int main(int argc, char **argv)
openlog(libwrapName, LOG_PID, LOG_AUTH); openlog(libwrapName, LOG_PID, LOG_AUTH);
#endif #endif
#ifndef DBUG_OFF
test_lc_time_sz();
#endif
/* /*
We have enough space for fiddling with the argv, continue We have enough space for fiddling with the argv, continue
*/ */
......
This diff is collapsed.
...@@ -338,6 +338,16 @@ my_string_repertoire(CHARSET_INFO *cs, const char *str, ulong length) ...@@ -338,6 +338,16 @@ my_string_repertoire(CHARSET_INFO *cs, const char *str, ulong length)
} }
/*
Returns repertoire for charset
*/
uint my_charset_repertoire(CHARSET_INFO *cs)
{
return cs->state & MY_CS_PUREASCII ?
MY_REPERTOIRE_ASCII : MY_REPERTOIRE_UNICODE30;
}
/* /*
Detect whether a character set is ASCII compatible. Detect whether a character set is ASCII compatible.
......
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