diff --git a/mysql-test/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result index 5516be88b75..5104d3d9d42 100644 --- a/mysql-test/r/ctype_utf8.result +++ b/mysql-test/r/ctype_utf8.result @@ -1064,46 +1064,56 @@ xxx yyy DROP TABLE t1; set names utf8; -select hex(char(1)); -hex(char(1)) +select hex(char(1 using utf8)); +hex(char(1 using utf8)) 01 -select char(0xd1,0x8f); -char(0xd1,0x8f) +select char(0xd1,0x8f using utf8); +char(0xd1,0x8f using utf8) я -select char(0xd18f); -char(0xd18f) +select char(0xd18f using utf8); +char(0xd18f using utf8) я -select char(53647); -char(53647) +select char(53647 using utf8); +char(53647 using utf8) я -select char(0xff,0x8f); -char(0xff,0x8f) +select char(0xff,0x8f using utf8); +char(0xff,0x8f using utf8) +Warnings: +Warning 1300 Invalid utf8 character string: 'FF8F' set sql_mode=traditional; -select char(0xff,0x8f); -char(0xff,0x8f) - -select convert(char(0xff,0x8f) using utf8); -convert(char(0xff,0x8f) using utf8) - -select char(195); -char(195) - -select convert(char(195) using utf8); -convert(char(195) using utf8) - -select char(196); -char(196) - -select convert(char(196) using utf8); -convert(char(196) using utf8) - +select char(0xff,0x8f using utf8); +char(0xff,0x8f using utf8) +NULL +Warnings: +Error 1300 Invalid utf8 character string: 'FF8F' +select char(195 using utf8); +char(195 using utf8) +NULL +Warnings: +Error 1300 Invalid utf8 character string: 'C3' +select char(196 using utf8); +char(196 using utf8) +NULL +Warnings: +Error 1300 Invalid utf8 character string: 'C4' +select char(2557 using utf8); +char(2557 using utf8) +NULL +Warnings: +Error 1300 Invalid utf8 character string: 'FD' +select hex(convert(char(2557 using latin1) using utf8)); +hex(convert(char(2557 using latin1) using utf8)) +09C3BD +select hex(char(195)); +hex(char(195)) +C3 +select hex(char(196)); +hex(char(196)) +C4 select hex(char(2557)); hex(char(2557)) 09FD -select hex(convert(char(2557) using utf8)); -hex(convert(char(2557) using utf8)) -09FD set names utf8; create table t1 (a char(1)) default character set utf8; create table t2 (a char(1)) default character set utf8; diff --git a/mysql-test/t/ctype_utf8.test b/mysql-test/t/ctype_utf8.test index d186ca8a1f6..8f695ef315c 100644 --- a/mysql-test/t/ctype_utf8.test +++ b/mysql-test/t/ctype_utf8.test @@ -871,22 +871,32 @@ DROP TABLE t1; # set names utf8; # correct value -select hex(char(1)); -select char(0xd1,0x8f); -select char(0xd18f); -select char(53647); +select hex(char(1 using utf8)); +select char(0xd1,0x8f using utf8); +select char(0xd18f using utf8); +select char(53647 using utf8); # incorrect value: return with warning -select char(0xff,0x8f); +select char(0xff,0x8f using utf8); # incorrect value in strict mode: return NULL with "Error" level warning set sql_mode=traditional; -select char(0xff,0x8f); -select convert(char(0xff,0x8f) using utf8); -select char(195); -select convert(char(195) using utf8); -select char(196); -select convert(char(196) using utf8); +select char(0xff,0x8f using utf8); +select char(195 using utf8); +select char(196 using utf8); +select char(2557 using utf8); + +# +# Check convert + char + using +# +select hex(convert(char(2557 using latin1) using utf8)); + +# +# char() without USING returns "binary" by default, any argument is ok +# +select hex(char(195)); +select hex(char(196)); select hex(char(2557)); -select hex(convert(char(2557) using utf8)); + + # # Bug#12891: UNION doesn't return DISTINCT result for multi-byte characters diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index ec470bb242b..5889821293d 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -480,12 +480,15 @@ public: class Item_func_char :public Item_str_func { public: - Item_func_char(List &list) :Item_str_func(list) {} + Item_func_char(List &list) :Item_str_func(list) + { collation.set(&my_charset_bin); } + Item_func_char(List &list, CHARSET_INFO *cs) :Item_str_func(list) + { collation.set(cs); } String *val_str(String *); void fix_length_and_dec() { - collation.set(&my_charset_bin); - maybe_null=0; max_length=arg_count; + maybe_null=0; + max_length=arg_count * collation.collation->mbmaxlen; } const char *func_name() const { return "char"; } }; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 447530d633b..14f617b9f8b 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -4536,6 +4536,8 @@ simple_expr: { $$= new Item_func_atan($3,$5); } | CHAR_SYM '(' expr_list ')' { $$= new Item_func_char(*$3); } + | CHAR_SYM '(' expr_list USING charset_name ')' + { $$= new Item_func_char(*$3, $5); } | CHARSET '(' expr ')' { $$= new Item_func_charset($3); } | COALESCE '(' expr_list ')'