From bf7a2bb12cde9d4ec47e400ab645467783cbaf32 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Mon, 7 Sep 2015 10:50:27 +0400 Subject: [PATCH] MDEV-8704 Wrong result for SELECT..WHERE LENGTH(double_column)!=6 AND double_column=100e0 --- mysql-test/r/type_float.result | 95 ++++++++++++++++++++++++++++++++++ mysql-test/t/type_float.test | 64 +++++++++++++++++++++++ sql/field.cc | 22 ++++++++ sql/field.h | 2 + 4 files changed, 183 insertions(+) diff --git a/mysql-test/r/type_float.result b/mysql-test/r/type_float.result index 6cc07cd2549..76465d77b50 100644 --- a/mysql-test/r/type_float.result +++ b/mysql-test/r/type_float.result @@ -532,3 +532,98 @@ DROP TABLE t1,t2; # # End of 10.0 tests # +# +# MDEV-8704 Wrong result for SELECT..WHERE LENGTH(double_column)!=6 AND double_column=100e0 +# +CREATE TABLE t1 (a DOUBLE(9,2)); +INSERT INTO t1 VALUES (100),(110); +SELECT * FROM t1 WHERE LENGTH(a)!=6; +a +SELECT * FROM t1 WHERE LENGTH(a)!=6 AND a=100e0; +a +DROP TABLE t1; +CREATE TABLE t1 (a DOUBLE); +INSERT INTO t1 VALUES (100),(110); +SELECT * FROM t1 WHERE LENGTH(a)!=6; +a +100 +110 +SELECT * FROM t1 WHERE LENGTH(a)!=6 AND a=100e0; +a +100 +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE LENGTH(a)!=6 AND a=100e0; +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` = 100e0) +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE LENGTH(a)!=RAND() AND a=100e0; +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` = 100e0) and ((length(100)) <> rand())) +DROP TABLE t1; +CREATE TABLE t1 (a DOUBLE(10,1)); +INSERT INTO t1 VALUES (1.1),(1.2),(1.3); +SELECT * FROM t1 WHERE LENGTH(a)!=3; +a +SELECT * FROM t1 WHERE LENGTH(a)!=3 AND a=1.10e0; +a +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE LENGTH(a)!=3 AND a=1.10e0; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +Warnings: +Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where 0 +# Notice 1.1 instead of 1.10 in the final WHERE condition +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE LENGTH(a)!=RAND() AND a=1.10e0; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where +Warnings: +Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where ((`test`.`t1`.`a` = 1.10e0) and ((length(1.1)) <> rand())) +DROP TABLE t1; +CREATE TABLE t1 (a DOUBLE(10,2)); +INSERT INTO t1 VALUES (1.1),(1.2),(1.3); +SELECT * FROM t1 WHERE LENGTH(a)!=4; +a +SELECT * FROM t1 WHERE LENGTH(a)!=4 AND a=1.10e0; +a +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE LENGTH(a)!=4 AND a=1.10e0; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +Warnings: +Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where 0 +# Notice 1.10 in the final WHERE condition +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE LENGTH(a)!=RAND() AND a=1.10e0; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where +Warnings: +Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where ((`test`.`t1`.`a` = 1.10e0) and ((length(1.10)) <> rand())) +DROP TABLE t1; +CREATE TABLE t1 (a DOUBLE(10,3)); +INSERT INTO t1 VALUES (1.1),(1.2),(1.3); +SELECT * FROM t1 WHERE LENGTH(a)!=5; +a +SELECT * FROM t1 WHERE LENGTH(a)!=5 AND a=1.10e0; +a +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE LENGTH(a)!=5 AND a=1.10e0; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +Warnings: +Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where 0 +# Notice 1.100 rather than 1.10 in the final WHERE condition +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE LENGTH(a)!=RAND() AND a=1.10e0; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where +Warnings: +Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where ((`test`.`t1`.`a` = 1.10e0) and ((length(1.100)) <> rand())) +DROP TABLE t1; +# +# End of 10.1 tests +# diff --git a/mysql-test/t/type_float.test b/mysql-test/t/type_float.test index bb7a784553e..9b4b6fa21f7 100644 --- a/mysql-test/t/type_float.test +++ b/mysql-test/t/type_float.test @@ -385,3 +385,67 @@ DROP TABLE t1,t2; --echo # --echo # End of 10.0 tests --echo # + + +--echo # +--echo # MDEV-8704 Wrong result for SELECT..WHERE LENGTH(double_column)!=6 AND double_column=100e0 +--echo # + +# The original test case from the bug report +CREATE TABLE t1 (a DOUBLE(9,2)); +INSERT INTO t1 VALUES (100),(110); +SELECT * FROM t1 WHERE LENGTH(a)!=6; +SELECT * FROM t1 WHERE LENGTH(a)!=6 AND a=100e0; +DROP TABLE t1; + +# DOUBLE with no specific precision +CREATE TABLE t1 (a DOUBLE); +INSERT INTO t1 VALUES (100),(110); +SELECT * FROM t1 WHERE LENGTH(a)!=6; +SELECT * FROM t1 WHERE LENGTH(a)!=6 AND a=100e0; +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE LENGTH(a)!=6 AND a=100e0; +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE LENGTH(a)!=RAND() AND a=100e0; +DROP TABLE t1; + +# The constant scale is bigger than the field scale +CREATE TABLE t1 (a DOUBLE(10,1)); +INSERT INTO t1 VALUES (1.1),(1.2),(1.3); +SELECT * FROM t1 WHERE LENGTH(a)!=3; +SELECT * FROM t1 WHERE LENGTH(a)!=3 AND a=1.10e0; +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE LENGTH(a)!=3 AND a=1.10e0; +--echo # Notice 1.1 instead of 1.10 in the final WHERE condition +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE LENGTH(a)!=RAND() AND a=1.10e0; +DROP TABLE t1; + +# The constant scale is equal to the field scale +CREATE TABLE t1 (a DOUBLE(10,2)); +INSERT INTO t1 VALUES (1.1),(1.2),(1.3); +SELECT * FROM t1 WHERE LENGTH(a)!=4; +SELECT * FROM t1 WHERE LENGTH(a)!=4 AND a=1.10e0; +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE LENGTH(a)!=4 AND a=1.10e0; +--echo # Notice 1.10 in the final WHERE condition +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE LENGTH(a)!=RAND() AND a=1.10e0; +DROP TABLE t1; + +# The constant scale is smaller than the field scale +CREATE TABLE t1 (a DOUBLE(10,3)); +INSERT INTO t1 VALUES (1.1),(1.2),(1.3); +SELECT * FROM t1 WHERE LENGTH(a)!=5; +SELECT * FROM t1 WHERE LENGTH(a)!=5 AND a=1.10e0; +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE LENGTH(a)!=5 AND a=1.10e0; +--echo # Notice 1.100 rather than 1.10 in the final WHERE condition +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE LENGTH(a)!=RAND() AND a=1.10e0; +DROP TABLE t1; + + +--echo # +--echo # End of 10.1 tests +--echo # diff --git a/sql/field.cc b/sql/field.cc index 6a8dddc5c10..5a7ac815c9d 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -4639,6 +4639,28 @@ bool Field_real::get_date(MYSQL_TIME *ltime,ulonglong fuzzydate) } +Item *Field_real::get_equal_const_item(THD *thd, const Context &ctx, + Item_field *field_item, + Item *const_item) +{ + if (flags & ZEROFILL_FLAG) + return Field_num::get_equal_zerofill_const_item(thd, ctx, + field_item, const_item); + switch (ctx.subst_constraint()) { + case IDENTITY_SUBST: + if (const_item->decimal_scale() != Field_real::decimals()) + { + double val= const_item->val_real(); + return new (thd->mem_root) Item_float(thd, val, Field_real::decimals()); + } + break; + case ANY_SUBST: + break; + } + return const_item; +} + + String *Field_double::val_str(String *val_buffer, String *val_ptr __attribute__((unused))) { diff --git a/sql/field.h b/sql/field.h index 57e90c4ea2f..b08419ae7cc 100644 --- a/sql/field.h +++ b/sql/field.h @@ -1363,6 +1363,8 @@ public: my_decimal *val_decimal(my_decimal *); uint32 max_display_length() { return field_length; } uint size_of() const { return sizeof(*this); } + Item *get_equal_const_item(THD *thd, const Context &ctx, + Item_field *field_item, Item *const_item); };