Commit 2d619d7c authored by unknown's avatar unknown
Browse files

Bug#8235 Connection collation change & table create with default result in crash


mysql-test/r/ctype_ucs.result:
  Test case
mysql-test/t/ctype_ucs.test:
  Test case
sql/field.cc:
  Fixed minus check to be UCS2-compatible
strings/ctype-ucs2.c:
  Missing my_scan_ucs2() was added.
parent a5058450
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -613,3 +613,17 @@ ucs2_bin 00610009
ucs2_bin	0061
ucs2_bin	00610020
drop table t1;
SET NAMES latin1;
SET collation_connection='ucs2_swedish_ci';
CREATE TABLE t1 (Field1 int(10) default '0');
INSERT INTO t1 VALUES ('-1');
SELECT * FROM t1;
Field1
-1
DROP TABLE t1;
CREATE TABLE t1 (Field1 int(10) unsigned default '0');
INSERT INTO t1 VALUES ('-1');
Warnings:
Warning	1265	Data truncated for column 'Field1' at row 1
DROP TABLE t1;
SET NAMES latin1;
+21 −0
Original line number Diff line number Diff line
@@ -390,3 +390,24 @@ SET collation_connection='ucs2_general_ci';
SET NAMES latin1;
SET collation_connection='ucs2_bin';
-- source include/ctype_filesort.inc

SET NAMES latin1;
#
# Bug#8235
#
# This bug also helped to find another problem that
# INSERT of a UCS2 string containing a negative number
# into a unsigned int column didn't produce warnings.
# This test covers both problems.
#
SET collation_connection='ucs2_swedish_ci';
CREATE TABLE t1 (Field1 int(10) default '0');
# no warnings, negative numbers are allowed
INSERT INTO t1 VALUES ('-1');
SELECT * FROM t1;
DROP TABLE t1;
CREATE TABLE t1 (Field1 int(10) unsigned default '0');
# this should generate a "Data truncated" warning
INSERT INTO t1 VALUES ('-1');
DROP TABLE t1;
SET NAMES latin1;
+10 −2
Original line number Diff line number Diff line
@@ -1777,6 +1777,14 @@ void Field_medium::sql_type(String &res) const
****************************************************************************/


static bool test_if_minus(CHARSET_INFO *cs,
                          const char *s, const char *e)
{
  my_wc_t wc;
  return cs->cset->mb_wc(cs, &wc, (uchar*) s, (uchar*) e) > 0 && wc == '-';
}


int Field_long::store(const char *from,uint len,CHARSET_INFO *cs)
{
  long tmp;
@@ -1790,7 +1798,7 @@ int Field_long::store(const char *from,uint len,CHARSET_INFO *cs)

  if (unsigned_flag)
  {
    if (!len || *from == '-')
    if (!len || test_if_minus(cs, from, from + len))
    {
      tmp=0;					// Set negative to 0
      my_errno=ERANGE;
@@ -2086,7 +2094,7 @@ int Field_longlong::store(const char *from,uint len,CHARSET_INFO *cs)
  my_errno=0;
  if (unsigned_flag)
  {
    if (!len || *from == '-')
    if (!len || test_if_minus(cs, from, from + len))
    {
      tmp=0;					// Set negative to 0
      my_errno= ERANGE;
+24 −1
Original line number Diff line number Diff line
@@ -1480,6 +1480,29 @@ my_bool my_like_range_ucs2(CHARSET_INFO *cs,
  return 0;
}


ulong my_scan_ucs2(CHARSET_INFO *cs __attribute__((unused)),
                   const char *str, const char *end, int sequence_type)
{
  const char *str0= str;
  end--; /* for easier loop condition, because of two bytes per character */
  
  switch (sequence_type)
  {
  case MY_SEQ_SPACES:
    for ( ; str < end; str+= 2)
    {
      if (str[0] != '\0' || str[1] != ' ')
        break;
    }
    return str - str0;
  default:
    return 0;
  }
}



static MY_COLLATION_HANDLER my_collation_ucs2_general_ci_handler =
{
    NULL,		/* init */
@@ -1534,7 +1557,7 @@ MY_CHARSET_HANDLER my_charset_ucs2_handler=
    my_strntoull_ucs2,
    my_strntod_ucs2,
    my_strtoll10_ucs2,
    my_scan_8bit
    my_scan_ucs2
};