summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <bar@mysql.com>2005-07-14 10:46:15 +0500
committerunknown <bar@mysql.com>2005-07-14 10:46:15 +0500
commit86cb32b7b0cf3de0c697e75cfa0f5338601d6eb8 (patch)
tree5c176739b0f73dfb0d35397879e6434dac085fc5
parentc663aa896194ee7320b1c17b8a598d5713d32bce (diff)
parent4a2af29fe784ff10b7506ee39d7054859fc6eb51 (diff)
downloadmariadb-git-86cb32b7b0cf3de0c697e75cfa0f5338601d6eb8.tar.gz
Merge abarkov@bk-internal.mysql.com:/home/bk/mysql-4.1
into mysql.com:/usr/home/bar/mysql-4.1.num-conv mysql-test/r/ctype_utf8.result: Auto merged mysql-test/t/ctype_utf8.test: Auto merged sql/item.cc: Auto merged sql/item.h: Auto merged sql/sql_table.cc: Auto merged
-rw-r--r--mysql-test/r/ctype_utf8.result4
-rw-r--r--mysql-test/t/ctype_utf8.test9
-rw-r--r--sql/item.cc44
-rw-r--r--sql/item.h2
-rw-r--r--sql/sql_table.cc11
5 files changed, 66 insertions, 4 deletions
diff --git a/mysql-test/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result
index 665387e476c..150c06840c6 100644
--- a/mysql-test/r/ctype_utf8.result
+++ b/mysql-test/r/ctype_utf8.result
@@ -905,6 +905,10 @@ select * from t1 where city = 'Durban ';
id city
2 Durban
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;
CREATE TABLE t1 (
`id` int(20) NOT NULL auto_increment,
diff --git a/mysql-test/t/ctype_utf8.test b/mysql-test/t/ctype_utf8.test
index 737dcbcf1ed..151bd91feb9 100644
--- a/mysql-test/t/ctype_utf8.test
+++ b/mysql-test/t/ctype_utf8.test
@@ -748,6 +748,15 @@ select * from t1 where city = 'Durban ';
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
#
diff --git a/sql/item.cc b/sql/item.cc
index ed39fe177cd..6f224983d4e 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -212,15 +212,43 @@ bool Item::eq(const Item *item, bool binary_cmp) const
Item *Item::safe_charset_converter(CHARSET_INFO *tocs)
{
/*
+ Allow conversion from and to "binary".
Don't allow automatic conversion to non-Unicode charsets,
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 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_string *conv;
@@ -2127,6 +2155,20 @@ bool Item_varbinary::eq(const Item *arg, bool binary_cmp) const
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
*/
diff --git a/sql/item.h b/sql/item.h
index a8b0bfe9512..895463ceeca 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -334,6 +334,7 @@ class Item_num: public Item
{
public:
virtual Item_num *neg()= 0;
+ Item *safe_charset_converter(CHARSET_INFO *tocs);
};
#define NO_CACHED_FIELD_INDEX ((uint)(-1))
@@ -834,6 +835,7 @@ public:
// to prevent drop fixed flag (no need parent cleanup call)
void cleanup() {}
bool eq(const Item *item, bool binary_cmp) const;
+ virtual Item *safe_charset_converter(CHARSET_INFO *tocs);
};
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index d4dcfdd6759..204a8df6e9a 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -557,10 +557,15 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
Convert the default value from client character
set into the column character set if necessary.
*/
- if (sql_field->def)
+ if (sql_field->def && cs != sql_field->def->collation.collation)
{
- sql_field->def=
- sql_field->def->safe_charset_converter(cs);
+ if (!(sql_field->def=
+ sql_field->def->safe_charset_converter(cs)))
+ {
+ /* Could not convert */
+ my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
+ DBUG_RETURN(-1);
+ }
}
if (sql_field->sql_type == FIELD_TYPE_SET)