diff options
-rw-r--r-- | mysql-test/r/func_str.result | 29 | ||||
-rw-r--r-- | mysql-test/t/func_str.test | 17 | ||||
-rw-r--r-- | sql/item_cmpfunc.cc | 49 | ||||
-rw-r--r-- | sql/item_cmpfunc.h | 7 |
4 files changed, 68 insertions, 34 deletions
diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result index 34c7752798d..2865a019f4b 100644 --- a/mysql-test/r/func_str.result +++ b/mysql-test/r/func_str.result @@ -1,4 +1,5 @@ drop table if exists t1; +set names latin1; select 'hello',"'hello'",'""hello""','''h''e''l''l''o''',"hel""lo",'hel\'lo'; hello 'hello' ""hello"" 'h'e'l'l'o' hel"lo hel'lo hello 'hello' ""hello"" 'h'e'l'l'o' hel"lo hel'lo @@ -249,6 +250,34 @@ INSERT INTO t1 VALUES (1, 'a545f661efdd1fb66fdee3aab79945bf'); SELECT 1 FROM t1 WHERE tmp=AES_DECRYPT(tmp,"password"); 1 DROP TABLE t1; +select 1=_latin1'1'; +1=_latin1'1' +1 +select _latin1'1'=1; +_latin1'1'=1 +1 +select _latin2'1'=1; +_latin2'1'=1 +1 +select 1=_latin2'1'; +1=_latin2'1' +1 +select _latin1'1'=_latin2'1'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (latin2_general_ci,COERCIBLE) for operation '=' +select row('a','b','c') = row('a','b','c'); +row('a','b','c') = row('a','b','c') +1 +select row('A','b','c') = row('a','b','c'); +row('A','b','c') = row('a','b','c') +1 +select row('A' COLLATE latin1_bin,'b','c') = row('a','b','c'); +row('A' COLLATE latin1_bin,'b','c') = row('a','b','c') +0 +select row('A','b','c') = row('a' COLLATE latin1_bin,'b','c'); +row('A','b','c') = row('a' COLLATE latin1_bin,'b','c') +0 +select row('A' COLLATE latin1_general_ci,'b','c') = row('a' COLLATE latin1_bin,'b','c'); +ERROR HY000: Illegal mix of collations (latin1_general_ci,EXPLICIT) and (latin1_bin,EXPLICIT) for operation '=' select POSITION(_latin1'B' IN _latin1'abcd'); POSITION(_latin1'B' IN _latin1'abcd') 2 diff --git a/mysql-test/t/func_str.test b/mysql-test/t/func_str.test index a898d3551d7..7dc08dece55 100644 --- a/mysql-test/t/func_str.test +++ b/mysql-test/t/func_str.test @@ -8,6 +8,8 @@ drop table if exists t1; --enable_warnings +set names latin1; + select 'hello',"'hello'",'""hello""','''h''e''l''l''o''',"hel""lo",'hel\'lo'; select 'hello' 'monty'; select length('\n\t\r\b\0\_\%\\'); @@ -136,6 +138,21 @@ DROP TABLE t1; # # Test collation and coercibility # + +select 1=_latin1'1'; +select _latin1'1'=1; +select _latin2'1'=1; +select 1=_latin2'1'; +--error 1265 +select _latin1'1'=_latin2'1'; +select row('a','b','c') = row('a','b','c'); +select row('A','b','c') = row('a','b','c'); +select row('A' COLLATE latin1_bin,'b','c') = row('a','b','c'); +select row('A','b','c') = row('a' COLLATE latin1_bin,'b','c'); +--error 1265 +select row('A' COLLATE latin1_general_ci,'b','c') = row('a' COLLATE latin1_bin,'b','c'); + + select POSITION(_latin1'B' IN _latin1'abcd'); select POSITION(_latin1'B' IN _latin1'abcd' COLLATE latin1_bin); select POSITION(_latin1'B' COLLATE latin1_bin IN _latin1'abcd'); diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index a19311cd2fe..11a6e6604bf 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -109,15 +109,6 @@ static bool convert_constant_item(Field *field, Item **item) } -bool Item_bool_func2::fix_fields(THD *thd, struct st_table_list *tables, - Item ** ref) -{ - if (Item_int_func::fix_fields(thd, tables, ref)) - return 1; - return 0; -} - - void Item_bool_func2::fix_length_and_dec() { max_length= 1; // Function returns 0 or 1 @@ -191,8 +182,6 @@ void Item_bool_func2::fix_length_and_dec() { cmp.set_cmp_func(this, tmp_arg, tmp_arg+1, INT_RESULT); // Works for all types. - cmp_collation.set(&my_charset_bin, - DERIVATION_NONE); // For test in fix_fields return; } } @@ -206,23 +195,11 @@ void Item_bool_func2::fix_length_and_dec() { cmp.set_cmp_func(this, tmp_arg, tmp_arg+1, INT_RESULT); // Works for all types. - cmp_collation.set(&my_charset_bin, - DERIVATION_NONE); // For test in fix_fields return; } } } set_cmp_func(); - /* - We must set cmp_charset here as we may be called from for an automatic - generated item, like in natural join - */ - if (cmp_collation.set(args[0]->collation, args[1]->collation)) - { - /* set_cmp_charset() failed */ - my_coll_agg_error(args[0]->collation, args[1]->collation, func_name()); - return; - } } @@ -252,6 +229,18 @@ int Arg_comparator::set_compare_func(Item_bool_func2 *item, Item_result type) comparators[i].set_cmp_func(owner, (*a)->addr(i), (*b)->addr(i)); } } + else if (type == STRING_RESULT) + { + /* + We must set cmp_charset here as we may be called from for an automatic + generated item, like in natural join + */ + if (cmp_collation.set((*a)->collation, (*b)->collation)) + { + my_coll_agg_error((*a)->collation, (*b)->collation, owner->func_name()); + return 1; + } + } return 0; } @@ -264,7 +253,7 @@ int Arg_comparator::compare_string() if ((res2= (*b)->val_str(&owner->tmp_value2))) { owner->null_value= 0; - return sortcmp(res1,res2,owner->cmp_collation.collation); + return sortcmp(res1,res2,cmp_collation.collation); } } owner->null_value= 1; @@ -278,7 +267,7 @@ int Arg_comparator::compare_e_string() res2= (*b)->val_str(&owner->tmp_value2); if (!res1 || !res2) return test(res1 == res2); - return test(sortcmp(res1, res2, owner->cmp_collation.collation) == 0); + return test(sortcmp(res1, res2, cmp_collation.collation) == 0); } @@ -502,7 +491,7 @@ longlong Item_func_strcmp::val_int() null_value=1; return 0; } - int value= sortcmp(a,b,cmp_collation.collation); + int value= sortcmp(a,b,cmp.cmp_collation.collation); null_value=0; return !value ? 0 : (value < 0 ? (longlong) -1 : (longlong) 1); } @@ -1893,7 +1882,7 @@ longlong Item_func_like::val_int() null_value=0; if (canDoTurboBM) return turboBM_matches(res->ptr(), res->length()) ? 1 : 0; - return my_wildcmp(cmp_collation.collation, + return my_wildcmp(cmp.cmp_collation.collation, res->ptr(),res->ptr()+res->length(), res2->ptr(),res2->ptr()+res2->length(), escape,wild_one,wild_many) ? 0 : 1; @@ -2103,7 +2092,7 @@ void Item_func_like::turboBM_compute_suffixes(int *suff) *splm1 = pattern_len; - if (cmp_collation.collation == &my_charset_bin) + if (cmp.cmp_collation.collation == &my_charset_bin) { int i; for (i = pattern_len - 2; i >= 0; i--) @@ -2206,7 +2195,7 @@ void Item_func_like::turboBM_compute_bad_character_shifts() for (i = bmBc; i < end; i++) *i = pattern_len; - if (cmp_collation.collation == &my_charset_bin) + if (cmp.cmp_collation.collation == &my_charset_bin) { for (j = 0; j < plm1; j++) bmBc[(uint) (uchar) pattern[j]] = plm1 - j; @@ -2237,7 +2226,7 @@ bool Item_func_like::turboBM_matches(const char* text, int text_len) const const int tlmpl= text_len - pattern_len; /* Searching */ - if (cmp_collation.collation == &my_charset_bin) + if (cmp.cmp_collation.collation == &my_charset_bin) { while (j <= tlmpl) { diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 1d93c9b6892..8309cd25a72 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -35,6 +35,8 @@ class Arg_comparator: public Sql_alloc Arg_comparator *comparators; // used only for compare_row() public: + DTCollation cmp_collation; + Arg_comparator() {}; Arg_comparator(Item **a1, Item **a2): a(a1), b(a2) {}; @@ -112,13 +114,10 @@ class Item_bool_func2 :public Item_int_func protected: Arg_comparator cmp; String tmp_value1,tmp_value2; - DTCollation cmp_collation; public: Item_bool_func2(Item *a,Item *b): - Item_int_func(a,b), cmp(tmp_arg, tmp_arg+1) - { cmp_collation.set(0,DERIVATION_NONE);} - bool fix_fields(THD *thd, TABLE_LIST *tlist, Item ** ref); + Item_int_func(a,b), cmp(tmp_arg, tmp_arg+1) {} void fix_length_and_dec(); void set_cmp_func() { |