From: Date: July 3 2009 12:52pm Subject: bzr push into mysql-5.1-bugteam branch (Alexey.Kopytov:2995 to 2996) List-Archive: http://lists.mysql.com/commits/77882 Message-Id: <20090703105210.86F9151AF@kaamos.local> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="Boundary_(ID_tCNN4C/+Pu5wQRSwYLwVpQ)" --Boundary_(ID_tCNN4C/+Pu5wQRSwYLwVpQ) MIME-version: 1.0 Content-type: text/plain; CHARSET=US-ASCII Content-transfer-encoding: 7BIT Content-disposition: inline 2996 Alexey Kopytov 2009-07-03 [merge] Automerge. modified: mysql-test/r/type_newdecimal.result mysql-test/t/type_newdecimal.test sql/item.cc sql/item_cmpfunc.cc sql/item_func.cc sql/item_func.h sql/item_sum.cc sql/my_decimal.h sql/sql_select.cc 2995 Sergey Glukhov 2009-07-03 [merge] 5.0-bugteam->5.1-bugteam merge @ mysql-test/r/view.result 5.0-bugteam->5.1-bugteam merge @ mysql-test/t/view.test 5.0-bugteam->5.1-bugteam merge @ sql/sql_insert.cc 5.0-bugteam->5.1-bugteam merge modified: mysql-test/r/view.result mysql-test/t/view.test sql/sql_insert.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-03 10:36:04 +0000 @@ -1524,10 +1524,10 @@ Warnings: Warning 1264 Out of range value for column 'f1' at row 1 DESC t1; Field Type Null Key Default Extra -f1 decimal(59,30) NO 0.000000000000000000000000000000 +f1 decimal(65,30) NO 0.000000000000000000000000000000 SELECT f1 FROM t1; f1 -99999999999999999999999999999.999999999999999999999999999999 +99999999999999999999999999999999999.999999999999999999999999999999 DROP TABLE t1; select (1.20396873 * 0.89550000 * 0.68000000 * 1.08721696 * 0.99500000 * 1.01500000 * 1.01500000 * 0.99500000); @@ -1577,3 +1577,56 @@ Error 1264 Out of range value for column select cast(98.6 as decimal(2,0)); cast(98.6 as decimal(2,0)) 99 +# +# Bug #45262: Bad effects with CREATE TABLE and DECIMAL +# +CREATE TABLE t1 SELECT .123456789123456789123456789123456789123456789123456789123456789123456789123456789 AS my_col; +Warnings: +Note 1265 Data truncated for column 'my_col' at row 1 +DESCRIBE t1; +Field Type Null Key Default Extra +my_col decimal(30,30) NO 0.000000000000000000000000000000 +SELECT my_col FROM t1; +my_col +0.123456789123456789123456789123 +DROP TABLE t1; +CREATE TABLE t1 SELECT 1 + .123456789123456789123456789123456789123456789123456789123456789123456789123456789 AS my_col; +Warnings: +Note 1265 Data truncated for column 'my_col' at row 1 +DESCRIBE t1; +Field Type Null Key Default Extra +my_col decimal(65,30) NO 0.000000000000000000000000000000 +SELECT my_col FROM t1; +my_col +1.123456789123456789123456789123 +DROP TABLE t1; +CREATE TABLE t1 SELECT 1 * .123456789123456789123456789123456789123456789123456789123456789123456789123456789 AS my_col; +Warnings: +Note 1265 Data truncated for column 'my_col' at row 1 +DESCRIBE t1; +Field Type Null Key Default Extra +my_col decimal(65,30) NO 0.000000000000000000000000000000 +SELECT my_col FROM t1; +my_col +0.123456789123456789123456789123 +DROP TABLE t1; +CREATE TABLE t1 SELECT 1 / .123456789123456789123456789123456789123456789123456789123456789123456789123456789 AS my_col; +Warnings: +Note 1265 Data truncated for column 'my_col' at row 1 +DESCRIBE t1; +Field Type Null Key Default Extra +my_col decimal(65,4) YES NULL +SELECT my_col FROM t1; +my_col +8.1000 +DROP TABLE t1; +CREATE TABLE t1 SELECT 1 % .123456789123456789123456789123456789123456789123456789123456789123456789123456789 AS my_col; +Warnings: +Note 1265 Data truncated for column 'my_col' at row 1 +DESCRIBE t1; +Field Type Null Key Default Extra +my_col decimal(65,30) YES NULL +SELECT my_col FROM t1; +my_col +0.012345687012345687012345687012 +DROP TABLE t1; === 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-03 10:36:04 +0000 @@ -1257,3 +1257,32 @@ 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)); + +--echo # +--echo # Bug #45262: Bad effects with CREATE TABLE and DECIMAL +--echo # + +CREATE TABLE t1 SELECT .123456789123456789123456789123456789123456789123456789123456789123456789123456789 AS my_col; +DESCRIBE t1; +SELECT my_col FROM t1; +DROP TABLE t1; + +CREATE TABLE t1 SELECT 1 + .123456789123456789123456789123456789123456789123456789123456789123456789123456789 AS my_col; +DESCRIBE t1; +SELECT my_col FROM t1; +DROP TABLE t1; + +CREATE TABLE t1 SELECT 1 * .123456789123456789123456789123456789123456789123456789123456789123456789123456789 AS my_col; +DESCRIBE t1; +SELECT my_col FROM t1; +DROP TABLE t1; + +CREATE TABLE t1 SELECT 1 / .123456789123456789123456789123456789123456789123456789123456789123456789123456789 AS my_col; +DESCRIBE t1; +SELECT my_col FROM t1; +DROP TABLE t1; + +CREATE TABLE t1 SELECT 1 % .123456789123456789123456789123456789123456789123456789123456789123456789123456789 AS my_col; +DESCRIBE t1; +SELECT my_col FROM t1; +DROP TABLE t1; === modified file 'sql/item.cc' --- a/sql/item.cc 2009-07-02 14:42:00 +0000 +++ b/sql/item.cc 2009-07-03 10:43:54 +0000 @@ -2260,8 +2260,10 @@ Item_decimal::Item_decimal(const char *s name= (char*) str_arg; decimals= (uint8) decimal_value.frac; fixed= 1; - max_length= my_decimal_precision_to_length(decimal_value.intg + decimals, - decimals, unsigned_flag); + max_length= my_decimal_precision_to_length_no_truncation(decimal_value.intg + + decimals, + decimals, + unsigned_flag); } Item_decimal::Item_decimal(longlong val, bool unsig) @@ -2269,8 +2271,10 @@ Item_decimal::Item_decimal(longlong val, int2my_decimal(E_DEC_FATAL_ERROR, val, unsig, &decimal_value); decimals= (uint8) decimal_value.frac; fixed= 1; - max_length= my_decimal_precision_to_length(decimal_value.intg + decimals, - decimals, unsigned_flag); + max_length= my_decimal_precision_to_length_no_truncation(decimal_value.intg + + decimals, + decimals, + unsigned_flag); } @@ -2279,8 +2283,10 @@ Item_decimal::Item_decimal(double val, i double2my_decimal(E_DEC_FATAL_ERROR, val, &decimal_value); decimals= (uint8) decimal_value.frac; fixed= 1; - max_length= my_decimal_precision_to_length(decimal_value.intg + decimals, - decimals, unsigned_flag); + max_length= my_decimal_precision_to_length_no_truncation(decimal_value.intg + + decimals, + decimals, + unsigned_flag); } @@ -2300,8 +2306,10 @@ Item_decimal::Item_decimal(my_decimal *v my_decimal2decimal(value_par, &decimal_value); decimals= (uint8) decimal_value.frac; fixed= 1; - max_length= my_decimal_precision_to_length(decimal_value.intg + decimals, - decimals, unsigned_flag); + max_length= my_decimal_precision_to_length_no_truncation(decimal_value.intg + + decimals, + decimals, + unsigned_flag); } @@ -2311,8 +2319,8 @@ Item_decimal::Item_decimal(const uchar * &decimal_value, precision, scale); decimals= (uint8) decimal_value.frac; fixed= 1; - max_length= my_decimal_precision_to_length(precision, decimals, - unsigned_flag); + max_length= my_decimal_precision_to_length_no_truncation(precision, decimals, + unsigned_flag); } @@ -2367,8 +2375,10 @@ void Item_decimal::set_decimal_value(my_ my_decimal2decimal(value_par, &decimal_value); decimals= (uint8) decimal_value.frac; unsigned_flag= !decimal_value.sign(); - max_length= my_decimal_precision_to_length(decimal_value.intg + decimals, - decimals, unsigned_flag); + max_length= my_decimal_precision_to_length_no_truncation(decimal_value.intg + + decimals, + decimals, + unsigned_flag); } @@ -2640,8 +2650,9 @@ void Item_param::set_decimal(const char str2my_decimal(E_DEC_FATAL_ERROR, str, &decimal_value, &end); state= DECIMAL_VALUE; decimals= decimal_value.frac; - max_length= my_decimal_precision_to_length(decimal_value.precision(), - decimals, unsigned_flag); + max_length= + my_decimal_precision_to_length_no_truncation(decimal_value.precision(), + decimals, unsigned_flag); maybe_null= 0; DBUG_VOID_RETURN; } @@ -2797,8 +2808,9 @@ bool Item_param::set_from_user_var(THD * my_decimal2decimal(ent_value, &decimal_value); state= DECIMAL_VALUE; decimals= ent_value->frac; - max_length= my_decimal_precision_to_length(ent_value->precision(), - decimals, unsigned_flag); + max_length= + my_decimal_precision_to_length_no_truncation(ent_value->precision(), + decimals, unsigned_flag); item_type= Item::DECIMAL_ITEM; break; } @@ -7296,8 +7308,9 @@ bool Item_type_holder::join_types(THD *t int item_prec = max(prev_decimal_int_part, item_int_part) + decimals; int precision= min(item_prec, DECIMAL_MAX_PRECISION); unsigned_flag&= item->unsigned_flag; - max_length= my_decimal_precision_to_length(precision, decimals, - unsigned_flag); + max_length= my_decimal_precision_to_length_no_truncation(precision, + decimals, + unsigned_flag); } switch (Field::result_merge_type(fld_type)) === modified file 'sql/item_cmpfunc.cc' --- a/sql/item_cmpfunc.cc 2009-06-09 16:44:26 +0000 +++ b/sql/item_cmpfunc.cc 2009-07-03 10:36:04 +0000 @@ -2760,8 +2760,9 @@ void Item_func_case::fix_length_and_dec( agg_num_lengths(args[i + 1]); if (else_expr_num != -1) agg_num_lengths(args[else_expr_num]); - max_length= my_decimal_precision_to_length(max_length + decimals, decimals, - unsigned_flag); + max_length= my_decimal_precision_to_length_no_truncation(max_length + + decimals, decimals, + unsigned_flag); } } === modified file 'sql/item_func.cc' --- a/sql/item_func.cc 2009-06-09 16:44:26 +0000 +++ b/sql/item_func.cc 2009-07-03 10:36:04 +0000 @@ -452,11 +452,45 @@ Field *Item_func::tmp_table_field(TABLE return make_string_field(table); break; case DECIMAL_RESULT: - field= new Field_new_decimal(my_decimal_precision_to_length(decimal_precision(), - decimals, - unsigned_flag), - maybe_null, name, decimals, unsigned_flag); + { + uint8 dec= decimals; + uint8 intg= decimal_precision() - dec; + uint32 len= max_length; + + /* + Trying to put too many digits overall in a DECIMAL(prec,dec) + will always throw a warning. We must limit dec to + DECIMAL_MAX_SCALE however to prevent an assert() later. + */ + + if (dec > 0) + { + int overflow; + + dec= min(dec, DECIMAL_MAX_SCALE); + + /* + If the value still overflows the field with the corrected dec, + we'll throw out decimals rather than integers. This is still + bad and of course throws a truncation warning. + */ + + const int required_length= + my_decimal_precision_to_length(intg + dec, dec, + unsigned_flag); + + overflow= required_length - len; + + if (overflow > 0) + dec= max(0, dec - overflow); // too long, discard fract + else + /* Corrected value fits. */ + len= required_length; + } + + field= new Field_new_decimal(len, maybe_null, name, dec, unsigned_flag); break; + } case ROW_RESULT: default: // This case should never be chosen @@ -545,8 +579,8 @@ void Item_func::count_decimal_length() set_if_smaller(unsigned_flag, args[i]->unsigned_flag); } int precision= min(max_int_part + decimals, DECIMAL_MAX_PRECISION); - max_length= my_decimal_precision_to_length(precision, decimals, - unsigned_flag); + max_length= my_decimal_precision_to_length_no_truncation(precision, decimals, + unsigned_flag); } @@ -1141,16 +1175,15 @@ void Item_func_additive_op::result_preci decimals= max(args[0]->decimals, args[1]->decimals); int arg1_int= args[0]->decimal_precision() - args[0]->decimals; int arg2_int= args[1]->decimal_precision() - args[1]->decimals; - int est_prec= max(arg1_int, arg2_int) + 1 + decimals; - int precision= min(est_prec, DECIMAL_MAX_PRECISION); + int precision= max(arg1_int, arg2_int) + 1 + decimals; /* Integer operations keep unsigned_flag if one of arguments is unsigned */ if (result_type() == INT_RESULT) unsigned_flag= args[0]->unsigned_flag | args[1]->unsigned_flag; else unsigned_flag= args[0]->unsigned_flag & args[1]->unsigned_flag; - max_length= my_decimal_precision_to_length(precision, decimals, - unsigned_flag); + max_length= my_decimal_precision_to_length_no_truncation(precision, decimals, + unsigned_flag); } @@ -1255,7 +1288,8 @@ void Item_func_mul::result_precision() decimals= min(args[0]->decimals + args[1]->decimals, DECIMAL_MAX_SCALE); uint est_prec = args[0]->decimal_precision() + args[1]->decimal_precision(); uint precision= min(est_prec, DECIMAL_MAX_PRECISION); - max_length= my_decimal_precision_to_length(precision, decimals,unsigned_flag); + max_length= my_decimal_precision_to_length_no_truncation(precision, decimals, + unsigned_flag); } @@ -1311,8 +1345,8 @@ void Item_func_div::result_precision() else unsigned_flag= args[0]->unsigned_flag & args[1]->unsigned_flag; decimals= min(args[0]->decimals + prec_increment, DECIMAL_MAX_SCALE); - max_length= my_decimal_precision_to_length(precision, decimals, - unsigned_flag); + max_length= my_decimal_precision_to_length_no_truncation(precision, decimals, + unsigned_flag); } @@ -1999,8 +2033,9 @@ void Item_func_round::fix_length_and_dec precision-= decimals_delta - length_increase; decimals= min(decimals_to_set, DECIMAL_MAX_SCALE); - max_length= my_decimal_precision_to_length(precision, decimals, - unsigned_flag); + max_length= my_decimal_precision_to_length_no_truncation(precision, + decimals, + unsigned_flag); break; } default: @@ -2243,8 +2278,9 @@ void Item_func_min_max::fix_length_and_d } } else if ((cmp_type == DECIMAL_RESULT) || (cmp_type == INT_RESULT)) - max_length= my_decimal_precision_to_length(max_int_part+decimals, decimals, - unsigned_flag); + max_length= my_decimal_precision_to_length_no_truncation(max_int_part + + decimals, decimals, + unsigned_flag); cached_field_type= agg_field_type(args, arg_count); } === modified file 'sql/item_func.h' --- a/sql/item_func.h 2009-05-21 20:22:46 +0000 +++ b/sql/item_func.h 2009-07-03 10:36:04 +0000 @@ -378,7 +378,8 @@ public: Item_decimal_typecast(Item *a, int len, int dec) :Item_func(a) { decimals= dec; - max_length= my_decimal_precision_to_length(len, dec, unsigned_flag); + max_length= my_decimal_precision_to_length_no_truncation(len, dec, + unsigned_flag); } String *val_str(String *str); double val_real(); === modified file 'sql/item_sum.cc' --- a/sql/item_sum.cc 2009-06-15 15:57:06 +0000 +++ b/sql/item_sum.cc 2009-07-03 10:36:04 +0000 @@ -798,8 +798,9 @@ void Item_sum_sum::fix_length_and_dec() { /* SUM result can't be longer than length(arg) + length(MAX_ROWS) */ int precision= args[0]->decimal_precision() + DECIMAL_LONGLONG_DIGITS; - max_length= my_decimal_precision_to_length(precision, decimals, - unsigned_flag); + max_length= my_decimal_precision_to_length_no_truncation(precision, + decimals, + unsigned_flag); curr_dec_buff= 0; hybrid_type= DECIMAL_RESULT; my_decimal_set_zero(dec_buffs); @@ -1233,8 +1234,9 @@ void Item_sum_avg::fix_length_and_dec() { int precision= args[0]->decimal_precision() + prec_increment; decimals= min(args[0]->decimals + prec_increment, DECIMAL_MAX_SCALE); - max_length= my_decimal_precision_to_length(precision, decimals, - unsigned_flag); + max_length= my_decimal_precision_to_length_no_truncation(precision, + decimals, + unsigned_flag); f_precision= min(precision+DECIMAL_LONGLONG_DIGITS, DECIMAL_MAX_PRECISION); f_scale= args[0]->decimals; dec_bin_size= my_decimal_get_binary_size(f_precision, f_scale); @@ -1439,8 +1441,9 @@ void Item_sum_variance::fix_length_and_d { int precision= args[0]->decimal_precision()*2 + prec_increment; decimals= min(args[0]->decimals + prec_increment, DECIMAL_MAX_SCALE); - max_length= my_decimal_precision_to_length(precision, decimals, - unsigned_flag); + max_length= my_decimal_precision_to_length_no_truncation(precision, + decimals, + unsigned_flag); break; } === 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-03 10:36:04 +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-26 19:57:42 +0000 +++ b/sql/sql_select.cc 2009-07-03 10:43:54 +0000 @@ -9391,13 +9391,17 @@ static Field *create_tmp_field_from_item +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(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, --Boundary_(ID_tCNN4C/+Pu5wQRSwYLwVpQ) MIME-version: 1.0 Content-type: text/bzr-bundle; CHARSET=US-ASCII; name="bzr/alexey.kopytov@stripped" Content-transfer-encoding: 7BIT Content-disposition: inline; filename="bzr/alexey.kopytov@stripped" # Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: alexey.kopytov@stripped # target_branch: file:///data/src/bzr/bugteam/mysql-5.1-bugteam/ # testament_sha1: 7a5f5c5b7c58ba7b057ad62f872030049413e888 # timestamp: 2009-07-03 14:52:10 +0400 # source_branch: file:///data/src/bzr/bugteam/bug45236/my51-bug45236/ # base_revision_id: sergey.glukhov@stripped\ # a6ejp0imgq25b9tb # # Begin bundle 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 --Boundary_(ID_tCNN4C/+Pu5wQRSwYLwVpQ)--