Commit db39976a authored by gluh@mysql.com/eagle.(none)'s avatar gluh@mysql.com/eagle.(none)
Browse files

Bug#30981 CHAR(0x41 USING ucs2) doesn't add leading zero

Bug#30982 CHAR(..USING..) can return a not-well-formed string
Bug#30986 Character set introducer followed by a HEX string can return bad result
check_well_formed_result moved to Item from Item_str_func
fixed Item_func_char::val_str for proper ucs symbols converting
added check for well formed strings for correct conversion of constants with underscore
charset
parent 20ec6605
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -922,4 +922,7 @@ ERROR HY000: Illegal mix of collations (ascii_general_ci,IMPLICIT) and (ucs2_gen
select * from t1 where a=if(b<10,_ucs2 0x0062,_ucs2 0x00C0);
ERROR HY000: Illegal mix of collations (ascii_general_ci,IMPLICIT) and (ucs2_general_ci,COERCIBLE) for operation '='
drop table t1;
select hex(char(0x41 using ucs2));
hex(char(0x41 using ucs2))
0041
End of 5.0 tests
+64 −2
Original line number Diff line number Diff line
@@ -1538,12 +1538,12 @@ char(53647 using utf8)
я
select char(0xff,0x8f using utf8);
char(0xff,0x8f using utf8)


Warnings:
Warning	1300	Invalid utf8 character string: 'FF8F'
select convert(char(0xff,0x8f) using utf8);
convert(char(0xff,0x8f) using utf8)


Warnings:
Warning	1300	Invalid utf8 character string: 'FF8F'
set sql_mode=traditional;
@@ -1730,3 +1730,65 @@ i
1
н1234567890
DROP TABLE t1, t2;
set sql_mode=traditional;
select hex(char(0xFF using utf8));
hex(char(0xFF using utf8))
NULL
Warnings:
Error	1300	Invalid utf8 character string: 'FF'
select hex(convert(0xFF using utf8));
hex(convert(0xFF using utf8))
NULL
Warnings:
Error	1300	Invalid utf8 character string: 'FF'
select hex(_utf8 0x616263FF);
hex(_utf8 0x616263FF)
NULL
Warnings:
Error	1300	Invalid utf8 character string: 'FF'
select hex(_utf8 X'616263FF');
hex(_utf8 X'616263FF')
NULL
Warnings:
Error	1300	Invalid utf8 character string: 'FF'
select hex(_utf8 B'001111111111');
hex(_utf8 B'001111111111')
NULL
Warnings:
Error	1300	Invalid utf8 character string: 'FF'
select (_utf8 X'616263FF');
(_utf8 X'616263FF')
NULL
Warnings:
Error	1300	Invalid utf8 character string: 'FF'
set sql_mode=default;
select hex(char(0xFF using utf8));
hex(char(0xFF using utf8))

Warnings:
Warning	1300	Invalid utf8 character string: 'FF'
select hex(convert(0xFF using utf8));
hex(convert(0xFF using utf8))

Warnings:
Warning	1300	Invalid utf8 character string: 'FF'
select hex(_utf8 0x616263FF);
hex(_utf8 0x616263FF)
616263
Warnings:
Warning	1300	Invalid utf8 character string: 'FF'
select hex(_utf8 X'616263FF');
hex(_utf8 X'616263FF')
616263
Warnings:
Warning	1300	Invalid utf8 character string: 'FF'
select hex(_utf8 B'001111111111');
hex(_utf8 B'001111111111')
03
Warnings:
Warning	1300	Invalid utf8 character string: 'FF'
select (_utf8 X'616263FF');
(_utf8 X'616263FF')
abc
Warnings:
Warning	1300	Invalid utf8 character string: 'FF'
+5 −0
Original line number Diff line number Diff line
@@ -651,4 +651,9 @@ select * from t1 where a=if(b<10,_ucs2 0x00C0,_ucs2 0x0062);
select * from t1 where a=if(b<10,_ucs2 0x0062,_ucs2 0x00C0);
drop table t1;

#
# Bug#30981 CHAR(0x41 USING ucs2) doesn't add leading zero
#
select hex(char(0x41 using ucs2));

--echo End of 5.0 tests
+19 −0
Original line number Diff line number Diff line
@@ -1403,3 +1403,22 @@ SELECT b FROM t2 UNION SELECT c FROM t1;
SELECT i FROM t2 UNION SELECT c FROM t1;

DROP TABLE t1, t2;

#
# Bug#30982: CHAR(..USING..) can return a not-well-formed string
# Bug #30986: Character set introducer followed by a HEX string can return bad result
#
set sql_mode=traditional;
select hex(char(0xFF using utf8));
select hex(convert(0xFF using utf8));
select hex(_utf8 0x616263FF);
select hex(_utf8 X'616263FF');
select hex(_utf8 B'001111111111');
select (_utf8 X'616263FF');
set sql_mode=default;
select hex(char(0xFF using utf8));
select hex(convert(0xFF using utf8));
select hex(_utf8 0x616263FF);
select hex(_utf8 X'616263FF');
select hex(_utf8 B'001111111111');
select (_utf8 X'616263FF');
+35 −0
Original line number Diff line number Diff line
@@ -4247,6 +4247,41 @@ bool Item::is_datetime()
}


String *Item::check_well_formed_result(String *str)
{
  /* Check whether we got a well-formed string */
  CHARSET_INFO *cs= str->charset();
  int well_formed_error;
  uint wlen= cs->cset->well_formed_len(cs,
                                       str->ptr(), str->ptr() + str->length(),
                                       str->length(), &well_formed_error);
  if (wlen < str->length())
  {
    THD *thd= current_thd;
    char hexbuf[7];
    enum MYSQL_ERROR::enum_warning_level level;
    uint diff= str->length() - wlen;
    set_if_smaller(diff, 3);
    octet2hex(hexbuf, str->ptr() + wlen, diff);
    if (thd->variables.sql_mode &
        (MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES))
    {
      level= MYSQL_ERROR::WARN_LEVEL_ERROR;
      null_value= 1;
      str= 0;
    }
    else
    {
      level= MYSQL_ERROR::WARN_LEVEL_WARN;
      str->length(wlen);
    }
    push_warning_printf(thd, level, ER_INVALID_CHARACTER_STRING,
                        ER(ER_INVALID_CHARACTER_STRING), cs->csname, hexbuf);
  }
  return str;
}


/*
  Create a field to hold a string value from an item

Loading