From: Martin Hansson Date: July 2 2009 12:28pm Subject: bzr commit into mysql-5.1-bugteam branch (martin.hansson:2936) Bug#45261 List-Archive: http://lists.mysql.com/commits/77769 X-Bug: 45261 Message-Id: <200907021229.n62CT5YQ029401@riff-raff> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============1752069731==" --===============1752069731== MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline #At file:///data0/martin/bzr/bug45261/5.1bt-gca-commit/ based on revid:davi.arnaut@stripped 2936 Martin Hansson 2009-07-02 Bug#45261: Crash, stored procedure + decimal The truncation procedure for creating field for DECIMAL typed columns calculated overflow using a function that automatically truncated field length to avoid overflow, and this was caught much later than the actual error. Fixed by creating a new function for field length calculation that does not truncate, and by adding an assertion in constructor for DECIMAL type column objects. @ mysql-test/r/type_newdecimal.result Bug#45261: - Wrong test result turned correct. - Test result. @ mysql-test/t/type_newdecimal.test Bug#45261: Test case. @ sql/field.cc Bug#45261: Added DBUG_ASSERT to ensure object's invariant is maintained. @ sql/field.h Bug#45261: Added comment to explain what member is for. @ sql/my_decimal.h Bug#45261: Created non-truncating version of my_decimal_precision_to_length() @ sql/sql_select.cc Bug#45261: Fix: Using new non-truncating function. modified: mysql-test/r/type_newdecimal.result mysql-test/t/type_newdecimal.test sql/field.cc sql/field.h sql/my_decimal.h sql/sql_select.cc === modified file 'mysql-test/r/type_newdecimal.result' --- a/mysql-test/r/type_newdecimal.result 2008-11-18 09:52:03 +0000 +++ b/mysql-test/r/type_newdecimal.result 2009-07-02 12:27:56 +0000 @@ -1521,13 +1521,13 @@ f1 DROP TABLE t1; CREATE TABLE t1 SELECT 123451234512345123451234512345123451234512345.678906789067890678906789067890678906789067890 AS f1; Warnings: -Warning 1264 Out of range value for column 'f1' at row 1 +Note 1265 Data truncated for column 'f1' at row 1 DESC t1; Field Type Null Key Default Extra -f1 decimal(59,30) NO 0.000000000000000000000000000000 +f1 decimal(65,20) NO 0.00000000000000000000 SELECT f1 FROM t1; f1 -99999999999999999999999999999.999999999999999999999999999999 +123451234512345123451234512345123451234512345.67890678906789067891 DROP TABLE t1; select (1.20396873 * 0.89550000 * 0.68000000 * 1.08721696 * 0.99500000 * 1.01500000 * 1.01500000 * 0.99500000); @@ -1577,3 +1577,47 @@ Error 1264 Out of range value for column select cast(98.6 as decimal(2,0)); cast(98.6 as decimal(2,0)) 99 +CREATE TABLE t1 SELECT +123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345 +AS a; +Warnings: +Note 1265 Data truncated for column 'a' at row 1 +SELECT a FROM t1; +a +123456789012345678901234567890123456789012345.12345678901234567890 +DESC t1; +Field Type Null Key Default Extra +a decimal(65,20) NO 0.00000000000000000000 +CREATE TABLE t2 SELECT +12345678901234567890123456789012345678901234567890123456789012345.1 +AS a; +Warnings: +Note 1265 Data truncated for column 'a' at row 1 +SELECT a FROM t2; +a +12345678901234567890123456789012345678901234567890123456789012345 +DESC t2; +Field Type Null Key Default Extra +a decimal(65,0) NO 0 +CREATE TABLE t3 SELECT +123456789012345678901234567890123456789012345678901234567890123456.1 +AS a; +Warnings: +Warning 1264 Out of range value for column 'a' at row 1 +SELECT a FROM t3; +a +99999999999999999999999999999999999999999999999999999999999999999 +DESC t3; +Field Type Null Key Default Extra +a decimal(65,0) NO 0 +CREATE TABLE t4 +SELECT .123456789012345678901234567890123456789012345678901234567890123456 AS a; +Warnings: +Note 1265 Data truncated for column 'a' at row 1 +SELECT a FROM t4; +a +0.123456789012345678901234567890 +DESC t4; +Field Type Null Key Default Extra +a decimal(30,30) NO 0.000000000000000000000000000000 +DROP TABLE t1, t2, t3, t4; === modified file 'mysql-test/t/type_newdecimal.test' --- a/mysql-test/t/type_newdecimal.test 2008-11-17 15:43:10 +0000 +++ b/mysql-test/t/type_newdecimal.test 2009-07-02 12:27:56 +0000 @@ -1257,3 +1257,31 @@ select cast(-3.4 as decimal(2,1)); select cast(99.6 as decimal(2,0)); select cast(-13.4 as decimal(2,1)); select cast(98.6 as decimal(2,0)); +# +# Bug#45261 Crash, stored procedure + decimal +# + +CREATE TABLE t1 SELECT +123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345 +AS a; +SELECT a FROM t1; +DESC t1; + +CREATE TABLE t2 SELECT +12345678901234567890123456789012345678901234567890123456789012345.1 +AS a; +SELECT a FROM t2; +DESC t2; + +CREATE TABLE t3 SELECT +123456789012345678901234567890123456789012345678901234567890123456.1 +AS a; +SELECT a FROM t3; +DESC t3; + +CREATE TABLE t4 +SELECT .123456789012345678901234567890123456789012345678901234567890123456 AS a; +SELECT a FROM t4; +DESC t4; + +DROP TABLE t1, t2, t3, t4; === modified file 'sql/field.cc' --- a/sql/field.cc 2009-06-09 16:44:26 +0000 +++ b/sql/field.cc 2009-07-02 12:27:56 +0000 @@ -2485,6 +2485,7 @@ Field_new_decimal::Field_new_decimal(uin { precision= my_decimal_length_to_precision(len_arg, dec_arg, unsigned_arg); set_if_smaller(precision, DECIMAL_MAX_PRECISION); + DBUG_ASSERT(precision >= dec); DBUG_ASSERT((precision <= DECIMAL_MAX_PRECISION) && (dec <= DECIMAL_MAX_SCALE)); bin_size= my_decimal_get_binary_size(precision, dec); === modified file 'sql/field.h' --- a/sql/field.h 2009-06-09 16:44:26 +0000 +++ b/sql/field.h 2009-07-02 12:27:56 +0000 @@ -608,6 +608,11 @@ protected: class Field_num :public Field { public: + + /** + The scale of the Field's value, i.e. the number of digits to the right + of the decimal point. + */ const uint8 dec; bool zerofill,unsigned_flag; // Purify cannot handle bit fields Field_num(uchar *ptr_arg,uint32 len_arg, uchar *null_ptr_arg, === modified file 'sql/my_decimal.h' --- a/sql/my_decimal.h 2008-05-20 07:38:17 +0000 +++ b/sql/my_decimal.h 2009-07-02 12:27:56 +0000 @@ -183,6 +183,19 @@ inline uint my_decimal_length_to_precisi (unsigned_flag || !length ? 0:1)); } +inline uint32 my_decimal_precision_to_length_no_truncation(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); + return (uint32)(precision + (scale > 0 ? 1 : 0) + + (unsigned_flag || !precision ? 0 : 1)); +} + inline uint32 my_decimal_precision_to_length(uint precision, uint8 scale, bool unsigned_flag) { @@ -192,8 +205,8 @@ inline uint32 my_decimal_precision_to_le */ DBUG_ASSERT(precision || !scale); set_if_smaller(precision, DECIMAL_MAX_PRECISION); - return (uint32)(precision + (scale>0 ? 1:0) + - (unsigned_flag || !precision ? 0:1)); + return my_decimal_precision_to_length_no_truncation(precision, scale, + unsigned_flag); } inline === modified file 'sql/sql_select.cc' --- a/sql/sql_select.cc 2009-06-07 20:40:53 +0000 +++ b/sql/sql_select.cc 2009-07-02 12:27:56 +0000 @@ -9389,14 +9389,16 @@ static Field *create_tmp_field_from_item bad and of course throws a truncation warning. +1: for decimal point */ - - overflow= my_decimal_precision_to_length(intg + dec, dec, - item->unsigned_flag) - len; + const int required_length= + my_decimal_precision_to_length_no_truncation(intg + dec, dec, + item->unsigned_flag); + overflow= required_length - len; if (overflow > 0) dec= max(0, dec - overflow); // too long, discard fract else - len -= item->decimals - dec; // corrected value fits + /* Corrected value fits. */ + len= required_length; } new_field= new Field_new_decimal(len, maybe_null, item->name, --===============1752069731== MIME-Version: 1.0 Content-Type: text/bzr-bundle; charset="us-ascii"; name="bzr/martin.hansson@stripped" Content-Transfer-Encoding: 7bit Content-Disposition: inline # Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: martin.hansson@stripped # target_branch: file:///data0/martin/bzr/bug45261/5.1bt-gca-commit/ # testament_sha1: 6320df4017c7d8f44aef70b82c8ba539d0dcd1ad # timestamp: 2009-07-02 14:28:05 +0200 # base_revision_id: davi.arnaut@stripped\ # y7y7n931lbgnesb4 # # Begin bundle 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 Lf8u --===============1752069731==--