Commit d79d0c40 authored by Alexander Barkov's avatar Alexander Barkov

merge 5.3 -> 5.5

parents a588de1f a33bb001
--echo #
--echo # MDEV-4842 STR_TO_DATE does not work with UCS2/UTF16/UTF32
--echo #
SELECT @@character_set_connection, HEX(CAST(_utf8'÷' AS CHAR));
SELECT STR_TO_DATE(CAST(_utf8'2001÷01÷01' AS CHAR),CAST(_utf8'%Y÷%m÷%d' AS CHAR));
CREATE TABLE t1 AS SELECT REPEAT(' ', 64) AS subject, REPEAT(' ',64) AS pattern LIMIT 0;
SHOW COLUMNS FROM t1;
INSERT INTO t1 VALUES (_utf8'2001÷01÷01',_utf8'%Y÷%m÷%d');
SELECT HEX(subject),HEX(pattern),STR_TO_DATE(subject, pattern) FROM t1;
DROP TABLE t1;
...@@ -336,6 +336,25 @@ select c1 as c2h from t1 where c1 like 'ab#_def' escape '#'; ...@@ -336,6 +336,25 @@ select c1 as c2h from t1 where c1 like 'ab#_def' escape '#';
c2h c2h
ab_def ab_def
drop table t1; drop table t1;
#
# MDEV-4842 STR_TO_DATE does not work with UCS2/UTF16/UTF32
#
SELECT @@character_set_connection, HEX(CAST(_utf8'÷' AS CHAR));
@@character_set_connection HEX(CAST(_utf8'÷' AS CHAR))
latin1 F7
SELECT STR_TO_DATE(CAST(_utf8'2001÷01÷01' AS CHAR),CAST(_utf8'%Y÷%m÷%d' AS CHAR));
STR_TO_DATE(CAST(_utf8'2001÷01÷01' AS CHAR),CAST(_utf8'%Y÷%m÷%d' AS CHAR))
2001-01-01
CREATE TABLE t1 AS SELECT REPEAT(' ', 64) AS subject, REPEAT(' ',64) AS pattern LIMIT 0;
SHOW COLUMNS FROM t1;
Field Type Null Key Default Extra
subject varchar(64) NO
pattern varchar(64) NO
INSERT INTO t1 VALUES (_utf8'2001÷01÷01',_utf8'%Y÷%m÷%d');
SELECT HEX(subject),HEX(pattern),STR_TO_DATE(subject, pattern) FROM t1;
HEX(subject) HEX(pattern) STR_TO_DATE(subject, pattern)
32303031F73031F73031 2559F7256DF72564 2001-01-01 00:00:00
DROP TABLE t1;
SET collation_connection='latin1_bin'; SET collation_connection='latin1_bin';
create table t1 select repeat('a',4000) a; create table t1 select repeat('a',4000) a;
delete from t1; delete from t1;
......
...@@ -138,6 +138,25 @@ a hex(b) c ...@@ -138,6 +138,25 @@ a hex(b) c
3 F1F2F1F2F1F2F1F2F1F2F1F2F1F2F1F2F1F2F1F2F1F2 3 F1F2F1F2F1F2F1F2F1F2F1F2F1F2F1F2F1F2F1F2F1F2
4 F1F2F1F2F1F2F1F2F1F2F1F2F1F2F1F2F1F2F1F2F1F2F1F2 4 F1F2F1F2F1F2F1F2F1F2F1F2F1F2F1F2F1F2F1F2F1F2F1F2
DROP TABLE t1; DROP TABLE t1;
#
# MDEV-4842 STR_TO_DATE does not work with UCS2/UTF16/UTF32
#
SELECT @@character_set_connection, HEX(CAST(_utf8'÷' AS CHAR));
@@character_set_connection HEX(CAST(_utf8'÷' AS CHAR))
sjis 8180
SELECT STR_TO_DATE(CAST(_utf8'2001÷01÷01' AS CHAR),CAST(_utf8'%Y÷%m÷%d' AS CHAR));
STR_TO_DATE(CAST(_utf8'2001÷01÷01' AS CHAR),CAST(_utf8'%Y÷%m÷%d' AS CHAR))
2001-01-01
CREATE TABLE t1 AS SELECT REPEAT(' ', 64) AS subject, REPEAT(' ',64) AS pattern LIMIT 0;
SHOW COLUMNS FROM t1;
Field Type Null Key Default Extra
subject varchar(64) NO
pattern varchar(64) NO
INSERT INTO t1 VALUES (_utf8'2001÷01÷01',_utf8'%Y÷%m÷%d');
SELECT HEX(subject),HEX(pattern),STR_TO_DATE(subject, pattern) FROM t1;
HEX(subject) HEX(pattern) STR_TO_DATE(subject, pattern)
323030318180303181803031 25598180256D81802564 2001-01-01 00:00:00
DROP TABLE t1;
SET collation_connection='sjis_bin'; SET collation_connection='sjis_bin';
create table t1 select repeat('a',4000) a; create table t1 select repeat('a',4000) a;
delete from t1; delete from t1;
......
...@@ -804,6 +804,25 @@ a hex(b) c ...@@ -804,6 +804,25 @@ a hex(b) c
3 F1F2F1F2F1F2F1F2F1F2F1F2F1F2F1F2F1F2F1F2F1F2 3 F1F2F1F2F1F2F1F2F1F2F1F2F1F2F1F2F1F2F1F2F1F2
4 F1F2F1F2F1F2F1F2F1F2F1F2F1F2F1F2F1F2F1F2F1F2F1F2 4 F1F2F1F2F1F2F1F2F1F2F1F2F1F2F1F2F1F2F1F2F1F2F1F2
DROP TABLE t1; DROP TABLE t1;
#
# MDEV-4842 STR_TO_DATE does not work with UCS2/UTF16/UTF32
#
SELECT @@character_set_connection, HEX(CAST(_utf8'÷' AS CHAR));
@@character_set_connection HEX(CAST(_utf8'÷' AS CHAR))
ucs2 00F7
SELECT STR_TO_DATE(CAST(_utf8'2001÷01÷01' AS CHAR),CAST(_utf8'%Y÷%m÷%d' AS CHAR));
STR_TO_DATE(CAST(_utf8'2001÷01÷01' AS CHAR),CAST(_utf8'%Y÷%m÷%d' AS CHAR))
2001-01-01
CREATE TABLE t1 AS SELECT REPEAT(' ', 64) AS subject, REPEAT(' ',64) AS pattern LIMIT 0;
SHOW COLUMNS FROM t1;
Field Type Null Key Default Extra
subject varchar(64) NO
pattern varchar(64) NO
INSERT INTO t1 VALUES (_utf8'2001÷01÷01',_utf8'%Y÷%m÷%d');
SELECT HEX(subject),HEX(pattern),STR_TO_DATE(subject, pattern) FROM t1;
HEX(subject) HEX(pattern) STR_TO_DATE(subject, pattern)
003200300030003100F70030003100F700300031 0025005900F70025006D00F700250064 2001-01-01 00:00:00
DROP TABLE t1;
SET NAMES latin1; SET NAMES latin1;
SET collation_connection='ucs2_bin'; SET collation_connection='ucs2_bin';
create table t1 select repeat('a',4000) a; create table t1 select repeat('a',4000) a;
......
...@@ -977,6 +977,25 @@ ss ...@@ -977,6 +977,25 @@ ss
u,ü u,ü
ue ue
drop table t1; drop table t1;
#
# MDEV-4842 STR_TO_DATE does not work with UCS2/UTF16/UTF32
#
SELECT @@character_set_connection, HEX(CAST(_utf8'÷' AS CHAR));
@@character_set_connection HEX(CAST(_utf8'÷' AS CHAR))
utf8 C3B7
SELECT STR_TO_DATE(CAST(_utf8'2001÷01÷01' AS CHAR),CAST(_utf8'%Y÷%m÷%d' AS CHAR));
STR_TO_DATE(CAST(_utf8'2001÷01÷01' AS CHAR),CAST(_utf8'%Y÷%m÷%d' AS CHAR))
2001-01-01
CREATE TABLE t1 AS SELECT REPEAT(' ', 64) AS subject, REPEAT(' ',64) AS pattern LIMIT 0;
SHOW COLUMNS FROM t1;
Field Type Null Key Default Extra
subject varchar(64) NO
pattern varchar(64) NO
INSERT INTO t1 VALUES (_utf8'2001÷01÷01',_utf8'%Y÷%m÷%d');
SELECT HEX(subject),HEX(pattern),STR_TO_DATE(subject, pattern) FROM t1;
HEX(subject) HEX(pattern) STR_TO_DATE(subject, pattern)
32303031C3B73031C3B73031 2559C3B7256DC3B72564 2001-01-01 00:00:00
DROP TABLE t1;
SET collation_connection='utf8_bin'; SET collation_connection='utf8_bin';
create table t1 select repeat('a',4000) a; create table t1 select repeat('a',4000) a;
delete from t1; delete from t1;
......
...@@ -82,6 +82,7 @@ select 'a' regexp 'A' collate latin1_bin; ...@@ -82,6 +82,7 @@ select 'a' regexp 'A' collate latin1_bin;
SET collation_connection='latin1_swedish_ci'; SET collation_connection='latin1_swedish_ci';
-- source include/ctype_filesort.inc -- source include/ctype_filesort.inc
-- source include/ctype_like_escape.inc -- source include/ctype_like_escape.inc
-- source include/ctype_str_to_date.inc
SET collation_connection='latin1_bin'; SET collation_connection='latin1_bin';
-- source include/ctype_filesort.inc -- source include/ctype_filesort.inc
-- source include/ctype_like_escape.inc -- source include/ctype_like_escape.inc
......
...@@ -69,6 +69,7 @@ SET collation_connection='sjis_japanese_ci'; ...@@ -69,6 +69,7 @@ SET collation_connection='sjis_japanese_ci';
-- source include/ctype_innodb_like.inc -- source include/ctype_innodb_like.inc
-- source include/ctype_like_escape.inc -- source include/ctype_like_escape.inc
-- source include/ctype_like_range_f1f2.inc -- source include/ctype_like_range_f1f2.inc
-- source include/ctype_str_to_date.inc
SET collation_connection='sjis_bin'; SET collation_connection='sjis_bin';
-- source include/ctype_filesort.inc -- source include/ctype_filesort.inc
-- source include/ctype_innodb_like.inc -- source include/ctype_innodb_like.inc
......
...@@ -421,6 +421,7 @@ SET collation_connection='ucs2_general_ci'; ...@@ -421,6 +421,7 @@ SET collation_connection='ucs2_general_ci';
-- source include/ctype_like_escape.inc -- source include/ctype_like_escape.inc
-- source include/ctype_german.inc -- source include/ctype_german.inc
-- source include/ctype_like_range_f1f2.inc -- source include/ctype_like_range_f1f2.inc
-- source include/ctype_str_to_date.inc
SET NAMES latin1; SET NAMES latin1;
SET collation_connection='ucs2_bin'; SET collation_connection='ucs2_bin';
-- source include/ctype_filesort.inc -- source include/ctype_filesort.inc
......
...@@ -714,6 +714,7 @@ SET collation_connection='utf8_general_ci'; ...@@ -714,6 +714,7 @@ SET collation_connection='utf8_general_ci';
-- source include/ctype_filesort.inc -- source include/ctype_filesort.inc
-- source include/ctype_like_escape.inc -- source include/ctype_like_escape.inc
-- source include/ctype_german.inc -- source include/ctype_german.inc
-- source include/ctype_str_to_date.inc
SET collation_connection='utf8_bin'; SET collation_connection='utf8_bin';
-- source include/ctype_filesort.inc -- source include/ctype_filesort.inc
-- source include/ctype_like_escape.inc -- source include/ctype_like_escape.inc
......
...@@ -263,6 +263,24 @@ String *Item::val_str_ascii(String *str) ...@@ -263,6 +263,24 @@ String *Item::val_str_ascii(String *str)
} }
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) String *Item::val_string_from_real(String *str)
{ {
double nr= val_real(); double nr= val_real();
......
...@@ -896,6 +896,10 @@ public: ...@@ -896,6 +896,10 @@ public:
*/ */
virtual String *val_str_ascii(String *str); virtual String *val_str_ascii(String *str);
/*
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. Return decimal representation of item with fixed point.
......
...@@ -3096,13 +3096,25 @@ get_date_time_result_type(const char *format, uint length) ...@@ -3096,13 +3096,25 @@ get_date_time_result_type(const char *format, uint length)
void Item_func_str_to_date::fix_length_and_dec() 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; cached_field_type= MYSQL_TYPE_DATETIME;
decimals= NOT_FIXED_DEC; decimals= NOT_FIXED_DEC;
if ((const_item= args[1]->const_item())) if ((const_item= args[1]->const_item()))
{ {
char format_buff[64]; char format_buff[64];
String format_str(format_buff, sizeof(format_buff), &my_charset_bin); 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; decimals= 0;
if (!args[1]->null_value) if (!args[1]->null_value)
{ {
...@@ -3140,8 +3152,8 @@ bool Item_func_str_to_date::get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date) ...@@ -3140,8 +3152,8 @@ bool Item_func_str_to_date::get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date)
String format_str(format_buff, sizeof(format_buff), &my_charset_bin), String format_str(format_buff, sizeof(format_buff), &my_charset_bin),
*format; *format;
val= args[0]->val_str(&val_string); val= args[0]->val_str(&val_string, &subject_converter, internal_charset);
format= args[1]->val_str(&format_str); format= args[1]->val_str(&format_str, &format_converter, internal_charset);
if (args[0]->null_value || args[1]->null_value) if (args[0]->null_value || args[1]->null_value)
return (null_value=1); return (null_value=1);
......
...@@ -1029,9 +1029,13 @@ class Item_func_str_to_date :public Item_temporal_func ...@@ -1029,9 +1029,13 @@ class Item_func_str_to_date :public Item_temporal_func
enum_field_types cached_field_type; enum_field_types cached_field_type;
timestamp_type cached_timestamp_type; timestamp_type cached_timestamp_type;
bool const_item; bool const_item;
String subject_converter;
String format_converter;
CHARSET_INFO *internal_charset;
public: public:
Item_func_str_to_date(Item *a, Item *b) 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, ulonglong fuzzy_date); bool get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date);
const char *func_name() const { return "str_to_date"; } const char *func_name() const { return "str_to_date"; }
......
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