diff options
author | Alexander Barkov <bar@mnogosearch.org> | 2013-11-08 14:18:16 +0400 |
---|---|---|
committer | Alexander Barkov <bar@mnogosearch.org> | 2013-11-08 14:18:16 +0400 |
commit | a33bb001445d2576f15437d9392bc70736ab419a (patch) | |
tree | 878fd523c8bcdac7fdfe7af8800bc28c92969fe1 /sql | |
parent | 5ce11d8b4ca2a57968656925a69ed8114d5374f6 (diff) | |
download | mariadb-git-a33bb001445d2576f15437d9392bc70736ab419a.tar.gz |
MDEV-4842 STR_TO_DATE does not work with UCS2/UTF16/UTF32
Diffstat (limited to 'sql')
-rw-r--r-- | sql/item.cc | 18 | ||||
-rw-r--r-- | sql/item.h | 4 | ||||
-rw-r--r-- | sql/item_timefunc.cc | 18 | ||||
-rw-r--r-- | sql/item_timefunc.h | 6 |
4 files changed, 42 insertions, 4 deletions
diff --git a/sql/item.cc b/sql/item.cc index 803c9fee576..a415464a2f9 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -218,6 +218,24 @@ bool Item::val_bool() } +String *Item::val_str(String *str, String *converter, CHARSET_INFO *cs) +{ + String *res= val_str(str); + if (null_value) + return (String *) 0; + + if (!cs) + return res; + + uint errors; + if ((null_value= converter->copy(res->ptr(), res->length(), + collation.collation, cs, &errors))) + return (String *) 0; + + return converter; +} + + String *Item::val_string_from_real(String *str) { double nr= val_real(); diff --git a/sql/item.h b/sql/item.h index 4f03d588bbc..084e77e4d23 100644 --- a/sql/item.h +++ b/sql/item.h @@ -794,6 +794,10 @@ public: */ virtual String *val_str(String *str)=0; /* + Returns the val_str() value converted to the given character set. + */ + String *val_str(String *str, String *converter, CHARSET_INFO *to); + /* Return decimal representation of item with fixed point. SYNOPSIS diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 6c304946abc..cb60368aafd 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -2980,13 +2980,25 @@ get_date_time_result_type(const char *format, uint length) void Item_func_str_to_date::fix_length_and_dec() { + if (agg_arg_charsets(collation, args, 2, MY_COLL_ALLOW_CONV, 1)) + return; + if (collation.collation->mbminlen > 1) + { +#if MYSQL_VERSION_ID > 50500 + internal_charset= &my_charset_utf8mb4_general_ci; +#else + internal_charset= &my_charset_utf8_general_ci; +#endif + } + cached_field_type= MYSQL_TYPE_DATETIME; decimals= NOT_FIXED_DEC; if ((const_item= args[1]->const_item())) { char format_buff[64]; String format_str(format_buff, sizeof(format_buff), &my_charset_bin); - String *format= args[1]->val_str(&format_str); + String *format= args[1]->val_str(&format_str, &format_converter, + internal_charset); decimals= 0; if (!args[1]->null_value) { @@ -3024,8 +3036,8 @@ bool Item_func_str_to_date::get_date(MYSQL_TIME *ltime, uint fuzzy_date) String format_str(format_buff, sizeof(format_buff), &my_charset_bin), *format; - val= args[0]->val_str(&val_string); - format= args[1]->val_str(&format_str); + val= args[0]->val_str(&val_string, &subject_converter, internal_charset); + format= args[1]->val_str(&format_str, &format_converter, internal_charset); if (args[0]->null_value || args[1]->null_value) goto null_date; diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h index 20365d4f25d..bc048e1ff64 100644 --- a/sql/item_timefunc.h +++ b/sql/item_timefunc.h @@ -998,9 +998,13 @@ class Item_func_str_to_date :public Item_temporal_func enum_field_types cached_field_type; timestamp_type cached_timestamp_type; bool const_item; + String subject_converter; + String format_converter; + CHARSET_INFO *internal_charset; public: Item_func_str_to_date(Item *a, Item *b) - :Item_temporal_func(a, b), const_item(false) + :Item_temporal_func(a, b), const_item(false), + internal_charset(NULL) {} bool get_date(MYSQL_TIME *ltime, uint fuzzy_date); const char *func_name() const { return "str_to_date"; } |