From 8a40e2e8f81508ba66f9b3e9bab7b1896fb8482d Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 10 Jun 2003 14:54:03 +0500 Subject: [PATCH 1/3] Some more functions work according to coercibility now: repeat, reverse, quote, soundex, substring Test func_str has been extended to check them --- mysql-test/r/func_str.result | 29 +++++++++++++++++++++++++++-- mysql-test/t/func_str.test | 13 ++++++++++++- sql/item_cmpfunc.h | 7 ------- sql/item_strfunc.cc | 5 ++++- sql/item_strfunc.h | 6 +++++- 5 files changed, 48 insertions(+), 12 deletions(-) diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result index c61563e6010..b6d9f512c1a 100644 --- a/mysql-test/r/func_str.result +++ b/mysql-test/r/func_str.result @@ -288,6 +288,21 @@ latin2_general_ci 3 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 +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 +select collation(reverse(_latin2'ab')), coercibility(reverse(_latin2'ab')); +collation(reverse(_latin2'ab')) coercibility(reverse(_latin2'ab')) +latin2_general_ci 3 +select collation(quote(_latin2'ab')), coercibility(quote(_latin2'ab')); +collation(quote(_latin2'ab')) coercibility(quote(_latin2'ab')) +latin2_general_ci 3 +select collation(soundex(_latin2'ab')), coercibility(soundex(_latin2'ab')); +collation(soundex(_latin2'ab')) coercibility(soundex(_latin2'ab')) +latin2_general_ci 3 +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 create table t1 select left(_latin2'a',1), @@ -302,7 +317,12 @@ ltrim(_latin2' a '), rtrim(_latin2' a '), trim(LEADING _latin2' ' FROM _latin2' a '), trim(TRAILING _latin2' ' FROM _latin2' a '), -trim(BOTH _latin2' ' FROM _latin2' a ') +trim(BOTH _latin2' ' FROM _latin2' a '), +repeat(_latin2'a',10), +reverse(_latin2'ab'), +quote(_latin2'ab'), +soundex(_latin2'ab'), +substring(_latin2'ab',1) ; show create table t1; Table Create Table @@ -319,6 +339,11 @@ t1 CREATE TABLE `t1` ( `rtrim(_latin2' a ')` char(3) character set latin2 NOT NULL default '', `trim(LEADING _latin2' ' FROM _latin2' a ')` char(3) character set latin2 NOT NULL default '', `trim(TRAILING _latin2' ' FROM _latin2' a ')` char(3) character set latin2 NOT NULL default '', - `trim(BOTH _latin2' ' FROM _latin2' a ')` char(3) character set latin2 NOT NULL default '' + `trim(BOTH _latin2' ' FROM _latin2' a ')` char(3) character set latin2 NOT NULL default '', + `repeat(_latin2'a',10)` char(10) character set latin2 NOT NULL default '', + `reverse(_latin2'ab')` char(2) character set latin2 NOT NULL default '', + `quote(_latin2'ab')` char(6) character set latin2 NOT NULL default '', + `soundex(_latin2'ab')` char(4) character set latin2 NOT NULL default '', + `substring(_latin2'ab',1)` char(2) character set latin2 NOT NULL default '' ) TYPE=MyISAM CHARSET=latin1 drop table t1; diff --git a/mysql-test/t/func_str.test b/mysql-test/t/func_str.test index d99b54d88ff..7bb83058281 100644 --- a/mysql-test/t/func_str.test +++ b/mysql-test/t/func_str.test @@ -149,6 +149,12 @@ select collation(rtrim(_latin2' a ')), coercibility(rtrim(_latin2' a ')); select collation(trim(LEADING _latin2' ' FROM _latin2'a')), coercibility(trim(LEADING _latin2'a' FROM _latin2'a')); select collation(trim(TRAILING _latin2' ' FROM _latin2'a')), coercibility(trim(TRAILING _latin2'a' FROM _latin2'a')); select collation(trim(BOTH _latin2' ' FROM _latin2'a')), coercibility(trim(BOTH _latin2'a' FROM _latin2'a')); +select collation(repeat(_latin2'a',10)), coercibility(repeat(_latin2'a',10)); +select collation(reverse(_latin2'ab')), coercibility(reverse(_latin2'ab')); +select collation(quote(_latin2'ab')), coercibility(quote(_latin2'ab')); +select collation(soundex(_latin2'ab')), coercibility(soundex(_latin2'ab')); +select collation(substring(_latin2'ab',1)), coercibility(substring(_latin2'ab',1)); + create table t1 select left(_latin2'a',1), @@ -163,7 +169,12 @@ select rtrim(_latin2' a '), trim(LEADING _latin2' ' FROM _latin2' a '), trim(TRAILING _latin2' ' FROM _latin2' a '), - trim(BOTH _latin2' ' FROM _latin2' a ') + trim(BOTH _latin2' ' FROM _latin2' a '), + repeat(_latin2'a',10), + reverse(_latin2'ab'), + quote(_latin2'ab'), + soundex(_latin2'ab'), + substring(_latin2'ab',1) ; show create table t1; diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 4438b902011..549839b4f96 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -263,13 +263,6 @@ class Item_func_strcmp :public Item_bool_func2 public: Item_func_strcmp(Item *a,Item *b) :Item_bool_func2(a,b) {} longlong val_int(); - void fix_length_and_dec() - { - max_length=2; - /* QQ: COERCIBILITY */ - cmp_charset= args[0]->binary() || args[1]->binary() ? - &my_charset_bin : args[0]->charset(); - } optimize_type select_optimize() const { return OPTIMIZE_NONE; } const char *func_name() const { return "strcmp"; } }; diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index e5b73e7670f..b9d44295f35 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -702,6 +702,7 @@ String *Item_func_reverse::val_str(String *str) void Item_func_reverse::fix_length_and_dec() { + set_charset(args[0]->charset(),args[0]->coercibility); max_length = args[0]->max_length; } @@ -1521,6 +1522,7 @@ String *Item_func_user::val_str(String *str) void Item_func_soundex::fix_length_and_dec() { + set_charset(args[0]->charset(), args[0]->coercibility); max_length=args[0]->max_length; set_if_bigger(max_length,4); } @@ -1552,7 +1554,7 @@ String *Item_func_soundex::val_str(String *str) { String *res =args[0]->val_str(str); char last_ch,ch; - CHARSET_INFO *cs= &my_charset_latin1; + CHARSET_INFO *cs= charset(); if ((null_value=args[0]->null_value)) return 0; /* purecov: inspected */ @@ -2538,6 +2540,7 @@ String *Item_func_quote::val_str(String *str) } *to= '\''; str->length(new_length); + str->set_charset(charset()); return str; null: diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index a70c9b39255..31d6c1fe89d 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -571,7 +571,11 @@ public: Item_func_quote(Item *a) :Item_str_func(a) {} const char *func_name() const { return "quote"; } String *val_str(String *); - void fix_length_and_dec() { max_length= args[0]->max_length * 2 + 2; } + void fix_length_and_dec() + { + set_charset(args[0]->charset(), args[0]->coercibility); + max_length= args[0]->max_length * 2 + 2; + } }; class Item_func_conv_charset :public Item_str_func From 54c04738a499578a18cdd9b72857962d964425de Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 10 Jun 2003 15:25:27 +0500 Subject: [PATCH 2/3] Coercibility tests for - equal predicate - LIKE predicate - strcmp() function --- mysql-test/r/func_test.result | 57 +++++++++++++++++++++++++++++++++++ mysql-test/t/func_test.test | 35 +++++++++++++++++++++ 2 files changed, 92 insertions(+) diff --git a/mysql-test/r/func_test.result b/mysql-test/r/func_test.result index d415b77692b..be0e3144fd6 100644 --- a/mysql-test/r/func_test.result +++ b/mysql-test/r/func_test.result @@ -52,6 +52,63 @@ select 10 % 7, 10 mod 7, 10 div 3; select (1 << 64)-1, ((1 << 64)-1) DIV 1, ((1 << 64)-1) DIV 2; (1 << 64)-1 ((1 << 64)-1) DIV 1 ((1 << 64)-1) DIV 2 18446744073709551615 18446744073709551615 9223372036854775807 +select _koi8r'a' = _koi8r'A'; +_koi8r'a' = _koi8r'A' +1 +select _koi8r'a' = _koi8r'A' COLLATE koi8r_general_ci; +_koi8r'a' = _koi8r'A' COLLATE koi8r_general_ci +1 +select _koi8r'a' = _koi8r'A' COLLATE koi8r_bin; +_koi8r'a' = _koi8r'A' COLLATE koi8r_bin +0 +select _koi8r'a' COLLATE koi8r_general_ci = _koi8r'A'; +_koi8r'a' COLLATE koi8r_general_ci = _koi8r'A' +1 +select _koi8r'a' COLLATE koi8r_bin = _koi8r'A'; +_koi8r'a' COLLATE koi8r_bin = _koi8r'A' +0 +select _koi8r'a' COLLATE koi8r_bin = _koi8r'A' COLLATE koi8r_general_ci; +ERROR HY000: Illegal mix of collations (koi8r_bin,EXPLICIT) and (koi8r_general_ci,EXPLICIT) for operation '=' +select _koi8r'a' = _latin1'A'; +ERROR HY000: Illegal mix of collations (koi8r_general_ci,COERCIBLE) and (latin1_swedish_ci,COERCIBLE) for operation '=' +select strcmp(_koi8r'a', _koi8r'A'); +strcmp(_koi8r'a', _koi8r'A') +0 +select strcmp(_koi8r'a', _koi8r'A' COLLATE koi8r_general_ci); +strcmp(_koi8r'a', _koi8r'A' COLLATE koi8r_general_ci) +0 +select strcmp(_koi8r'a', _koi8r'A' COLLATE koi8r_bin); +strcmp(_koi8r'a', _koi8r'A' COLLATE koi8r_bin) +1 +select strcmp(_koi8r'a' COLLATE koi8r_general_ci, _koi8r'A'); +strcmp(_koi8r'a' COLLATE koi8r_general_ci, _koi8r'A') +0 +select strcmp(_koi8r'a' COLLATE koi8r_bin, _koi8r'A'); +strcmp(_koi8r'a' COLLATE koi8r_bin, _koi8r'A') +1 +select strcmp(_koi8r'a' COLLATE koi8r_general_ci, _koi8r'A' COLLATE koi8r_bin); +ERROR HY000: Illegal mix of collations (koi8r_general_ci,EXPLICIT) and (koi8r_bin,EXPLICIT) for operation 'strcmp' +select strcmp(_koi8r'a', _latin1'A'); +ERROR HY000: Illegal mix of collations (koi8r_general_ci,COERCIBLE) and (latin1_swedish_ci,COERCIBLE) for operation 'strcmp' +select _koi8r'a' LIKE _koi8r'A'; +_koi8r'a' LIKE _koi8r'A' +1 +select _koi8r'a' LIKE _koi8r'A' COLLATE koi8r_general_ci; +_koi8r'a' LIKE _koi8r'A' COLLATE koi8r_general_ci +1 +select _koi8r'a' LIKE _koi8r'A' COLLATE koi8r_bin; +_koi8r'a' LIKE _koi8r'A' COLLATE koi8r_bin +0 +select _koi8r'a' COLLATE koi8r_general_ci LIKE _koi8r'A'; +_koi8r'a' COLLATE koi8r_general_ci LIKE _koi8r'A' +1 +select _koi8r'a' COLLATE koi8r_bin LIKE _koi8r'A'; +_koi8r'a' COLLATE koi8r_bin LIKE _koi8r'A' +0 +select _koi8r'a' COLLATE koi8r_general_ci LIKE _koi8r'A' COLLATE koi8r_bin; +ERROR HY000: Illegal mix of collations (koi8r_general_ci,EXPLICIT) and (koi8r_bin,EXPLICIT) for operation 'like' +select _koi8r'a' LIKE _latin1'A'; +ERROR HY000: Illegal mix of collations (koi8r_general_ci,COERCIBLE) and (latin1_swedish_ci,COERCIBLE) for operation 'like' select 5 between 0 and 10 between 0 and 1,(5 between 0 and 10) between 0 and 1; 5 between 0 and 10 between 0 and 1 (5 between 0 and 10) between 0 and 1 0 1 diff --git a/mysql-test/t/func_test.test b/mysql-test/t/func_test.test index bdf58ee4b15..2834d5bd9c7 100644 --- a/mysql-test/t/func_test.test +++ b/mysql-test/t/func_test.test @@ -20,6 +20,41 @@ select 1 XOR 1, 1 XOR 0, 0 XOR 1, 0 XOR 0, NULL XOR 1, 1 XOR NULL, 0 XOR NULL; select 10 % 7, 10 mod 7, 10 div 3; select (1 << 64)-1, ((1 << 64)-1) DIV 1, ((1 << 64)-1) DIV 2; +# +# Coercibility +# +select _koi8r'a' = _koi8r'A'; +select _koi8r'a' = _koi8r'A' COLLATE koi8r_general_ci; +select _koi8r'a' = _koi8r'A' COLLATE koi8r_bin; +select _koi8r'a' COLLATE koi8r_general_ci = _koi8r'A'; +select _koi8r'a' COLLATE koi8r_bin = _koi8r'A'; +--error 1265 +select _koi8r'a' COLLATE koi8r_bin = _koi8r'A' COLLATE koi8r_general_ci; +--error 1265 +select _koi8r'a' = _latin1'A'; + +select strcmp(_koi8r'a', _koi8r'A'); +select strcmp(_koi8r'a', _koi8r'A' COLLATE koi8r_general_ci); +select strcmp(_koi8r'a', _koi8r'A' COLLATE koi8r_bin); +select strcmp(_koi8r'a' COLLATE koi8r_general_ci, _koi8r'A'); +select strcmp(_koi8r'a' COLLATE koi8r_bin, _koi8r'A'); +--error 1265 +select strcmp(_koi8r'a' COLLATE koi8r_general_ci, _koi8r'A' COLLATE koi8r_bin); +--error 1265 +select strcmp(_koi8r'a', _latin1'A'); + +select _koi8r'a' LIKE _koi8r'A'; +select _koi8r'a' LIKE _koi8r'A' COLLATE koi8r_general_ci; +select _koi8r'a' LIKE _koi8r'A' COLLATE koi8r_bin; +select _koi8r'a' COLLATE koi8r_general_ci LIKE _koi8r'A'; +select _koi8r'a' COLLATE koi8r_bin LIKE _koi8r'A'; +--error 1265 +select _koi8r'a' COLLATE koi8r_general_ci LIKE _koi8r'A' COLLATE koi8r_bin; +--error 1265 +select _koi8r'a' LIKE _latin1'A'; + + + # # Wrong usage of functions # From 7b93f3850526d3a44adf8f65fcfbbd74b46349ff Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 10 Jun 2003 16:41:42 +0500 Subject: [PATCH 3/3] Function INSERT() now works according to coercibility rules Test for INSERT() has been added --- mysql-test/r/func_str.result | 9 +++++++-- mysql-test/t/func_str.test | 4 +++- sql/item_strfunc.cc | 8 ++++++++ 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result index b6d9f512c1a..ffb7f2cd911 100644 --- a/mysql-test/r/func_str.result +++ b/mysql-test/r/func_str.result @@ -303,6 +303,9 @@ latin2_general_ci 3 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 +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 create table t1 select left(_latin2'a',1), @@ -322,7 +325,8 @@ repeat(_latin2'a',10), reverse(_latin2'ab'), quote(_latin2'ab'), soundex(_latin2'ab'), -substring(_latin2'ab',1) +substring(_latin2'ab',1), +insert(_latin2'abcd',2,3,_latin2'ef') ; show create table t1; Table Create Table @@ -344,6 +348,7 @@ t1 CREATE TABLE `t1` ( `reverse(_latin2'ab')` char(2) character set latin2 NOT NULL default '', `quote(_latin2'ab')` char(6) character set latin2 NOT NULL default '', `soundex(_latin2'ab')` char(4) character set latin2 NOT NULL default '', - `substring(_latin2'ab',1)` char(2) character set latin2 NOT NULL default '' + `substring(_latin2'ab',1)` char(2) character set latin2 NOT NULL default '', + `insert(_latin2'abcd',2,3,_latin2'ef')` char(6) character set latin2 NOT NULL default '' ) TYPE=MyISAM CHARSET=latin1 drop table t1; diff --git a/mysql-test/t/func_str.test b/mysql-test/t/func_str.test index 7bb83058281..93e35efa455 100644 --- a/mysql-test/t/func_str.test +++ b/mysql-test/t/func_str.test @@ -154,6 +154,7 @@ select collation(reverse(_latin2'ab')), coercibility(reverse(_latin2'ab')); select collation(quote(_latin2'ab')), coercibility(quote(_latin2'ab')); select collation(soundex(_latin2'ab')), coercibility(soundex(_latin2'ab')); select collation(substring(_latin2'ab',1)), coercibility(substring(_latin2'ab',1)); +select collation(insert(_latin2'abcd',2,3,_latin2'ef')), coercibility(insert(_latin2'abcd',2,3,_latin2'ef')); create table t1 select @@ -174,7 +175,8 @@ select reverse(_latin2'ab'), quote(_latin2'ab'), soundex(_latin2'ab'), - substring(_latin2'ab',1) + substring(_latin2'ab',1), + insert(_latin2'abcd',2,3,_latin2'ef') ; show create table t1; diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index b9d44295f35..d660f7c472c 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -861,6 +861,14 @@ null: void Item_func_insert::fix_length_and_dec() { + if (set_charset(args[0]->charset(), args[0]->coercibility, + args[3]->charset(), args[3]->coercibility)) + { + my_error(ER_CANT_AGGREGATE_COLLATIONS,MYF(0), + args[0]->charset()->name,coercion_name(args[0]->coercibility), + args[3]->charset()->name,coercion_name(args[3]->coercibility), + func_name()); + } max_length=args[0]->max_length+args[3]->max_length; if (max_length > MAX_BLOB_WIDTH) {