diff options
-rw-r--r-- | mysql-test/r/ctype_collate.result | 4 | ||||
-rw-r--r-- | mysql-test/r/func_str.result | 62 | ||||
-rw-r--r-- | mysql-test/r/func_system.result | 8 | ||||
-rw-r--r-- | mysql-test/r/type_blob.result | 2 | ||||
-rw-r--r-- | mysql-test/t/func_system.test | 9 | ||||
-rw-r--r-- | sql/item.cc | 10 | ||||
-rw-r--r-- | sql/item.h | 12 | ||||
-rw-r--r-- | sql/item_create.cc | 2 | ||||
-rw-r--r-- | sql/item_func.cc | 2 | ||||
-rw-r--r-- | sql/item_strfunc.cc | 17 | ||||
-rw-r--r-- | sql/item_strfunc.h | 16 |
11 files changed, 87 insertions, 57 deletions
diff --git a/mysql-test/r/ctype_collate.result b/mysql-test/r/ctype_collate.result index d4a8beda185..bc77e9c2362 100644 --- a/mysql-test/r/ctype_collate.result +++ b/mysql-test/r/ctype_collate.result @@ -514,7 +514,7 @@ Variable_name Value character_set_client latin1 SELECT charset('a'),collation('a'),coercibility('a'),'a'='A'; charset('a') collation('a') coercibility('a') 'a'='A' -latin1 latin1_swedish_ci 3 1 +latin1 latin1_swedish_ci 4 1 explain extended SELECT charset('a'),collation('a'),coercibility('a'),'a'='A'; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used @@ -525,7 +525,7 @@ SHOW VARIABLES LIKE 'collation_client'; Variable_name Value SELECT charset('a'),collation('a'),coercibility('a'),'a'='A'; charset('a') collation('a') coercibility('a') 'a'='A' -latin1 latin1_swedish_ci 3 1 +latin1 latin1_swedish_ci 4 1 SET CHARACTER SET 'DEFAULT'; ERROR 42000: Unknown character set: 'DEFAULT' DROP TABLE t1; diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result index f238915d3b9..2ef2329444c 100644 --- a/mysql-test/r/func_str.result +++ b/mysql-test/r/func_str.result @@ -464,97 +464,97 @@ select _latin1'B' COLLATE latin1_general_ci in (_latin1'a',_latin1'b' COLLATE la ERROR HY000: Illegal mix of collations (latin1_general_ci,EXPLICIT), (latin1_swedish_ci,COERCIBLE), (latin1_bin,EXPLICIT) for operation ' IN ' select collation(bin(130)), coercibility(bin(130)); collation(bin(130)) coercibility(bin(130)) -latin1_swedish_ci 3 +latin1_swedish_ci 4 select collation(oct(130)), coercibility(oct(130)); collation(oct(130)) coercibility(oct(130)) -latin1_swedish_ci 3 +latin1_swedish_ci 4 select collation(conv(130,16,10)), coercibility(conv(130,16,10)); collation(conv(130,16,10)) coercibility(conv(130,16,10)) -latin1_swedish_ci 3 +latin1_swedish_ci 4 select collation(hex(130)), coercibility(hex(130)); collation(hex(130)) coercibility(hex(130)) -latin1_swedish_ci 3 +latin1_swedish_ci 4 select collation(char(130)), coercibility(hex(130)); collation(char(130)) coercibility(hex(130)) -latin1_swedish_ci 3 +latin1_swedish_ci 4 select collation(format(130,10)), coercibility(format(130,10)); collation(format(130,10)) coercibility(format(130,10)) -latin1_swedish_ci 3 +latin1_swedish_ci 4 select collation(lcase(_latin2'a')), coercibility(lcase(_latin2'a')); collation(lcase(_latin2'a')) coercibility(lcase(_latin2'a')) -latin2_general_ci 3 +latin2_general_ci 4 select collation(ucase(_latin2'a')), coercibility(ucase(_latin2'a')); collation(ucase(_latin2'a')) coercibility(ucase(_latin2'a')) -latin2_general_ci 3 +latin2_general_ci 4 select collation(left(_latin2'a',1)), coercibility(left(_latin2'a',1)); collation(left(_latin2'a',1)) coercibility(left(_latin2'a',1)) -latin2_general_ci 3 +latin2_general_ci 4 select collation(right(_latin2'a',1)), coercibility(right(_latin2'a',1)); collation(right(_latin2'a',1)) coercibility(right(_latin2'a',1)) -latin2_general_ci 3 +latin2_general_ci 4 select collation(substring(_latin2'a',1,1)), coercibility(substring(_latin2'a',1,1)); collation(substring(_latin2'a',1,1)) coercibility(substring(_latin2'a',1,1)) -latin2_general_ci 3 +latin2_general_ci 4 select collation(concat(_latin2'a',_latin2'b')), coercibility(concat(_latin2'a',_latin2'b')); collation(concat(_latin2'a',_latin2'b')) coercibility(concat(_latin2'a',_latin2'b')) -latin2_general_ci 3 +latin2_general_ci 4 select collation(lpad(_latin2'a',4,_latin2'b')), coercibility(lpad(_latin2'a',4,_latin2'b')); collation(lpad(_latin2'a',4,_latin2'b')) coercibility(lpad(_latin2'a',4,_latin2'b')) -latin2_general_ci 3 +latin2_general_ci 4 select collation(rpad(_latin2'a',4,_latin2'b')), coercibility(rpad(_latin2'a',4,_latin2'b')); collation(rpad(_latin2'a',4,_latin2'b')) coercibility(rpad(_latin2'a',4,_latin2'b')) -latin2_general_ci 3 +latin2_general_ci 4 select collation(concat_ws(_latin2'a',_latin2'b')), coercibility(concat_ws(_latin2'a',_latin2'b')); collation(concat_ws(_latin2'a',_latin2'b')) coercibility(concat_ws(_latin2'a',_latin2'b')) -latin2_general_ci 3 +latin2_general_ci 4 select collation(make_set(255,_latin2'a',_latin2'b',_latin2'c')), coercibility(make_set(255,_latin2'a',_latin2'b',_latin2'c')); collation(make_set(255,_latin2'a',_latin2'b',_latin2'c')) coercibility(make_set(255,_latin2'a',_latin2'b',_latin2'c')) -latin2_general_ci 3 +latin2_general_ci 4 select collation(export_set(255,_latin2'y',_latin2'n',_latin2' ')), coercibility(export_set(255,_latin2'y',_latin2'n',_latin2' ')); collation(export_set(255,_latin2'y',_latin2'n',_latin2' ')) coercibility(export_set(255,_latin2'y',_latin2'n',_latin2' ')) -binary 3 +binary 4 select collation(trim(_latin2' a ')), coercibility(trim(_latin2' a ')); collation(trim(_latin2' a ')) coercibility(trim(_latin2' a ')) -latin2_general_ci 3 +latin2_general_ci 4 select collation(ltrim(_latin2' a ')), coercibility(ltrim(_latin2' a ')); collation(ltrim(_latin2' a ')) coercibility(ltrim(_latin2' a ')) -latin2_general_ci 3 +latin2_general_ci 4 select collation(rtrim(_latin2' a ')), coercibility(rtrim(_latin2' a ')); collation(rtrim(_latin2' a ')) coercibility(rtrim(_latin2' a ')) -latin2_general_ci 3 +latin2_general_ci 4 select collation(trim(LEADING _latin2' ' FROM _latin2'a')), coercibility(trim(LEADING _latin2'a' FROM _latin2'a')); collation(trim(LEADING _latin2' ' FROM _latin2'a')) coercibility(trim(LEADING _latin2'a' FROM _latin2'a')) -latin2_general_ci 3 +latin2_general_ci 4 select collation(trim(TRAILING _latin2' ' FROM _latin2'a')), coercibility(trim(TRAILING _latin2'a' FROM _latin2'a')); collation(trim(TRAILING _latin2' ' FROM _latin2'a')) coercibility(trim(TRAILING _latin2'a' FROM _latin2'a')) -latin2_general_ci 3 +latin2_general_ci 4 select collation(trim(BOTH _latin2' ' FROM _latin2'a')), coercibility(trim(BOTH _latin2'a' FROM _latin2'a')); collation(trim(BOTH _latin2' ' FROM _latin2'a')) coercibility(trim(BOTH _latin2'a' FROM _latin2'a')) -latin2_general_ci 3 +latin2_general_ci 4 select collation(repeat(_latin2'a',10)), coercibility(repeat(_latin2'a',10)); collation(repeat(_latin2'a',10)) coercibility(repeat(_latin2'a',10)) -latin2_general_ci 3 +latin2_general_ci 4 select collation(reverse(_latin2'ab')), coercibility(reverse(_latin2'ab')); collation(reverse(_latin2'ab')) coercibility(reverse(_latin2'ab')) -latin2_general_ci 3 +latin2_general_ci 4 select collation(quote(_latin2'ab')), coercibility(quote(_latin2'ab')); collation(quote(_latin2'ab')) coercibility(quote(_latin2'ab')) -latin2_general_ci 3 +latin2_general_ci 4 select collation(soundex(_latin2'ab')), coercibility(soundex(_latin2'ab')); collation(soundex(_latin2'ab')) coercibility(soundex(_latin2'ab')) -latin2_general_ci 3 +latin2_general_ci 4 select collation(substring(_latin2'ab',1)), coercibility(substring(_latin2'ab',1)); collation(substring(_latin2'ab',1)) coercibility(substring(_latin2'ab',1)) -latin2_general_ci 3 +latin2_general_ci 4 select collation(insert(_latin2'abcd',2,3,_latin2'ef')), coercibility(insert(_latin2'abcd',2,3,_latin2'ef')); collation(insert(_latin2'abcd',2,3,_latin2'ef')) coercibility(insert(_latin2'abcd',2,3,_latin2'ef')) -latin2_general_ci 3 +latin2_general_ci 4 select collation(replace(_latin2'abcd',_latin2'b',_latin2'B')), coercibility(replace(_latin2'abcd',_latin2'b',_latin2'B')); collation(replace(_latin2'abcd',_latin2'b',_latin2'B')) coercibility(replace(_latin2'abcd',_latin2'b',_latin2'B')) -latin2_general_ci 3 +latin2_general_ci 4 select collation(encode('abcd','ab')), coercibility(encode('abcd','ab')); collation(encode('abcd','ab')) coercibility(encode('abcd','ab')) -binary 3 +binary 4 create table t1 select bin(130), diff --git a/mysql-test/r/func_system.result b/mysql-test/r/func_system.result index d3db2cc5151..d0ac9d781a4 100644 --- a/mysql-test/r/func_system.result +++ b/mysql-test/r/func_system.result @@ -68,3 +68,11 @@ drop table t1; select TRUE,FALSE,NULL; TRUE FALSE NULL 1 0 NULL +create table t1 (a char(10)) character set latin1; +select * from t1 where a=version(); +a +select * from t1 where a=database(); +a +select * from t1 where a=user(); +a +drop table t1; diff --git a/mysql-test/r/type_blob.result b/mysql-test/r/type_blob.result index 8a0c74b3ae5..12eb2902966 100644 --- a/mysql-test/r/type_blob.result +++ b/mysql-test/r/type_blob.result @@ -499,7 +499,7 @@ charset(load_file('../../std_data/words.dat')), collation(load_file('../../std_data/words.dat')), coercibility(load_file('../../std_data/words.dat')); charset(load_file('../../std_data/words.dat')) collation(load_file('../../std_data/words.dat')) coercibility(load_file('../../std_data/words.dat')) -binary binary 3 +binary binary 4 explain extended select charset(load_file('../../std_data/words.dat')), collation(load_file('../../std_data/words.dat')), diff --git a/mysql-test/t/func_system.test b/mysql-test/t/func_system.test index a05b80ca56b..7fff165e057 100644 --- a/mysql-test/t/func_system.test +++ b/mysql-test/t/func_system.test @@ -30,3 +30,12 @@ show create table t1; drop table t1; select TRUE,FALSE,NULL; + +# +# Bug#8291 Illegal collation mix with USER() function +# +create table t1 (a char(10)) character set latin1; +select * from t1 where a=version(); +select * from t1 where a=database(); +select * from t1 where a=user(); +drop table t1; diff --git a/sql/item.cc b/sql/item.cc index 76cbaa99029..1293d2c94fe 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -384,7 +384,6 @@ void Item::split_sum_func2(THD *thd, Item **ref_pointer_array, */ bool DTCollation::aggregate(DTCollation &dt, uint flags) { - nagg++; if (!my_charset_same(collation, dt.collation)) { /* @@ -400,7 +399,6 @@ bool DTCollation::aggregate(DTCollation &dt, uint flags) else { set(dt); - strong= nagg; } } else if (dt.collation == &my_charset_bin) @@ -408,7 +406,6 @@ bool DTCollation::aggregate(DTCollation &dt, uint flags) if (dt.derivation <= derivation) { set(dt); - strong= nagg; } else ; // Do nothing @@ -424,20 +421,18 @@ bool DTCollation::aggregate(DTCollation &dt, uint flags) dt.collation->state & MY_CS_UNICODE) { set(dt); - strong= nagg; } else if ((flags & MY_COLL_ALLOW_COERCIBLE_CONV) && derivation < dt.derivation && - dt.derivation >= DERIVATION_COERCIBLE) + dt.derivation >= DERIVATION_SYSCONST) { // Do nothing; } else if ((flags & MY_COLL_ALLOW_COERCIBLE_CONV) && dt.derivation < derivation && - derivation >= DERIVATION_COERCIBLE) + derivation >= DERIVATION_SYSCONST) { set(dt); - strong= nagg; } else { @@ -453,7 +448,6 @@ bool DTCollation::aggregate(DTCollation &dt, uint flags) else if (dt.derivation < derivation) { set(dt); - strong= nagg; } else { diff --git a/sql/item.h b/sql/item.h index 2827be2d237..adc780677e1 100644 --- a/sql/item.h +++ b/sql/item.h @@ -31,8 +31,9 @@ void item_init(void); /* Init item functions */ enum Derivation { - DERIVATION_IGNORABLE= 4, - DERIVATION_COERCIBLE= 3, + DERIVATION_IGNORABLE= 5, + DERIVATION_COERCIBLE= 4, + DERIVATION_SYSCONST= 3, DERIVATION_IMPLICIT= 2, DERIVATION_NONE= 1, DERIVATION_EXPLICIT= 0 @@ -61,22 +62,16 @@ class DTCollation { public: CHARSET_INFO *collation; enum Derivation derivation; - uint nagg; // Total number of aggregated collations. - uint strong; // Number of the strongest collation. DTCollation() { collation= &my_charset_bin; derivation= DERIVATION_NONE; - nagg= 0; - strong= 0; } DTCollation(CHARSET_INFO *collation_arg, Derivation derivation_arg) { collation= collation_arg; derivation= derivation_arg; - nagg= 0; - strong= 0; } void set(DTCollation &dt) { @@ -102,6 +97,7 @@ public: case DERIVATION_IGNORABLE: return "IGNORABLE"; case DERIVATION_COERCIBLE: return "COERCIBLE"; case DERIVATION_IMPLICIT: return "IMPLICIT"; + case DERIVATION_SYSCONST: return "SYSCONST"; case DERIVATION_EXPLICIT: return "EXPLICIT"; case DERIVATION_NONE: return "NONE"; default: return "UNKNOWN"; diff --git a/sql/item_create.cc b/sql/item_create.cc index d959a6f393a..c0361c928be 100644 --- a/sql/item_create.cc +++ b/sql/item_create.cc @@ -441,7 +441,7 @@ Item *create_func_version(void) { return new Item_string(NullS,server_version, (uint) strlen(server_version), - system_charset_info, DERIVATION_IMPLICIT); + system_charset_info, DERIVATION_SYSCONST); } Item *create_func_weekday(Item* a) diff --git a/sql/item_func.cc b/sql/item_func.cc index 895740d2e5e..96250522c4a 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -79,8 +79,6 @@ bool Item_func::agg_arg_collations(DTCollation &c, Item **av, uint count, uint flags) { uint i; - c.nagg= 0; - c.strong= 0; c.set(av[0]->collation); for (i= 1; i < count; i++) { diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 0023d7b1f20..2f8d6dd822d 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -1509,6 +1509,23 @@ String *Item_func_decode::val_str(String *str) } +Item *Item_func_sysconst::safe_charset_converter(CHARSET_INFO *tocs) +{ + Item_string *conv; + uint conv_errors; + String tmp, cstr, *ostr= val_str(&tmp); + cstr.copy(ostr->ptr(), ostr->length(), ostr->charset(), tocs, &conv_errors); + if (conv_errors || !(conv= new Item_string(cstr.ptr(), cstr.length(), + cstr.charset(), + collation.derivation))) + { + return NULL; + } + conv->str_value.copy(); + return conv; +} + + String *Item_func_database::val_str(String *str) { DBUG_ASSERT(fixed == 1); diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index c1c0969672c..0c3ed32fb68 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -337,10 +337,18 @@ public: }; -class Item_func_database :public Item_str_func +class Item_func_sysconst :public Item_str_func { public: - Item_func_database() { collation.set(system_charset_info,DERIVATION_IMPLICIT); } + Item_func_sysconst() + { collation.set(system_charset_info,DERIVATION_SYSCONST); } + Item *safe_charset_converter(CHARSET_INFO *tocs); +}; + +class Item_func_database :public Item_func_sysconst +{ +public: + Item_func_database() :Item_func_sysconst() {} String *val_str(String *); void fix_length_and_dec() { @@ -350,10 +358,10 @@ public: const char *func_name() const { return "database"; } }; -class Item_func_user :public Item_str_func +class Item_func_user :public Item_func_sysconst { public: - Item_func_user() { collation.set(system_charset_info, DERIVATION_IMPLICIT); } + Item_func_user() :Item_func_sysconst() {} String *val_str(String *); void fix_length_and_dec() { |