From: Alexander Barkov Date: April 5 2011 9:15am Subject: bzr commit into mysql-trunk branch (alexander.barkov:3328) Bug#60625 Bug#11926811 List-Archive: http://lists.mysql.com/commits/134697 X-Bug: 60625,11926811 Message-Id: <201104050915.p359FKqo019445@bar.myoffice.izhnet.ru> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============8262924303047807818==" --===============8262924303047807818== MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline #At file:///home/bar/mysql-bzr/mysql-trunk.b60625/ based on revid:alfranio.correia@stripped 3328 Alexander Barkov 2011-04-05 Bug#11926811 / Bug#60625 Illegal mix of collations Problem: comparison of a DATETIME sp variable and NOW() lead to Illegal mix of collations error when character_set_connection=utf8. Introduced by "WL#2649 Number-to-string conversions". Error happened in Arg_comparator::set_compare_func(), because the first argument was errouneously converted to utf8, while the second argument was not. Fix: separate agg_arg_charsets_for_comparison() into two functions: - agg_arg_charsets_for_comparison() - for pure comparison, when we don't need to return any string result and therefore don't need to convert arguments to @@character_set_connection: SELECT a = b; - agg_arg_charsets_for_string_results_with_comparison() - when we need to return a string result, but we also need to do comparison internally: SELECT REPLACE(a,b,c) If all arguments are numbers: SELECT REPLACE(123,2,3) -> 133 we convert arguments to @@character_set_connection. @ mysql-test/include/ctype_numconv.inc @ mysql-test/r/ctype_binary.result @ mysql-test/r/ctype_cp1251.result @ mysql-test/r/ctype_latin1.result @ mysql-test/r/ctype_ucs.result @ mysql-test/r/ctype_utf8.result Adding tests @ sql/item.cc @ sql/item.h @ sql/item_func.cc @ sql/item_func.h @ sql/item_strfunc.cc Introducing and using new function agg_item_charsets_for_string_result_with_comparison() and its Item_func wrapper agg_arg_charsets_for_string_result_with_comparison(). modified: mysql-test/include/ctype_numconv.inc mysql-test/r/ctype_binary.result mysql-test/r/ctype_cp1251.result mysql-test/r/ctype_latin1.result mysql-test/r/ctype_ucs.result mysql-test/r/ctype_utf8.result sql/item.cc sql/item.h sql/item_func.cc sql/item_func.h sql/item_strfunc.cc === modified file 'mysql-test/include/ctype_numconv.inc' --- a/mysql-test/include/ctype_numconv.inc 2011-02-10 13:41:16 +0000 +++ b/mysql-test/include/ctype_numconv.inc 2011-04-05 09:04:24 +0000 @@ -1776,7 +1776,23 @@ SELECT HEX(DATE_SUB('2007-08-03 17:33:00', INTERVAL 1 MINUTE)) AS field1_str2, HEX(DATE_SUB(DATE('2007-08-03'), INTERVAL 1 DAY)) AS field_date, HEX(DATE_SUB(CAST('2007-08-03 17:33:00' AS DATETIME), INTERVAL 1 MINUTE)) AS field_datetime; - + +--echo # +--echo # Bug#11926811 / Bug#60625 Illegal mix of collations +--echo # +SELECT @@collation_connection; +DELIMITER //; +CREATE PROCEDURE p1() +BEGIN + DECLARE v_LastPaymentDate DATETIME DEFAULT NULL; + SELECT v_LastPaymentDate < NOW(); + EXPLAIN EXTENDED SELECT v_LastPaymentDate < NOW(); + SHOW WARNINGS; + EXPLAIN EXTENDED SELECT CONCAT(v_LastPaymentDate, NOW()); +END// +DELIMITER ;// +CALL p1; +DROP PROCEDURE p1; --echo # --echo # Bug#52159 returning time type from function and empty left join causes debug assertion @@ -1797,3 +1813,5 @@ SELECT maketime(`a`,`a`,`a`) FROM t1 GRO --enable_warnings DROP TABLE t1; SET sql_mode=default; + + === modified file 'mysql-test/r/ctype_binary.result' --- a/mysql-test/r/ctype_binary.result 2011-02-10 08:47:05 +0000 +++ b/mysql-test/r/ctype_binary.result 2011-04-05 09:04:24 +0000 @@ -2830,6 +2830,32 @@ HEX(DATE_SUB(CAST('2007-08-03 17:33:00' field_str1 field1_str2 field_date field_datetime 323030372D30382D30322032333A35393A3030 323030372D30382D30332031373A33323A3030 323030372D30382D3032 323030372D30382D30332031373A33323A3030 # +# Bug#11926811 / Bug#60625 Illegal mix of collations +# +SELECT @@collation_connection; +@@collation_connection +binary +CREATE PROCEDURE p1() +BEGIN +DECLARE v_LastPaymentDate DATETIME DEFAULT NULL; +SELECT v_LastPaymentDate < NOW(); +EXPLAIN EXTENDED SELECT v_LastPaymentDate < NOW(); +SHOW WARNINGS; +EXPLAIN EXTENDED SELECT CONCAT(v_LastPaymentDate, NOW()); +END// +CALL p1; +v_LastPaymentDate < NOW() +NULL +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select (v_LastPaymentDate@0 < now()) AS `v_LastPaymentDate < NOW()` +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Warnings: +Note 1003 select concat(v_LastPaymentDate@0,now()) AS `CONCAT(v_LastPaymentDate, NOW())` +DROP PROCEDURE p1; +# # Bug#52159 returning time type from function and empty left join causes debug assertion # CREATE FUNCTION f1() RETURNS TIME RETURN 1; === modified file 'mysql-test/r/ctype_cp1251.result' --- a/mysql-test/r/ctype_cp1251.result 2011-02-18 07:43:02 +0000 +++ b/mysql-test/r/ctype_cp1251.result 2011-04-05 09:04:24 +0000 @@ -3222,6 +3222,32 @@ HEX(DATE_SUB(CAST('2007-08-03 17:33:00' field_str1 field1_str2 field_date field_datetime 323030372D30382D30322032333A35393A3030 323030372D30382D30332031373A33323A3030 323030372D30382D3032 323030372D30382D30332031373A33323A3030 # +# Bug#11926811 / Bug#60625 Illegal mix of collations +# +SELECT @@collation_connection; +@@collation_connection +cp1251_general_ci +CREATE PROCEDURE p1() +BEGIN +DECLARE v_LastPaymentDate DATETIME DEFAULT NULL; +SELECT v_LastPaymentDate < NOW(); +EXPLAIN EXTENDED SELECT v_LastPaymentDate < NOW(); +SHOW WARNINGS; +EXPLAIN EXTENDED SELECT CONCAT(v_LastPaymentDate, NOW()); +END// +CALL p1; +v_LastPaymentDate < NOW() +NULL +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select (v_LastPaymentDate@0 < now()) AS `v_LastPaymentDate < NOW()` +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Warnings: +Note 1003 select concat(convert(v_LastPaymentDate@0 using cp1251),now()) AS `CONCAT(v_LastPaymentDate, NOW())` +DROP PROCEDURE p1; +# # Bug#52159 returning time type from function and empty left join causes debug assertion # CREATE FUNCTION f1() RETURNS TIME RETURN 1; === modified file 'mysql-test/r/ctype_latin1.result' --- a/mysql-test/r/ctype_latin1.result 2011-03-04 15:55:18 +0000 +++ b/mysql-test/r/ctype_latin1.result 2011-04-05 09:04:24 +0000 @@ -3249,6 +3249,32 @@ HEX(DATE_SUB(CAST('2007-08-03 17:33:00' field_str1 field1_str2 field_date field_datetime 323030372D30382D30322032333A35393A3030 323030372D30382D30332031373A33323A3030 323030372D30382D3032 323030372D30382D30332031373A33323A3030 # +# Bug#11926811 / Bug#60625 Illegal mix of collations +# +SELECT @@collation_connection; +@@collation_connection +latin1_swedish_ci +CREATE PROCEDURE p1() +BEGIN +DECLARE v_LastPaymentDate DATETIME DEFAULT NULL; +SELECT v_LastPaymentDate < NOW(); +EXPLAIN EXTENDED SELECT v_LastPaymentDate < NOW(); +SHOW WARNINGS; +EXPLAIN EXTENDED SELECT CONCAT(v_LastPaymentDate, NOW()); +END// +CALL p1; +v_LastPaymentDate < NOW() +NULL +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select (v_LastPaymentDate@0 < now()) AS `v_LastPaymentDate < NOW()` +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Warnings: +Note 1003 select concat(v_LastPaymentDate@0,now()) AS `CONCAT(v_LastPaymentDate, NOW())` +DROP PROCEDURE p1; +# # Bug#52159 returning time type from function and empty left join causes debug assertion # CREATE FUNCTION f1() RETURNS TIME RETURN 1; === modified file 'mysql-test/r/ctype_ucs.result' --- a/mysql-test/r/ctype_ucs.result 2011-03-04 14:59:32 +0000 +++ b/mysql-test/r/ctype_ucs.result 2011-04-05 09:04:24 +0000 @@ -4149,6 +4149,32 @@ HEX(DATE_SUB(CAST('2007-08-03 17:33:00' field_str1 field1_str2 field_date field_datetime 0032003000300037002D00300038002D00300032002000320033003A00350039003A00300030 0032003000300037002D00300038002D00300033002000310037003A00330032003A00300030 323030372D30382D3032 323030372D30382D30332031373A33323A3030 # +# Bug#11926811 / Bug#60625 Illegal mix of collations +# +SELECT @@collation_connection; +@@collation_connection +ucs2_general_ci +CREATE PROCEDURE p1() +BEGIN +DECLARE v_LastPaymentDate DATETIME DEFAULT NULL; +SELECT v_LastPaymentDate < NOW(); +EXPLAIN EXTENDED SELECT v_LastPaymentDate < NOW(); +SHOW WARNINGS; +EXPLAIN EXTENDED SELECT CONCAT(v_LastPaymentDate, NOW()); +END// +CALL p1; +v_LastPaymentDate < NOW() +NULL +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select (v_LastPaymentDate@0 < now()) AS `v_LastPaymentDate < NOW()` +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Warnings: +Note 1003 select concat(convert(v_LastPaymentDate@0 using ucs2),convert(now() using ucs2)) AS `CONCAT(v_LastPaymentDate, NOW())` +DROP PROCEDURE p1; +# # Bug#52159 returning time type from function and empty left join causes debug assertion # CREATE FUNCTION f1() RETURNS TIME RETURN 1; === modified file 'mysql-test/r/ctype_utf8.result' --- a/mysql-test/r/ctype_utf8.result 2011-03-04 15:55:18 +0000 +++ b/mysql-test/r/ctype_utf8.result 2011-04-05 09:04:24 +0000 @@ -5052,6 +5052,32 @@ HEX(DATE_SUB(CAST('2007-08-03 17:33:00' field_str1 field1_str2 field_date field_datetime 323030372D30382D30322032333A35393A3030 323030372D30382D30332031373A33323A3030 323030372D30382D3032 323030372D30382D30332031373A33323A3030 # +# Bug#11926811 / Bug#60625 Illegal mix of collations +# +SELECT @@collation_connection; +@@collation_connection +utf8_general_ci +CREATE PROCEDURE p1() +BEGIN +DECLARE v_LastPaymentDate DATETIME DEFAULT NULL; +SELECT v_LastPaymentDate < NOW(); +EXPLAIN EXTENDED SELECT v_LastPaymentDate < NOW(); +SHOW WARNINGS; +EXPLAIN EXTENDED SELECT CONCAT(v_LastPaymentDate, NOW()); +END// +CALL p1; +v_LastPaymentDate < NOW() +NULL +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Level Code Message +Note 1003 select (v_LastPaymentDate@0 < now()) AS `v_LastPaymentDate < NOW()` +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Warnings: +Note 1003 select concat(convert(v_LastPaymentDate@0 using utf8),now()) AS `CONCAT(v_LastPaymentDate, NOW())` +DROP PROCEDURE p1; +# # Bug#52159 returning time type from function and empty left join causes debug assertion # CREATE FUNCTION f1() RETURNS TIME RETURN 1; === modified file 'sql/item.cc' --- a/sql/item.cc 2011-04-04 08:47:25 +0000 +++ b/sql/item.cc 2011-04-05 09:04:24 +0000 @@ -1765,7 +1765,8 @@ bool agg_item_collations(DTCollation &c, } /* If all arguments where numbers, reset to @@collation_connection */ - if (c.derivation == DERIVATION_NUMERIC) + if (flags & MY_COLL_ALLOW_NUMERIC_CONV && + c.derivation == DERIVATION_NUMERIC) c.set(Item::default_charset(), DERIVATION_COERCIBLE, MY_REPERTOIRE_NUMERIC); return FALSE; === modified file 'sql/item.h' --- a/sql/item.h 2011-03-22 11:44:40 +0000 +++ b/sql/item.h 2011-04-05 09:04:24 +0000 @@ -49,6 +49,8 @@ char_to_byte_length_safe(uint32 char_len (i.e. constant). MY_COLL_ALLOW_CONV - allow any kind of conversion (combination of the above two) + MY_COLL_ALLOW_NUMERIC_CONV - if all items were numbers, convert to + @@character_set_connection MY_COLL_DISALLOW_NONE - don't allow return DERIVATION_NONE (e.g. when aggregating for comparison) MY_COLL_CMP_CONV - combination of MY_COLL_ALLOW_CONV @@ -58,6 +60,7 @@ char_to_byte_length_safe(uint32 char_len #define MY_COLL_ALLOW_SUPERSET_CONV 1 #define MY_COLL_ALLOW_COERCIBLE_CONV 2 #define MY_COLL_DISALLOW_NONE 4 +#define MY_COLL_ALLOW_NUMERIC_CONV 8 #define MY_COLL_ALLOW_CONV (MY_COLL_ALLOW_SUPERSET_CONV | MY_COLL_ALLOW_COERCIBLE_CONV) #define MY_COLL_CMP_CONV (MY_COLL_ALLOW_CONV | MY_COLL_DISALLOW_NONE) @@ -1609,7 +1612,8 @@ agg_item_charsets_for_string_result(DTCo int item_sep= 1) { uint flags= MY_COLL_ALLOW_SUPERSET_CONV | - MY_COLL_ALLOW_COERCIBLE_CONV; + MY_COLL_ALLOW_COERCIBLE_CONV | + MY_COLL_ALLOW_NUMERIC_CONV; return agg_item_charsets(c, name, items, nitems, flags, item_sep); } inline bool @@ -1622,6 +1626,19 @@ agg_item_charsets_for_comparison(DTColla MY_COLL_DISALLOW_NONE; return agg_item_charsets(c, name, items, nitems, flags, item_sep); } +inline bool +agg_item_charsets_for_string_result_with_comparison(DTCollation &c, + const char *name, + Item **items, uint nitems, + int item_sep= 1) +{ + uint flags= MY_COLL_ALLOW_SUPERSET_CONV | + MY_COLL_ALLOW_COERCIBLE_CONV | + MY_COLL_ALLOW_NUMERIC_CONV | + MY_COLL_DISALLOW_NONE; + return agg_item_charsets(c, name, items, nitems, flags, item_sep); +} + class Item_num: public Item_basic_constant { === modified file 'sql/item_func.cc' --- a/sql/item_func.cc 2011-03-28 13:38:03 +0000 +++ b/sql/item_func.cc 2011-04-05 09:04:24 +0000 @@ -2550,7 +2550,8 @@ void Item_func_min_max::fix_length_and_d } if (cmp_type == STRING_RESULT) { - agg_arg_charsets_for_comparison(collation, args, arg_count); + agg_arg_charsets_for_string_result_with_comparison(collation, + args, arg_count); if (datetime_found) { thd= current_thd; === modified file 'sql/item_func.h' --- a/sql/item_func.h 2011-03-22 11:44:40 +0000 +++ b/sql/item_func.h 2011-04-05 09:04:24 +0000 @@ -164,6 +164,11 @@ public: { return agg_item_charsets(c, func_name(), items, nitems, flags, item_sep); } + /* + Aggregate arguments for string result, e.g: CONCAT(a,b) + - convert to @@character_set_connection if all arguments are numbers + - allow DERIVATION_NONE + */ bool agg_arg_charsets_for_string_result(DTCollation &c, Item **items, uint nitems, int item_sep= 1) @@ -171,6 +176,11 @@ public: return agg_item_charsets_for_string_result(c, func_name(), items, nitems, item_sep); } + /* + Aggregate arguments for comparison, e.g: a=b, a LIKE b, a RLIKE b + - don't convert to @@character_set_connection if all arguments are numbers + - don't allow DERIVATION_NONE + */ bool agg_arg_charsets_for_comparison(DTCollation &c, Item **items, uint nitems, int item_sep= 1) @@ -178,6 +188,21 @@ public: return agg_item_charsets_for_comparison(c, func_name(), items, nitems, item_sep); } + /* + Aggregate arguments for string result, when some comparison + is involved internally, e.g: REPLACE(a,b,c) + - convert to @@character_set_connection if all arguments are numbers + - disallow DERIVATION_NONE + */ + bool agg_arg_charsets_for_string_result_with_comparison(DTCollation &c, + Item **items, + uint nitems, + int item_sep= 1) + { + return agg_item_charsets_for_string_result_with_comparison(c, func_name(), + items, nitems, + item_sep); + } bool walk(Item_processor processor, bool walk_subquery, uchar *arg); Item *transform(Item_transformer transformer, uchar *arg); Item* compile(Item_analyzer analyzer, uchar **arg_p, === modified file 'sql/item_strfunc.cc' --- a/sql/item_strfunc.cc 2011-03-24 10:37:16 +0000 +++ b/sql/item_strfunc.cc 2011-04-05 09:04:24 +0000 @@ -1261,7 +1261,7 @@ void Item_func_replace::fix_length_and_d char_length+= max_substrs * (uint) diff; } - if (agg_arg_charsets_for_comparison(collation, args, 3)) + if (agg_arg_charsets_for_string_result_with_comparison(collation, args, 3)) return; fix_char_length_ulonglong(char_length); } @@ -1551,7 +1551,7 @@ void Item_func_substr::fix_length_and_de void Item_func_substr_index::fix_length_and_dec() { - if (agg_arg_charsets_for_comparison(collation, args, 2)) + if (agg_arg_charsets_for_string_result_with_comparison(collation, args, 2)) return; fix_char_length(args[0]->max_char_length()); } @@ -1890,7 +1890,8 @@ void Item_func_trim::fix_length_and_dec( { // Handle character set for args[1] and args[0]. // Note that we pass args[1] as the first item, and args[0] as the second. - if (agg_arg_charsets_for_comparison(collation, &args[1], 2, -1)) + if (agg_arg_charsets_for_string_result_with_comparison(collation, + &args[1], 2, -1)) return; } fix_char_length(args[0]->max_char_length()); --===============8262924303047807818== MIME-Version: 1.0 Content-Type: text/bzr-bundle; charset="us-ascii"; name="bzr/alexander.barkov@stripped" Content-Transfer-Encoding: 7bit Content-Disposition: inline # Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: alexander.barkov@stripped\ # geq9dw50t4tco7jd # target_branch: file:///home/bar/mysql-bzr/mysql-trunk.b60625/ # testament_sha1: 8403ff56932ca37860fdc47317b4d03571b96bc1 # timestamp: 2011-04-05 13:15:20 +0400 # base_revision_id: alfranio.correia@stripped\ # 74vdhj8hw75d90x5 # # Begin bundle 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 X1bg --===============8262924303047807818==--