List:Commits« Previous MessageNext Message »
From:holyfoot Date:May 6 2007 3:17pm
Subject:bk commit into 5.0 tree (holyfoot:1.2474) BUG#27957
View as plain text  
Below is the list of changes that have just been committed into a local
5.0 repository of hf. When hf does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet@stripped, 2007-05-06 18:17:24+05:00, holyfoot@stripped +4 -0
  bug #27957 (cast as decimal does not check overflow, also inconsistent with group,
subselect)
  Item_decimal_typecast::val_decimal now checks the value if it's too
  big to fit the given precision/scale, truncates the value and issues
  a warning if the decimal gets off the range.

  mysql-test/r/cast.result@stripped, 2007-05-06 18:17:22+05:00, holyfoot@stripped +20 -3
    result added

  mysql-test/t/cast.test@stripped, 2007-05-06 18:17:22+05:00, holyfoot@stripped +11 -1
    testcase added and one old test fixed

  sql/item_func.cc@stripped, 2007-05-06 18:17:22+05:00, holyfoot@stripped +18 -0
    overflow checking added

  sql/item_func.h@stripped, 2007-05-06 18:17:22+05:00, holyfoot@stripped +3 -1
    store maximum possible value of the Item_decimal_typecast
    to check for overflow later

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	holyfoot
# Host:	hfmain.(none)
# Root:	/home/hf/work/27957/my50-27957

--- 1.335/sql/item_func.cc	2007-05-06 18:17:28 +05:00
+++ 1.336/sql/item_func.cc	2007-05-06 18:17:28 +05:00
@@ -1038,9 +1038,27 @@ longlong Item_decimal_typecast::val_int(
 
 my_decimal *Item_decimal_typecast::val_decimal(my_decimal *dec)
 {
+  bool orig_sign;
   my_decimal tmp_buf, *tmp= args[0]->val_decimal(&tmp_buf);
   if ((null_value= args[0]->null_value))
     return NULL;
+  orig_sign= tmp->sign();
+  tmp->sign(false);
+  max_value.sign(false);
+  if (my_decimal_cmp(tmp, &max_value) > 0)
+  {
+    char buf[100];
+    String err_st(buf, sizeof(buf), &my_charset_bin);
+    tmp->sign(orig_sign);
+    my_decimal2string(E_DEC_FATAL_ERROR, tmp, 0, 0, 0, &err_st);
+    push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+        ER_TRUNCATED_WRONG_VALUE,
+        ER(ER_TRUNCATED_WRONG_VALUE),
+        "DECIMAL", err_st.ptr());
+    max_value.sign(orig_sign);
+    return &max_value;
+  }
+  tmp->sign(orig_sign);
   my_decimal_round(E_DEC_FATAL_ERROR, tmp, decimals, FALSE, dec);
   return dec;
 }

--- 1.165/sql/item_func.h	2007-05-06 18:17:28 +05:00
+++ 1.166/sql/item_func.h	2007-05-06 18:17:28 +05:00
@@ -334,11 +334,13 @@ public:
 class Item_decimal_typecast :public Item_func
 {
   my_decimal decimal_value;
+  my_decimal max_value;
 public:
   Item_decimal_typecast(Item *a, int len, int dec) :Item_func(a)
   {
     max_length= len + 2;
     decimals= dec;
+    max_my_decimal(&max_value, len, dec);
   }
   String *val_str(String *str);
   double val_real();
@@ -346,7 +348,7 @@ public:
   my_decimal *val_decimal(my_decimal*);
   enum Item_result result_type () const { return DECIMAL_RESULT; }
   enum_field_types field_type() const { return MYSQL_TYPE_NEWDECIMAL; }
-  void fix_length_and_dec() {};
+  void fix_length_and_dec() {}
   const char *func_name() const { return "decimal_typecast"; }
   void print(String *);
 };

--- 1.49/mysql-test/r/cast.result	2007-05-06 18:17:28 +05:00
+++ 1.50/mysql-test/r/cast.result	2007-05-06 18:17:28 +05:00
@@ -376,9 +376,9 @@ cast(-1e18 as decimal(22,2))
 -1000000000000000000.00
 create table t1(s1 time);
 insert into t1 values ('11:11:11');
-select cast(s1 as decimal(7,2)) from t1;
-cast(s1 as decimal(7,2))
-111111.00
+select cast(s1 as decimal(7,1)) from t1;
+cast(s1 as decimal(7,1))
+111111.0
 drop table t1;
 CREATE TABLE t1 (v varchar(10), tt tinytext, t text,
 mt mediumtext, lt longtext);
@@ -401,4 +401,21 @@ hex(cast('a' as binary(2)))
 select hex(cast('a' as char(2) binary));
 hex(cast('a' as char(2) binary))
 61
+create table t1 (d DECIMAL(10, 5));
+insert into t1 values (11.1234), (-11.1234);
+select cast(d as DECIMAL(3,2)) d_c from t1;
+d_c
+9.99
+-9.99
+Warnings:
+Warning	1292	Truncated incorrect DECIMAL value: '11.12340'
+Warning	1292	Truncated incorrect DECIMAL value: '-11.12340'
+select * from (select cast(d as DECIMAL(3,2)) d_c from t1) t;
+d_c
+9.99
+-9.99
+Warnings:
+Warning	1292	Truncated incorrect DECIMAL value: '11.12340'
+Warning	1292	Truncated incorrect DECIMAL value: '-11.12340'
+drop table t1;
 End of 5.0 tests

--- 1.35/mysql-test/t/cast.test	2007-05-06 18:17:28 +05:00
+++ 1.36/mysql-test/t/cast.test	2007-05-06 18:17:28 +05:00
@@ -201,7 +201,7 @@ select cast(-1e18 as decimal(22,2));
 
 create table t1(s1 time);
 insert into t1 values ('11:11:11');
-select cast(s1 as decimal(7,2)) from t1;
+select cast(s1 as decimal(7,1)) from t1;
 drop table t1;
 
 #
@@ -230,5 +230,15 @@ set names latin1;
 select hex(cast('a' as char(2) binary));
 select hex(cast('a' as binary(2)));
 select hex(cast('a' as char(2) binary));
+
+#
+# Bug #27957 cast as decimal does not check overflow, also inconsistent with group,
subselect 
+#
+
+create table t1 (d DECIMAL(10, 5));
+insert into t1 values (11.1234), (-11.1234);
+select cast(d as DECIMAL(3,2)) d_c from t1;
+select * from (select cast(d as DECIMAL(3,2)) d_c from t1) t;
+drop table t1;
 
 --echo End of 5.0 tests
Thread
bk commit into 5.0 tree (holyfoot:1.2474) BUG#27957holyfoot6 May