Loading mysql-test/r/type_newdecimal.result +25 −3 Original line number Diff line number Diff line Loading @@ -846,15 +846,14 @@ select 0/0; NULL select 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 as x; x 999999999999999999999999999999999999999999999999999999999999999999999999999999999 99999999999999999999999999999999999999999999999999999999999999999 Warnings: Error 1292 Truncated incorrect DECIMAL value: '' select 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 + 1 as x; x NULL 100000000000000000000000000000000000000000000000000000000000000000 Warnings: Error 1292 Truncated incorrect DECIMAL value: '' Error 1292 Truncated incorrect DECIMAL value: '' select 0.190287977636363637 + 0.040372670 * 0 - 0; 0.190287977636363637 + 0.040372670 * 0 - 0 0.190287977636363637 Loading Loading @@ -1021,3 +1020,26 @@ cast(@non_existing_user_var/2 as DECIMAL) NULL create table t (d decimal(0,10)); ERROR 42000: For float(M,D), double(M,D) or decimal(M,D), M must be >= D (column 'd'). create table t1 (c1 decimal(64)); insert into t1 values( 89000000000000000000000000000000000000000000000000000000000000000000000000000000000000000); Warnings: Error 1292 Truncated incorrect DECIMAL value: '' Warning 1264 Out of range value adjusted for column 'c1' at row 1 insert into t1 values( 99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 * 99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999); Warnings: Error 1292 Truncated incorrect DECIMAL value: '' Error 1292 Truncated incorrect DECIMAL value: '' Error 1292 Truncated incorrect DECIMAL value: '' Warning 1264 Out of range value adjusted for column 'c1' at row 1 insert into t1 values(1e100); Warnings: Warning 1264 Out of range value adjusted for column 'c1' at row 1 select * from t1; c1 9999999999999999999999999999999999999999999999999999999999999999 9999999999999999999999999999999999999999999999999999999999999999 9999999999999999999999999999999999999999999999999999999999999999 drop table t1; mysql-test/t/type_newdecimal.test +14 −0 Original line number Diff line number Diff line Loading @@ -1050,3 +1050,17 @@ select cast(@non_existing_user_var/2 as DECIMAL); # --error 1427 create table t (d decimal(0,10)); # # Bug #13573 (Wrong data inserted for too big values) # create table t1 (c1 decimal(64)); insert into t1 values( 89000000000000000000000000000000000000000000000000000000000000000000000000000000000000000); insert into t1 values( 99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 * 99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999); insert into t1 values(1e100); select * from t1; drop table t1; sql/item_func.cc +14 −15 Original line number Diff line number Diff line Loading @@ -972,8 +972,8 @@ my_decimal *Item_func_plus::decimal_op(my_decimal *decimal_value) return 0; val2= args[1]->val_decimal(&value2); if (!(null_value= (args[1]->null_value || my_decimal_add(E_DEC_FATAL_ERROR, decimal_value, val1, val2) > 1))) (my_decimal_add(E_DEC_FATAL_ERROR, decimal_value, val1, val2) > 3)))) return decimal_value; return 0; } Loading Loading @@ -1045,8 +1045,8 @@ my_decimal *Item_func_minus::decimal_op(my_decimal *decimal_value) return 0; val2= args[1]->val_decimal(&value2); if (!(null_value= (args[1]->null_value || my_decimal_sub(E_DEC_FATAL_ERROR, decimal_value, val1, val2) > 1))) (my_decimal_sub(E_DEC_FATAL_ERROR, decimal_value, val1, val2) > 3)))) return decimal_value; return 0; } Loading Loading @@ -1083,8 +1083,8 @@ my_decimal *Item_func_mul::decimal_op(my_decimal *decimal_value) return 0; val2= args[1]->val_decimal(&value2); if (!(null_value= (args[1]->null_value || my_decimal_mul(E_DEC_FATAL_ERROR, decimal_value, val1, val2) > 1))) (my_decimal_mul(E_DEC_FATAL_ERROR, decimal_value, val1, val2) > 3)))) return decimal_value; return 0; } Loading Loading @@ -1124,6 +1124,7 @@ my_decimal *Item_func_div::decimal_op(my_decimal *decimal_value) { my_decimal value1, *val1; my_decimal value2, *val2; int err; val1= args[0]->val_decimal(&value1); if ((null_value= args[0]->null_value)) Loading @@ -1131,17 +1132,15 @@ my_decimal *Item_func_div::decimal_op(my_decimal *decimal_value) val2= args[1]->val_decimal(&value2); if ((null_value= args[1]->null_value)) return 0; switch (my_decimal_div(E_DEC_FATAL_ERROR & ~E_DEC_DIV_ZERO, decimal_value, val1, val2, prec_increment)) { case E_DEC_TRUNCATED: case E_DEC_OK: return decimal_value; case E_DEC_DIV_ZERO: if ((err= my_decimal_div(E_DEC_FATAL_ERROR & ~E_DEC_DIV_ZERO, decimal_value, val1, val2, prec_increment)) > 3) { if (err == E_DEC_DIV_ZERO) signal_divide_by_null(); default: null_value= 1; // Safety null_value= 1; return 0; } return decimal_value; } Loading sql/my_decimal.cc +1 −1 Original line number Diff line number Diff line Loading @@ -185,7 +185,7 @@ int str2my_decimal(uint mask, const char *from, uint length, } } } check_result(mask, err); check_result_and_overflow(mask, err, decimal_value); return err; } Loading sql/my_decimal.h +44 −16 Original line number Diff line number Diff line Loading @@ -126,6 +126,19 @@ inline int decimal_operation_results(int result) } #endif /*MYSQL_CLIENT*/ inline void max_my_decimal(my_decimal *to, int precision, int frac) { DBUG_ASSERT((precision <= DECIMAL_MAX_PRECISION)&& (frac <= DECIMAL_MAX_SCALE)); max_decimal(precision, frac, (decimal_t*) to); } inline void max_internal_decimal(my_decimal *to) { max_my_decimal(to, DECIMAL_MAX_PRECISION, 0); } inline int check_result(uint mask, int result) { if (result & mask) Loading @@ -133,6 +146,18 @@ inline int check_result(uint mask, int result) return result; } inline int check_result_and_overflow(uint mask, int result, my_decimal *val) { if (check_result(mask, result) & E_DEC_OVERFLOW) { bool sign= val->sign(); val->fix_buffer_pointer(); max_internal_decimal(val); val->sign(sign); } return result; } inline uint my_decimal_length_to_precision(uint length, uint scale, bool unsigned_flag) { Loading Loading @@ -256,7 +281,8 @@ int my_decimal2double(uint mask, const my_decimal *d, double *result) inline int str2my_decimal(uint mask, const char *str, my_decimal *d, char **end) { return check_result(mask, string2decimal(str, (decimal_t*) d, end)); return check_result_and_overflow(mask, string2decimal(str,(decimal_t*)d,end), d); } Loading @@ -274,7 +300,7 @@ int string2my_decimal(uint mask, const String *str, my_decimal *d) inline int double2my_decimal(uint mask, double val, my_decimal *d) { return check_result(mask, double2decimal(val, (decimal_t*) d)); return check_result_and_overflow(mask, double2decimal(val, (decimal_t*)d), d); } Loading Loading @@ -303,7 +329,9 @@ inline int my_decimal_add(uint mask, my_decimal *res, const my_decimal *a, const my_decimal *b) { return check_result(mask, decimal_add((decimal_t*) a, (decimal_t*) b, res)); return check_result_and_overflow(mask, decimal_add((decimal_t*)a,(decimal_t*)b,res), res); } Loading @@ -311,7 +339,9 @@ inline int my_decimal_sub(uint mask, my_decimal *res, const my_decimal *a, const my_decimal *b) { return check_result(mask, decimal_sub((decimal_t*) a, (decimal_t*) b, res)); return check_result_and_overflow(mask, decimal_sub((decimal_t*)a,(decimal_t*)b,res), res); } Loading @@ -319,7 +349,9 @@ inline int my_decimal_mul(uint mask, my_decimal *res, const my_decimal *a, const my_decimal *b) { return check_result(mask, decimal_mul((decimal_t*) a, (decimal_t*) b, res)); return check_result_and_overflow(mask, decimal_mul((decimal_t*)a,(decimal_t*)b,res), res); } Loading @@ -327,8 +359,10 @@ inline int my_decimal_div(uint mask, my_decimal *res, const my_decimal *a, const my_decimal *b, int div_scale_inc) { return check_result(mask, decimal_div((decimal_t*) a, (decimal_t*) b, res, div_scale_inc)); return check_result_and_overflow(mask, decimal_div((decimal_t*)a,(decimal_t*)b,res, div_scale_inc), res); } Loading @@ -336,7 +370,9 @@ inline int my_decimal_mod(uint mask, my_decimal *res, const my_decimal *a, const my_decimal *b) { return check_result(mask, decimal_mod((decimal_t*) a, (decimal_t*) b, res)); return check_result_and_overflow(mask, decimal_mod((decimal_t*)a,(decimal_t*)b,res), res); } Loading @@ -347,13 +383,5 @@ int my_decimal_cmp(const my_decimal *a, const my_decimal *b) return decimal_cmp((decimal_t*) a, (decimal_t*) b); } inline void max_my_decimal(my_decimal *to, int precision, int frac) { DBUG_ASSERT((precision <= DECIMAL_MAX_PRECISION)&& (frac <= DECIMAL_MAX_SCALE)); max_decimal(precision, frac, (decimal_t*) to); } #endif /*my_decimal_h*/ Loading
mysql-test/r/type_newdecimal.result +25 −3 Original line number Diff line number Diff line Loading @@ -846,15 +846,14 @@ select 0/0; NULL select 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 as x; x 999999999999999999999999999999999999999999999999999999999999999999999999999999999 99999999999999999999999999999999999999999999999999999999999999999 Warnings: Error 1292 Truncated incorrect DECIMAL value: '' select 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 + 1 as x; x NULL 100000000000000000000000000000000000000000000000000000000000000000 Warnings: Error 1292 Truncated incorrect DECIMAL value: '' Error 1292 Truncated incorrect DECIMAL value: '' select 0.190287977636363637 + 0.040372670 * 0 - 0; 0.190287977636363637 + 0.040372670 * 0 - 0 0.190287977636363637 Loading Loading @@ -1021,3 +1020,26 @@ cast(@non_existing_user_var/2 as DECIMAL) NULL create table t (d decimal(0,10)); ERROR 42000: For float(M,D), double(M,D) or decimal(M,D), M must be >= D (column 'd'). create table t1 (c1 decimal(64)); insert into t1 values( 89000000000000000000000000000000000000000000000000000000000000000000000000000000000000000); Warnings: Error 1292 Truncated incorrect DECIMAL value: '' Warning 1264 Out of range value adjusted for column 'c1' at row 1 insert into t1 values( 99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 * 99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999); Warnings: Error 1292 Truncated incorrect DECIMAL value: '' Error 1292 Truncated incorrect DECIMAL value: '' Error 1292 Truncated incorrect DECIMAL value: '' Warning 1264 Out of range value adjusted for column 'c1' at row 1 insert into t1 values(1e100); Warnings: Warning 1264 Out of range value adjusted for column 'c1' at row 1 select * from t1; c1 9999999999999999999999999999999999999999999999999999999999999999 9999999999999999999999999999999999999999999999999999999999999999 9999999999999999999999999999999999999999999999999999999999999999 drop table t1;
mysql-test/t/type_newdecimal.test +14 −0 Original line number Diff line number Diff line Loading @@ -1050,3 +1050,17 @@ select cast(@non_existing_user_var/2 as DECIMAL); # --error 1427 create table t (d decimal(0,10)); # # Bug #13573 (Wrong data inserted for too big values) # create table t1 (c1 decimal(64)); insert into t1 values( 89000000000000000000000000000000000000000000000000000000000000000000000000000000000000000); insert into t1 values( 99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 * 99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999); insert into t1 values(1e100); select * from t1; drop table t1;
sql/item_func.cc +14 −15 Original line number Diff line number Diff line Loading @@ -972,8 +972,8 @@ my_decimal *Item_func_plus::decimal_op(my_decimal *decimal_value) return 0; val2= args[1]->val_decimal(&value2); if (!(null_value= (args[1]->null_value || my_decimal_add(E_DEC_FATAL_ERROR, decimal_value, val1, val2) > 1))) (my_decimal_add(E_DEC_FATAL_ERROR, decimal_value, val1, val2) > 3)))) return decimal_value; return 0; } Loading Loading @@ -1045,8 +1045,8 @@ my_decimal *Item_func_minus::decimal_op(my_decimal *decimal_value) return 0; val2= args[1]->val_decimal(&value2); if (!(null_value= (args[1]->null_value || my_decimal_sub(E_DEC_FATAL_ERROR, decimal_value, val1, val2) > 1))) (my_decimal_sub(E_DEC_FATAL_ERROR, decimal_value, val1, val2) > 3)))) return decimal_value; return 0; } Loading Loading @@ -1083,8 +1083,8 @@ my_decimal *Item_func_mul::decimal_op(my_decimal *decimal_value) return 0; val2= args[1]->val_decimal(&value2); if (!(null_value= (args[1]->null_value || my_decimal_mul(E_DEC_FATAL_ERROR, decimal_value, val1, val2) > 1))) (my_decimal_mul(E_DEC_FATAL_ERROR, decimal_value, val1, val2) > 3)))) return decimal_value; return 0; } Loading Loading @@ -1124,6 +1124,7 @@ my_decimal *Item_func_div::decimal_op(my_decimal *decimal_value) { my_decimal value1, *val1; my_decimal value2, *val2; int err; val1= args[0]->val_decimal(&value1); if ((null_value= args[0]->null_value)) Loading @@ -1131,17 +1132,15 @@ my_decimal *Item_func_div::decimal_op(my_decimal *decimal_value) val2= args[1]->val_decimal(&value2); if ((null_value= args[1]->null_value)) return 0; switch (my_decimal_div(E_DEC_FATAL_ERROR & ~E_DEC_DIV_ZERO, decimal_value, val1, val2, prec_increment)) { case E_DEC_TRUNCATED: case E_DEC_OK: return decimal_value; case E_DEC_DIV_ZERO: if ((err= my_decimal_div(E_DEC_FATAL_ERROR & ~E_DEC_DIV_ZERO, decimal_value, val1, val2, prec_increment)) > 3) { if (err == E_DEC_DIV_ZERO) signal_divide_by_null(); default: null_value= 1; // Safety null_value= 1; return 0; } return decimal_value; } Loading
sql/my_decimal.cc +1 −1 Original line number Diff line number Diff line Loading @@ -185,7 +185,7 @@ int str2my_decimal(uint mask, const char *from, uint length, } } } check_result(mask, err); check_result_and_overflow(mask, err, decimal_value); return err; } Loading
sql/my_decimal.h +44 −16 Original line number Diff line number Diff line Loading @@ -126,6 +126,19 @@ inline int decimal_operation_results(int result) } #endif /*MYSQL_CLIENT*/ inline void max_my_decimal(my_decimal *to, int precision, int frac) { DBUG_ASSERT((precision <= DECIMAL_MAX_PRECISION)&& (frac <= DECIMAL_MAX_SCALE)); max_decimal(precision, frac, (decimal_t*) to); } inline void max_internal_decimal(my_decimal *to) { max_my_decimal(to, DECIMAL_MAX_PRECISION, 0); } inline int check_result(uint mask, int result) { if (result & mask) Loading @@ -133,6 +146,18 @@ inline int check_result(uint mask, int result) return result; } inline int check_result_and_overflow(uint mask, int result, my_decimal *val) { if (check_result(mask, result) & E_DEC_OVERFLOW) { bool sign= val->sign(); val->fix_buffer_pointer(); max_internal_decimal(val); val->sign(sign); } return result; } inline uint my_decimal_length_to_precision(uint length, uint scale, bool unsigned_flag) { Loading Loading @@ -256,7 +281,8 @@ int my_decimal2double(uint mask, const my_decimal *d, double *result) inline int str2my_decimal(uint mask, const char *str, my_decimal *d, char **end) { return check_result(mask, string2decimal(str, (decimal_t*) d, end)); return check_result_and_overflow(mask, string2decimal(str,(decimal_t*)d,end), d); } Loading @@ -274,7 +300,7 @@ int string2my_decimal(uint mask, const String *str, my_decimal *d) inline int double2my_decimal(uint mask, double val, my_decimal *d) { return check_result(mask, double2decimal(val, (decimal_t*) d)); return check_result_and_overflow(mask, double2decimal(val, (decimal_t*)d), d); } Loading Loading @@ -303,7 +329,9 @@ inline int my_decimal_add(uint mask, my_decimal *res, const my_decimal *a, const my_decimal *b) { return check_result(mask, decimal_add((decimal_t*) a, (decimal_t*) b, res)); return check_result_and_overflow(mask, decimal_add((decimal_t*)a,(decimal_t*)b,res), res); } Loading @@ -311,7 +339,9 @@ inline int my_decimal_sub(uint mask, my_decimal *res, const my_decimal *a, const my_decimal *b) { return check_result(mask, decimal_sub((decimal_t*) a, (decimal_t*) b, res)); return check_result_and_overflow(mask, decimal_sub((decimal_t*)a,(decimal_t*)b,res), res); } Loading @@ -319,7 +349,9 @@ inline int my_decimal_mul(uint mask, my_decimal *res, const my_decimal *a, const my_decimal *b) { return check_result(mask, decimal_mul((decimal_t*) a, (decimal_t*) b, res)); return check_result_and_overflow(mask, decimal_mul((decimal_t*)a,(decimal_t*)b,res), res); } Loading @@ -327,8 +359,10 @@ inline int my_decimal_div(uint mask, my_decimal *res, const my_decimal *a, const my_decimal *b, int div_scale_inc) { return check_result(mask, decimal_div((decimal_t*) a, (decimal_t*) b, res, div_scale_inc)); return check_result_and_overflow(mask, decimal_div((decimal_t*)a,(decimal_t*)b,res, div_scale_inc), res); } Loading @@ -336,7 +370,9 @@ inline int my_decimal_mod(uint mask, my_decimal *res, const my_decimal *a, const my_decimal *b) { return check_result(mask, decimal_mod((decimal_t*) a, (decimal_t*) b, res)); return check_result_and_overflow(mask, decimal_mod((decimal_t*)a,(decimal_t*)b,res), res); } Loading @@ -347,13 +383,5 @@ int my_decimal_cmp(const my_decimal *a, const my_decimal *b) return decimal_cmp((decimal_t*) a, (decimal_t*) b); } inline void max_my_decimal(my_decimal *to, int precision, int frac) { DBUG_ASSERT((precision <= DECIMAL_MAX_PRECISION)&& (frac <= DECIMAL_MAX_SCALE)); max_decimal(precision, frac, (decimal_t*) to); } #endif /*my_decimal_h*/