From 8b077c2b9fb9fab697a5136db22e1695da3c6ccb Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 13 Jan 2005 00:41:45 +0100 Subject: [PATCH 1/2] Fix conversion of floating point values to character fields when the absolute value of the float is less than 1, and also fix calculation of length for negative values. (Bug #7774) sql/field.cc: Fix handling of negative values and fabs(values> < 1 in Field_str::store mysql-test/r/type_float.result: Add results mysql-test/r/type_float.result.es: Add results mysql-test/t/type_float.test: Add test for conversion of floats to character field --- mysql-test/r/type_float.result | 15 +++++++++++++++ mysql-test/r/type_float.result.es | 15 +++++++++++++++ mysql-test/t/type_float.test | 10 ++++++++++ sql/field.cc | 13 ++++++++++--- 4 files changed, 50 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/type_float.result b/mysql-test/r/type_float.result index 9dd92c13c98..530eb32f77d 100644 --- a/mysql-test/r/type_float.result +++ b/mysql-test/r/type_float.result @@ -179,3 +179,18 @@ f 9.999 9.999 drop table if exists t1; +create table t1 (c char(20)); +insert into t1 values (5e-28); +select * from t1; +c +5e-28 +drop table t1; +create table t1 (c char(6)); +insert into t1 values (2e5),(2e6),(2e-4),(2e-5); +select * from t1; +c +200000 +2e+06 +0.0002 +2e-05 +drop table t1; diff --git a/mysql-test/r/type_float.result.es b/mysql-test/r/type_float.result.es index 64d9be7e30f..b93539b6bea 100644 --- a/mysql-test/r/type_float.result.es +++ b/mysql-test/r/type_float.result.es @@ -179,3 +179,18 @@ f 9.999 9.999 drop table if exists t1; +create table t1 (c char(20)); +insert into t1 values (5e-28); +select * from t1; +c +5e-28 +drop table t1; +create table t1 (c char(6)); +insert into t1 values (2e5),(2e6),(2e-4),(2e-5); +select * from t1; +c +200000 +2e+06 +0.0002 +2e-05 +drop table t1; diff --git a/mysql-test/t/type_float.test b/mysql-test/t/type_float.test index 3fe3afa3fac..69cdeaa32a9 100644 --- a/mysql-test/t/type_float.test +++ b/mysql-test/t/type_float.test @@ -103,3 +103,13 @@ create table t1 (f double(4,3)); insert into t1 values (-11.0),(-11),("-11"),(11.0),(11),("11"); select * from t1; drop table if exists t1; + +# Check conversion of floats to character field (Bug #7774) +create table t1 (c char(20)); +insert into t1 values (5e-28); +select * from t1; +drop table t1; +create table t1 (c char(6)); +insert into t1 values (2e5),(2e6),(2e-4),(2e-5); +select * from t1; +drop table t1; diff --git a/sql/field.cc b/sql/field.cc index e2c11cc7372..2f2115e55dd 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -4301,13 +4301,20 @@ int Field_str::store(double nr) char buff[DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE]; uint length; bool use_scientific_notation= TRUE; - use_scientific_notation= TRUE; - if (field_length < 32 && fabs(nr) < log_10[field_length]-1) + /* + Check fabs(nr) against longest value that can be stored in field, + which depends on whether the value is < 1 or not, and negative or not + */ + double anr= fabs(nr); + int neg= (nr < 0.0) ? 1 : 0; + if (field_length < 32 && + (anr < 1.0 ? anr > 1/(log_10[max(0,field_length-neg-2)]) /* -2 for "0." */ + : anr < log_10[field_length-neg]-1)) use_scientific_notation= FALSE; length= (uint) my_sprintf(buff, (buff, "%-.*g", (use_scientific_notation ? - max(0, (int)field_length-5) : + max(0, (int)field_length-neg-5) : field_length), nr)); /* From 7682d6c9cfa7081dc88b744d1a4f343367309c2b Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 13 Jan 2005 00:52:19 +0100 Subject: [PATCH 2/2] Small fix for Field_str::store() to avoid trying to read past beginning of log_10 array. sql/field.cc: Avoid pointless calculation for really short fields, and what could be an attempt to access outside the bounds of the log_10 array. --- sql/field.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/field.cc b/sql/field.cc index 2f2115e55dd..fec65438e4d 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -4307,7 +4307,7 @@ int Field_str::store(double nr) */ double anr= fabs(nr); int neg= (nr < 0.0) ? 1 : 0; - if (field_length < 32 && + if (field_length > 4 && field_length < 32 && (anr < 1.0 ? anr > 1/(log_10[max(0,field_length-neg-2)]) /* -2 for "0." */ : anr < log_10[field_length-neg]-1)) use_scientific_notation= FALSE;