From d1ca1c1faeb1e43df1533a10dfa0ac79433227f9 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Sun, 2 Nov 2014 01:08:09 +0400 Subject: [PATCH] MDEV-7001 Bad result for NOT NOT STRCMP('a','b') and NOT NOT NULLIF(2,3) The bug is not very important per se, but it was helpful to move Item_func_strcmp out of Item_bool_func2 (to Item_int_func), for the purposes of "MDEV-4912 Add a plugin to field types (column types)". --- mysql-test/r/func_test.result | 17 +++++++++++++++++ mysql-test/r/null.result | 12 ++++++++++++ mysql-test/t/func_test.test | 14 ++++++++++++++ mysql-test/t/null.test | 13 +++++++++++++ sql/item.h | 6 ++++++ sql/item_cmpfunc.cc | 6 +++--- sql/item_cmpfunc.h | 16 +++++++--------- 7 files changed, 72 insertions(+), 12 deletions(-) diff --git a/mysql-test/r/func_test.result b/mysql-test/r/func_test.result index 2c1c416472f..97ef61047a5 100644 --- a/mysql-test/r/func_test.result +++ b/mysql-test/r/func_test.result @@ -320,3 +320,20 @@ id select_type table type possible_keys key key_len ref rows filtered Extra Warnings: Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (not((`test`.`t1`.`a` + 0))) drop table t1; +# +# Start of 10.0 tests +# +# +# MDEV-7001 Bad result for NOT NOT STRCMP('a','b') and NOT NOT NULLIF(2,3) +# +SELECT NOT NOT strcmp('a','b'); +NOT NOT strcmp('a','b') +1 +EXPLAIN EXTENDED SELECT NOT NOT strcmp('a','b'); +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 (strcmp('a','b') <> 0) AS `NOT NOT strcmp('a','b')` +# +# End of 10.0 tests +# diff --git a/mysql-test/r/null.result b/mysql-test/r/null.result index ce233e0db23..b5219333ef1 100644 --- a/mysql-test/r/null.result +++ b/mysql-test/r/null.result @@ -382,3 +382,15 @@ CREATE TABLE t2 (d DATE) ENGINE=MyISAM; SELECT * FROM t1,t2 WHERE 1 IS NOT NULL AND t1.b IS NULL; a b c d DROP TABLE t1,t2; +# +# Start of 10.0 tests +# +# +# MDEV-7001 Bad result for NOT NOT STRCMP('a','b') and NOT NOT NULLIF(2,3) +# +SELECT NOT NOT NULLIF(2,3); +NOT NOT NULLIF(2,3) +1 +# +# End of 10.0 tests +# diff --git a/mysql-test/t/func_test.test b/mysql-test/t/func_test.test index 6a99b975e81..d3703de26c5 100644 --- a/mysql-test/t/func_test.test +++ b/mysql-test/t/func_test.test @@ -180,3 +180,17 @@ select * from t1 where not (a+0); explain extended select * from t1 where not (a+0); drop table t1; + +--echo # +--echo # Start of 10.0 tests +--echo # + +--echo # +--echo # MDEV-7001 Bad result for NOT NOT STRCMP('a','b') and NOT NOT NULLIF(2,3) +--echo # +SELECT NOT NOT strcmp('a','b'); +EXPLAIN EXTENDED SELECT NOT NOT strcmp('a','b'); + +--echo # +--echo # End of 10.0 tests +--echo # diff --git a/mysql-test/t/null.test b/mysql-test/t/null.test index 81951a9ce68..40f66946822 100644 --- a/mysql-test/t/null.test +++ b/mysql-test/t/null.test @@ -295,3 +295,16 @@ CREATE TABLE t2 (d DATE) ENGINE=MyISAM; SELECT * FROM t1,t2 WHERE 1 IS NOT NULL AND t1.b IS NULL; DROP TABLE t1,t2; + +--echo # +--echo # Start of 10.0 tests +--echo # + +--echo # +--echo # MDEV-7001 Bad result for NOT NOT STRCMP('a','b') and NOT NOT NULLIF(2,3) +--echo # +SELECT NOT NOT NULLIF(2,3); + +--echo # +--echo # End of 10.0 tests +--echo # diff --git a/sql/item.h b/sql/item.h index 22d147028ef..36bd68e1b0b 100644 --- a/sql/item.h +++ b/sql/item.h @@ -164,6 +164,12 @@ public: default: return "UNKNOWN"; } } + int sortcmp(const String *s, const String *t) const + { + return collation->coll->strnncollsp(collation, + (uchar *) s->ptr(), s->length(), + (uchar *) t->ptr(), t->length(), 0); + } }; /*************************************************************************/ diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index fdc6df6fd94..62f63501d86 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -1970,14 +1970,14 @@ longlong Item_func_lt::val_int() longlong Item_func_strcmp::val_int() { DBUG_ASSERT(fixed == 1); - String *a=args[0]->val_str(&cmp.value1); - String *b=args[1]->val_str(&cmp.value2); + String *a= args[0]->val_str(&value1); + String *b= args[1]->val_str(&value2); if (!a || !b) { null_value=1; return 0; } - int value= sortcmp(a,b,cmp.cmp_collation.collation); + int value= cmp_collation.sortcmp(a, b); null_value=0; return !value ? 0 : (value < 0 ? (longlong) -1 : (longlong) 1); } diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 71674c61d47..d4a1c6b1384 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -695,21 +695,18 @@ public: }; -class Item_func_strcmp :public Item_bool_func2 +class Item_func_strcmp :public Item_int_func { + String value1, value2; + DTCollation cmp_collation; public: - Item_func_strcmp(Item *a,Item *b) :Item_bool_func2(a,b) {} + Item_func_strcmp(Item *a,Item *b) :Item_int_func(a,b) {} longlong val_int(); - optimize_type select_optimize() const { return OPTIMIZE_NONE; } + uint decimal_precision() const { return 1; } const char *func_name() const { return "strcmp"; } - - virtual inline void print(String *str, enum_query_type query_type) - { - Item_func::print(str, query_type); - } void fix_length_and_dec() { - Item_bool_func2::fix_length_and_dec(); + agg_arg_charsets_for_comparison(cmp_collation, args, 2); fix_char_length(2); // returns "1" or "0" or "-1" } }; @@ -803,6 +800,7 @@ public: Item_func_nullif(Item *a,Item *b) :Item_bool_func2(a,b), cached_result_type(INT_RESULT) {} + bool is_bool_func() { return false; } double val_real(); longlong val_int(); String *val_str(String *str);