diff options
author | paul@teton.kitebird.com <> | 2004-03-08 14:08:10 -0600 |
---|---|---|
committer | paul@teton.kitebird.com <> | 2004-03-08 14:08:10 -0600 |
commit | d292e9bd1ff0e00ada68c22eef1b6574c82f3158 (patch) | |
tree | 6e8d7940567f1540c9bce9a1728f827843bc375c /sql/field.cc | |
parent | c696fc62993b54c127551277ccde92d3b48ea156 (diff) | |
parent | 6a10859beef92a451a52d9a5ff54076f0ac1407c (diff) | |
download | mariadb-git-d292e9bd1ff0e00ada68c22eef1b6574c82f3158.tar.gz |
Merge paul@bk-internal.mysql.com:/home/bk/mysql-4.1
into teton.kitebird.com:/home/paul/mysql-4.1
Diffstat (limited to 'sql/field.cc')
-rw-r--r-- | sql/field.cc | 120 |
1 files changed, 84 insertions, 36 deletions
diff --git a/sql/field.cc b/sql/field.cc index 48e7dbb32ca..93827a8cd1f 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -2271,13 +2271,18 @@ void Field_longlong::sql_type(String &res) const int Field_float::store(const char *from,uint len,CHARSET_INFO *cs) { int err; - Field_float::store(my_strntod(cs,(char*) from,len,(char**)NULL,&err)); - if (err || current_thd->count_cuted_fields && !test_if_real(from,len,cs)) + char *end; + double nr= my_strntod(cs,(char*) from,len,&end,&err); + if (!err && (!current_thd->count_cuted_fields || end-from==len)) + { + return Field_float::store(nr); + } + else { set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED); + Field_float::store(nr); return 1; } - return (err) ? 1 : 0; } @@ -2285,28 +2290,48 @@ int Field_float::store(double nr) { float j; int error= 0; - if (dec < NOT_FIXED_DEC) - nr=floor(nr*log_10[dec]+0.5)/log_10[dec]; // To fixed point - if (unsigned_flag && nr < 0) + + if (isnan(nr)) { + j= 0; + set_null(); set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE); - nr=0; error= 1; } - if (nr < -FLT_MAX) + else if (unsigned_flag && nr < 0) { - j= -FLT_MAX; + j= 0; set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE); error= 1; } - else if (nr > FLT_MAX) + else { - j=FLT_MAX; - set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE); - error= 1; + double max_value; + if (dec >= NOT_FIXED_DEC) + { + max_value= FLT_MAX; + } + else + { + max_value= (log_10[field_length]-1)/log_10[dec]; + nr= floor(nr*log_10[dec]+0.5)/log_10[dec]; + } + if (nr < -max_value) + { + j= (float)-max_value; + set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE); + error= 1; + } + else if (nr > max_value) + { + j= (float)max_value; + set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE); + error= 1; + } + else + j= (float) nr; } - else - j= (float) nr; + #ifdef WORDS_BIGENDIAN if (table->db_low_byte_first) { @@ -2544,41 +2569,64 @@ void Field_float::sql_type(String &res) const int Field_double::store(const char *from,uint len,CHARSET_INFO *cs) { int err; - double j= my_strntod(cs,(char*) from,len,(char**)0,&err); - if (err || current_thd->count_cuted_fields && !test_if_real(from,len,cs)) - { - set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED); - err= 1; - } - if (unsigned_flag && j < 0) + char *end; + double nr= my_strntod(cs,(char*) from,len,&end,&err); + if (!err && (!current_thd->count_cuted_fields || end-from==len)) { - set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE); - j=0; - err= 1; + return Field_double::store(nr); } -#ifdef WORDS_BIGENDIAN - if (table->db_low_byte_first) + else { - float8store(ptr,j); + set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED); + Field_double::store(nr); + return 1; } - else -#endif - doublestore(ptr,j); - return err; } int Field_double::store(double nr) { int error= 0; - if (dec < NOT_FIXED_DEC) - nr=floor(nr*log_10[dec]+0.5)/log_10[dec]; // To fixed point - if (unsigned_flag && nr < 0) + + if (isnan(nr)) { + nr= 0; + set_null(); + set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE); + error= 1; + } + else if (unsigned_flag && nr < 0) + { + nr= 0; set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE); - nr=0; error= 1; } + else + { + double max_value; + if (dec >= NOT_FIXED_DEC) + { + max_value= DBL_MAX; + } + else + { + max_value= (log_10[field_length]-1)/log_10[dec]; + nr= floor(nr*log_10[dec]+0.5)/log_10[dec]; + } + if (nr < -max_value) + { + nr= -max_value; + set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE); + error= 1; + } + else if (nr > max_value) + { + nr= max_value; + set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE); + error= 1; + } + } + #ifdef WORDS_BIGENDIAN if (table->db_low_byte_first) { |