MySQL Lists are EOL. Please join:

List:Commits« Previous MessageNext Message »
From:eugene Date:April 24 2008 8:39pm
Subject:bk commit into 5.0 tree (evgen:1.2613) BUG#36023
View as plain text  
Below is the list of changes that have just been committed into a local
5.0 repository of evgen.  When evgen 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, 2008-04-25 00:39:37+04:00, evgen@stripped +3 -0
  Bug#36023: Incorrect handling of zero length caused an assertion to fail.
  
  When a zero length is provided to the my_decimal_length_to_precision
  function along with unsigned_flag set to false it returns a negative value.
  For queries that employs temporary tables may cause failed assertion or
  excessive memory consumption while temporary table creation.
  
  Now the my_decimal_length_to_precision and the my_decimal_precision_to_length
  functions take unsigned_flag into account only if the length/precision
  argument is non-zero.

  mysql-test/r/type_decimal.result@stripped, 2008-04-25 00:38:56+04:00, evgen@stripped +7 -0
    Added a test case for the bug#36023: Incorrect handling of zero length caused
     an assertion to fail.

  mysql-test/t/type_decimal.test@stripped, 2008-04-25 00:38:54+04:00, evgen@stripped +8 -0
    Added a test case for the bug#36023: Incorrect handling of zero length caused
     an assertion to fail.

  sql/my_decimal.h@stripped, 2008-04-25 00:38:57+04:00, evgen@stripped +11 -2
    Bug#36023: Incorrect handling of zero length caused an assertion to fail.
    Now the my_decimal_length_to_precision and the my_decimal_precision_to_length
    functions take unsigned_flag into account only if the length/precision
    argument is non-zero.

diff -Nrup a/mysql-test/r/type_decimal.result b/mysql-test/r/type_decimal.result
--- a/mysql-test/r/type_decimal.result	2008-01-17 20:15:50 +03:00
+++ b/mysql-test/r/type_decimal.result	2008-04-25 00:38:56 +04:00
@@ -946,4 +946,11 @@ SELECT ROUND(20061108085411.000002);
 ROUND(20061108085411.000002)
 20061108085411
 DROP TABLE t1, t2, t3, t4, t5, t6;
+create table t1(`c` decimal(9,2));
+insert into t1 values (300),(201.11);
+select max(case 1 when 1 then c else null end) from t1 group by c;
+max(case 1 when 1 then c else null end)
+201.11
+300.00
+drop table t1;
 End of 5.0 tests
diff -Nrup a/mysql-test/t/type_decimal.test b/mysql-test/t/type_decimal.test
--- a/mysql-test/t/type_decimal.test	2008-01-17 20:15:50 +03:00
+++ b/mysql-test/t/type_decimal.test	2008-04-25 00:38:54 +04:00
@@ -521,4 +521,12 @@ SELECT ROUND(20061108085411.000002);
 
 DROP TABLE t1, t2, t3, t4, t5, t6;
 
+#
+# Bug#36023: Incorrect handling of zero length caused an assertion to fail.
+#
+create table t1(`c` decimal(9,2));
+insert into t1 values (300),(201.11);
+select max(case 1 when 1 then c else null end) from t1 group by c;
+drop table t1;
+
 --echo End of 5.0 tests
diff -Nrup a/sql/my_decimal.h b/sql/my_decimal.h
--- a/sql/my_decimal.h	2007-05-28 02:05:33 +04:00
+++ b/sql/my_decimal.h	2008-04-25 00:38:57 +04:00
@@ -164,14 +164,23 @@ inline int check_result_and_overflow(uin
 inline uint my_decimal_length_to_precision(uint length, uint scale,
                                            bool unsigned_flag)
 {
-  return (uint) (length - (scale>0 ? 1:0) - (unsigned_flag ? 0:1));
+  /* Precision can't be negative thus ignore unsigned_flag when length is 0. */
+  DBUG_ASSERT(length || !scale);
+  return (uint) (length - (scale>0 ? 1:0) -
+                 (unsigned_flag || !length ? 0:1));
 }
 
 inline uint32 my_decimal_precision_to_length(uint precision, uint8 scale,
                                              bool unsigned_flag)
 {
+  /*
+    When precision is 0 it means that original length was also 0. Thus
+    unsigned_flag is ignored in this case.
+  */
+  DBUG_ASSERT(precision || !scale);
   set_if_smaller(precision, DECIMAL_MAX_PRECISION);
-  return (uint32)(precision + (scale>0 ? 1:0) + (unsigned_flag ? 0:1));
+  return (uint32)(precision + (scale>0 ? 1:0) +
+                  (unsigned_flag || !precision ? 0:1));
 }
 
 inline
Thread
bk commit into 5.0 tree (evgen:1.2613) BUG#36023eugene6 Aug