Commit 5150fdcc authored by bar@mysql.com's avatar bar@mysql.com

ctype_utf8.result:

  adding test case
sql_table.cc:
  sql_table.cc:
  - do not create a new item when charsets are the same
  - return ER_INVALID_DEFAULT if default value cannot
    be converted into the column character set.
item.cc:
  - Allow conversion not only to Unicode,
    but also to and from "binary".
  - Adding safe_charset_converter() for Item_num
    and Item_varbinary, returning a fixed const Item.
parent ff764e2b
...@@ -905,6 +905,10 @@ select * from t1 where city = 'Durban '; ...@@ -905,6 +905,10 @@ select * from t1 where city = 'Durban ';
id city id city
2 Durban 2 Durban
drop table t1; drop table t1;
create table t1 (x set('A', 'B') default 0) character set utf8;
ERROR 42000: Invalid default value for 'x'
create table t1 (x enum('A', 'B') default 0) character set utf8;
ERROR 42000: Invalid default value for 'x'
SET NAMES UTF8; SET NAMES UTF8;
CREATE TABLE t1 ( CREATE TABLE t1 (
`id` int(20) NOT NULL auto_increment, `id` int(20) NOT NULL auto_increment,
......
...@@ -747,6 +747,15 @@ select * from t1 where city = 'Durban'; ...@@ -747,6 +747,15 @@ select * from t1 where city = 'Durban';
select * from t1 where city = 'Durban '; select * from t1 where city = 'Durban ';
drop table t1; drop table t1;
#
# Bug #11819 CREATE TABLE with a SET DEFAULT 0 and UTF8 crashes server.
#
--error 1067
create table t1 (x set('A', 'B') default 0) character set utf8;
--error 1067
create table t1 (x enum('A', 'B') default 0) character set utf8;
# #
# Test for bug #11167: join for utf8 varchar value longer than 255 bytes # Test for bug #11167: join for utf8 varchar value longer than 255 bytes
# #
......
...@@ -212,15 +212,43 @@ bool Item::eq(const Item *item, bool binary_cmp) const ...@@ -212,15 +212,43 @@ bool Item::eq(const Item *item, bool binary_cmp) const
Item *Item::safe_charset_converter(CHARSET_INFO *tocs) Item *Item::safe_charset_converter(CHARSET_INFO *tocs)
{ {
/* /*
Allow conversion from and to "binary".
Don't allow automatic conversion to non-Unicode charsets, Don't allow automatic conversion to non-Unicode charsets,
as it potentially loses data. as it potentially loses data.
*/ */
if (!(tocs->state & MY_CS_UNICODE)) if (collation.collation != &my_charset_bin &&
tocs != &my_charset_bin &&
!(tocs->state & MY_CS_UNICODE))
return NULL; // safe conversion is not possible return NULL; // safe conversion is not possible
return new Item_func_conv_charset(this, tocs); return new Item_func_conv_charset(this, tocs);
} }
/*
Created mostly for mysql_prepare_table(). Important
when a string ENUM/SET column is described with a numeric default value:
CREATE TABLE t1(a SET('a') DEFAULT 1);
We cannot use generic Item::safe_charset_converter(), because
the latter returns a non-fixed Item, so val_str() crashes afterwards.
Override Item_num method, to return a fixed item.
*/
Item *Item_num::safe_charset_converter(CHARSET_INFO *tocs)
{
Item_string *conv;
char buf[64];
String *s, tmp(buf, sizeof(buf), &my_charset_bin);
s= val_str(&tmp);
if ((conv= new Item_string(s->ptr(), s->length(), s->charset())))
{
conv->str_value.copy();
conv->str_value.shrink_to_length();
}
return conv;
}
Item *Item_string::safe_charset_converter(CHARSET_INFO *tocs) Item *Item_string::safe_charset_converter(CHARSET_INFO *tocs)
{ {
Item_string *conv; Item_string *conv;
...@@ -2151,6 +2179,20 @@ bool Item_varbinary::eq(const Item *arg, bool binary_cmp) const ...@@ -2151,6 +2179,20 @@ bool Item_varbinary::eq(const Item *arg, bool binary_cmp) const
return FALSE; return FALSE;
} }
Item *Item_varbinary::safe_charset_converter(CHARSET_INFO *tocs)
{
Item_string *conv;
String tmp, *str= val_str(&tmp);
if (!(conv= new Item_string(str->ptr(), str->length(), tocs)))
return NULL;
conv->str_value.copy();
conv->str_value.shrink_to_length();
return conv;
}
/* /*
Pack data in buffer for sending Pack data in buffer for sending
*/ */
......
...@@ -334,6 +334,7 @@ class Item_num: public Item ...@@ -334,6 +334,7 @@ class Item_num: public Item
{ {
public: public:
virtual Item_num *neg()= 0; virtual Item_num *neg()= 0;
Item *safe_charset_converter(CHARSET_INFO *tocs);
}; };
#define NO_CACHED_FIELD_INDEX ((uint)(-1)) #define NO_CACHED_FIELD_INDEX ((uint)(-1))
...@@ -835,6 +836,7 @@ public: ...@@ -835,6 +836,7 @@ public:
// to prevent drop fixed flag (no need parent cleanup call) // to prevent drop fixed flag (no need parent cleanup call)
void cleanup() {} void cleanup() {}
bool eq(const Item *item, bool binary_cmp) const; bool eq(const Item *item, bool binary_cmp) const;
virtual Item *safe_charset_converter(CHARSET_INFO *tocs);
}; };
......
...@@ -557,10 +557,15 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, ...@@ -557,10 +557,15 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
Convert the default value from client character Convert the default value from client character
set into the column character set if necessary. set into the column character set if necessary.
*/ */
if (sql_field->def) if (sql_field->def && cs != sql_field->def->collation.collation)
{
if (!(sql_field->def=
sql_field->def->safe_charset_converter(cs)))
{ {
sql_field->def= /* Could not convert */
sql_field->def->safe_charset_converter(cs); my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
DBUG_RETURN(-1);
}
} }
if (sql_field->sql_type == FIELD_TYPE_SET) if (sql_field->sql_type == FIELD_TYPE_SET)
......
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