From aa1002a35cefcc1851cbfb6b6b60463bda6f9aa3 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Wed, 2 Sep 2015 08:20:49 +0400 Subject: [PATCH] MDEV-8723 Wrong result for SELECT..WHERE COLLATION(a)='binary' AND a='a' --- mysql-test/r/ctype_binary.result | 38 ++++++++++++++++++++++++++++++++ mysql-test/t/ctype_binary.test | 15 +++++++++++++ sql/item_func.h | 3 +++ sql/item_strfunc.h | 36 +++++++++++++++++++----------- 4 files changed, 79 insertions(+), 13 deletions(-) diff --git a/mysql-test/r/ctype_binary.result b/mysql-test/r/ctype_binary.result index 7e73c294b42..2dbf783ff27 100644 --- a/mysql-test/r/ctype_binary.result +++ b/mysql-test/r/ctype_binary.result @@ -3101,5 +3101,43 @@ Warnings: Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` = 'a ') DROP TABLE t1; # +# MDEV-8723 Wrong result for SELECT..WHERE COLLATION(a)='binary' AND a='a' +# +CREATE TABLE t1 (a VARBINARY(10)); +INSERT INTO t1 VALUES ('a'),('A'); +SELECT * FROM t1 WHERE COLLATION(a)='binary' AND a='a'; +a +a +SELECT * FROM t1 WHERE CHARSET(a)='binary' AND a='a'; +a +a +SELECT * FROM t1 WHERE COERCIBILITY(a)=2 AND a='a'; +a +a +SELECT * FROM t1 WHERE WEIGHT_STRING(a)='a' AND a='a'; +a +a +EXPLAIN EXTENDED SELECT * FROM t1 WHERE COLLATION(a)='binary' AND a='a'; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where +Warnings: +Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` = 'a') +EXPLAIN EXTENDED SELECT * FROM t1 WHERE CHARSET(a)='binary' AND a='a'; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where +Warnings: +Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` = 'a') +EXPLAIN EXTENDED SELECT * FROM t1 WHERE COERCIBILITY(a)=2 AND a='a'; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where +Warnings: +Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` = 'a') +EXPLAIN EXTENDED SELECT * FROM t1 WHERE WEIGHT_STRING(a)='a' AND a='a'; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where +Warnings: +Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where ((`test`.`t1`.`a` = 'a') and (weight_string(`test`.`t1`.`a`) = 'a')) +DROP TABLE t1; +# # End of 10.1 tests # diff --git a/mysql-test/t/ctype_binary.test b/mysql-test/t/ctype_binary.test index cb9d810e1a9..8da4eaff572 100644 --- a/mysql-test/t/ctype_binary.test +++ b/mysql-test/t/ctype_binary.test @@ -56,6 +56,21 @@ SELECT * FROM t1 WHERE a='a ' AND LENGTH(a)=2; EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='a ' AND LENGTH(a)=2; DROP TABLE t1; +--echo # +--echo # MDEV-8723 Wrong result for SELECT..WHERE COLLATION(a)='binary' AND a='a' +--echo # +CREATE TABLE t1 (a VARBINARY(10)); +INSERT INTO t1 VALUES ('a'),('A'); +SELECT * FROM t1 WHERE COLLATION(a)='binary' AND a='a'; +SELECT * FROM t1 WHERE CHARSET(a)='binary' AND a='a'; +SELECT * FROM t1 WHERE COERCIBILITY(a)=2 AND a='a'; +SELECT * FROM t1 WHERE WEIGHT_STRING(a)='a' AND a='a'; +EXPLAIN EXTENDED SELECT * FROM t1 WHERE COLLATION(a)='binary' AND a='a'; +EXPLAIN EXTENDED SELECT * FROM t1 WHERE CHARSET(a)='binary' AND a='a'; +EXPLAIN EXTENDED SELECT * FROM t1 WHERE COERCIBILITY(a)=2 AND a='a'; +EXPLAIN EXTENDED SELECT * FROM t1 WHERE WEIGHT_STRING(a)='a' AND a='a'; +DROP TABLE t1; + --echo # --echo # End of 10.1 tests --echo # diff --git a/sql/item_func.h b/sql/item_func.h index 676b818baf8..d5ae2668cde 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -1160,6 +1160,9 @@ public: const char *func_name() const { return "coercibility"; } void fix_length_and_dec() { max_length=10; maybe_null= 0; } table_map not_null_tables() const { return 0; } + Item* propagate_equal_fields(THD *thd, const Context &ctx, COND_EQUAL *cond) + { return this; } + bool const_item() const { return true; } }; class Item_func_locate :public Item_int_func diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index cba91bb9f00..e7d509206f2 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -1049,12 +1049,11 @@ public: } }; -class Item_func_charset :public Item_str_func + +class Item_func_expr_str_metadata :public Item_str_func { public: - Item_func_charset(THD *thd, Item *a): Item_str_func(thd, a) {} - String *val_str(String *); - const char *func_name() const { return "charset"; } + Item_func_expr_str_metadata(THD *thd, Item *a): Item_str_func(thd, a) { } void fix_length_and_dec() { collation.set(system_charset_info); @@ -1062,23 +1061,32 @@ public: maybe_null= 0; }; table_map not_null_tables() const { return 0; } + Item* propagate_equal_fields(THD *thd, const Context &ctx, COND_EQUAL *cond) + { return this; } + bool const_item() const { return true; } }; -class Item_func_collation :public Item_str_func + +class Item_func_charset :public Item_func_expr_str_metadata { public: - Item_func_collation(THD *thd, Item *a): Item_str_func(thd, a) {} + Item_func_charset(THD *thd, Item *a) + :Item_func_expr_str_metadata(thd, a) { } + String *val_str(String *); + const char *func_name() const { return "charset"; } +}; + + +class Item_func_collation :public Item_func_expr_str_metadata +{ +public: + Item_func_collation(THD *thd, Item *a) + :Item_func_expr_str_metadata(thd, a) {} String *val_str(String *); const char *func_name() const { return "collation"; } - void fix_length_and_dec() - { - collation.set(system_charset_info); - max_length= 64 * collation.collation->mbmaxlen; // should be enough - maybe_null= 0; - }; - table_map not_null_tables() const { return 0; } }; + class Item_func_weight_string :public Item_str_func { String tmp_value; @@ -1106,6 +1114,8 @@ public: this->nweights == that->nweights && this->result_length == that->result_length; } + Item* propagate_equal_fields(THD *thd, const Context &ctx, COND_EQUAL *cond) + { return this; } }; class Item_func_crc32 :public Item_int_func