diff --git a/mysql-test/main/type_float.result b/mysql-test/main/type_float.result index a3fa3d435d511..22ef549cd6168 100644 --- a/mysql-test/main/type_float.result +++ b/mysql-test/main/type_float.result @@ -154,6 +154,46 @@ select * from t1; d1 d2 -1 0 drop table t1; +create table t1 (f float unsigned, key(f)); +insert into t1 values (NULL),(0),(0.5); +select f, f = "-1" as eq from t1 order by f is null, f; +f eq +0 0 +0.5 0 +NULL NULL +select f from t1 where f = "-1"; +f +select f from t1 ignore index (f) where f = "-1"; +f +select f from t1 where f > "-1"; +f +0 +0.5 +select f from t1 ignore index (f) where f > "-1"; +f +0 +0.5 +drop table t1; +create table t1 (d double unsigned, key(d)); +insert into t1 values (NULL),(0),(0.5); +select d, d = "-1" as eq from t1 order by d is null, d; +d eq +0 0 +0.5 0 +NULL NULL +select d from t1 where d = "-1"; +d +select d from t1 ignore index (d) where d = "-1"; +d +select d from t1 where d > "-1"; +d +0 +0.5 +select d from t1 ignore index (d) where d > "-1"; +d +0 +0.5 +drop table t1; create table t1 (f float(4,3)); insert ignore into t1 values (-11.0),(-11),("-11"),(11.0),(11),("11"); Warnings: diff --git a/mysql-test/main/type_float.test b/mysql-test/main/type_float.test index adc737abe25b3..4f905d4755ddf 100644 --- a/mysql-test/main/type_float.test +++ b/mysql-test/main/type_float.test @@ -102,6 +102,26 @@ update ignore t1 set d2 = d1; select * from t1; drop table t1; +# Do not use a truncated negative string constant for an indexed +# FLOAT/DOUBLE UNSIGNED equality range. +create table t1 (f float unsigned, key(f)); +insert into t1 values (NULL),(0),(0.5); +select f, f = "-1" as eq from t1 order by f is null, f; +select f from t1 where f = "-1"; +select f from t1 ignore index (f) where f = "-1"; +select f from t1 where f > "-1"; +select f from t1 ignore index (f) where f > "-1"; +drop table t1; + +create table t1 (d double unsigned, key(d)); +insert into t1 values (NULL),(0),(0.5); +select d, d = "-1" as eq from t1 order by d is null, d; +select d from t1 where d = "-1"; +select d from t1 ignore index (d) where d = "-1"; +select d from t1 where d > "-1"; +select d from t1 ignore index (d) where d > "-1"; +drop table t1; + # Ensure that maximum values as the result of number of decimals # being specified in table schema are enforced (Bug #7361) create table t1 (f float(4,3)); diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 63fd9333c9803..86c6683e5d718 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -9665,6 +9665,18 @@ SEL_ARG *Field_num::get_mm_leaf(RANGE_OPT_PARAM *prm, KEY_PART *key_part, if (can_optimize_scalar_range(prm, key_part, cond, op, value) != Data_type_compatibility::OK) DBUG_RETURN(0); + if (unsigned_flag && + (type() == MYSQL_TYPE_FLOAT || type() == MYSQL_TYPE_DOUBLE)) + { + double item_val= value->val_real(); + if (!value->null_value && item_val < 0) + { + if (op == SCALAR_CMP_EQ || op == SCALAR_CMP_EQUAL || + op == SCALAR_CMP_LT || op == SCALAR_CMP_LE) + DBUG_RETURN(new (prm->mem_root) SEL_ARG_IMPOSSIBLE(this)); + DBUG_RETURN(0); + } + } int err= value->save_in_field_no_warnings(this, 1); if ((op != SCALAR_CMP_EQUAL && is_real_null()) || err < 0) DBUG_RETURN(&null_element);