Loading BUILD/Makefile.am +1 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ EXTRA_DIST = FINISH.sh \ SETUP.sh \ check-cpu \ compile-alpha \ compile-alpha-ccc \ compile-alpha-cxx \ Loading mysql-test/r/ctype_utf8.result +3 −0 Original line number Diff line number Diff line Loading @@ -888,3 +888,6 @@ NULL select ifnull(NULL, _utf8'string'); ifnull(NULL, _utf8'string') string create table t1 (a varchar(255)) default character set utf8; insert into t1 values (1.0); drop table t1; mysql-test/t/ctype_utf8.test +7 −0 Original line number Diff line number Diff line Loading @@ -724,3 +724,10 @@ select ifnull(a,'') from t1; drop table t1; select repeat(_utf8'+',3) as h union select NULL; select ifnull(NULL, _utf8'string'); # # Bug#10714: Inserting double value into utf8 column crashes server # create table t1 (a varchar(255)) default character set utf8; insert into t1 values (1.0); drop table t1; sql/field.cc +8 −7 Original line number Diff line number Diff line Loading @@ -4981,31 +4981,32 @@ int Field_str::store(double nr) char buff[DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE]; uint length; bool use_scientific_notation= TRUE; uint char_length= field_length / charset()->mbmaxlen; /* 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 > 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)) if (char_length > 4 && char_length < 32 && (anr < 1.0 ? anr > 1/(log_10[max(0,char_length-neg-2)]) /* -2 for "0." */ : anr < log_10[char_length-neg]-1)) use_scientific_notation= FALSE; length= (uint) my_sprintf(buff, (buff, "%-.*g", (use_scientific_notation ? max(0, (int)field_length-neg-5) : field_length), max(0, (int)char_length-neg-5) : char_length), nr)); /* +1 below is because "precision" in %g above means the max. number of significant digits, not the output width. Thus the width can be larger than number of significant digits by 1 (for decimal point) the test for field_length < 5 is for extreme cases, the test for char_length < 5 is for extreme cases, like inserting 500.0 in char(1) */ DBUG_ASSERT(field_length < 5 || length <= field_length+1); DBUG_ASSERT(char_length < 5 || length <= char_length+1); return store((const char *) buff, length, charset()); } Loading Loading
BUILD/Makefile.am +1 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ EXTRA_DIST = FINISH.sh \ SETUP.sh \ check-cpu \ compile-alpha \ compile-alpha-ccc \ compile-alpha-cxx \ Loading
mysql-test/r/ctype_utf8.result +3 −0 Original line number Diff line number Diff line Loading @@ -888,3 +888,6 @@ NULL select ifnull(NULL, _utf8'string'); ifnull(NULL, _utf8'string') string create table t1 (a varchar(255)) default character set utf8; insert into t1 values (1.0); drop table t1;
mysql-test/t/ctype_utf8.test +7 −0 Original line number Diff line number Diff line Loading @@ -724,3 +724,10 @@ select ifnull(a,'') from t1; drop table t1; select repeat(_utf8'+',3) as h union select NULL; select ifnull(NULL, _utf8'string'); # # Bug#10714: Inserting double value into utf8 column crashes server # create table t1 (a varchar(255)) default character set utf8; insert into t1 values (1.0); drop table t1;
sql/field.cc +8 −7 Original line number Diff line number Diff line Loading @@ -4981,31 +4981,32 @@ int Field_str::store(double nr) char buff[DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE]; uint length; bool use_scientific_notation= TRUE; uint char_length= field_length / charset()->mbmaxlen; /* 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 > 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)) if (char_length > 4 && char_length < 32 && (anr < 1.0 ? anr > 1/(log_10[max(0,char_length-neg-2)]) /* -2 for "0." */ : anr < log_10[char_length-neg]-1)) use_scientific_notation= FALSE; length= (uint) my_sprintf(buff, (buff, "%-.*g", (use_scientific_notation ? max(0, (int)field_length-neg-5) : field_length), max(0, (int)char_length-neg-5) : char_length), nr)); /* +1 below is because "precision" in %g above means the max. number of significant digits, not the output width. Thus the width can be larger than number of significant digits by 1 (for decimal point) the test for field_length < 5 is for extreme cases, the test for char_length < 5 is for extreme cases, like inserting 500.0 in char(1) */ DBUG_ASSERT(field_length < 5 || length <= field_length+1); DBUG_ASSERT(char_length < 5 || length <= char_length+1); return store((const char *) buff, length, charset()); } Loading