mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
Bug#16172 DECIMAL data type processed incorrectly
issue an 'overflow warning' if result value is bigger than max possible value
This commit is contained in:
@ -48,6 +48,7 @@ int decimal_bin_size(int precision, int scale);
|
|||||||
int decimal_result_size(decimal_t *from1, decimal_t *from2, char op,
|
int decimal_result_size(decimal_t *from1, decimal_t *from2, char op,
|
||||||
int param);
|
int param);
|
||||||
|
|
||||||
|
int decimal_intg(decimal_t *from);
|
||||||
int decimal_add(decimal_t *from1, decimal_t *from2, decimal_t *to);
|
int decimal_add(decimal_t *from1, decimal_t *from2, decimal_t *to);
|
||||||
int decimal_sub(decimal_t *from1, decimal_t *from2, decimal_t *to);
|
int decimal_sub(decimal_t *from1, decimal_t *from2, decimal_t *to);
|
||||||
int decimal_cmp(decimal_t *from1, decimal_t *from2);
|
int decimal_cmp(decimal_t *from1, decimal_t *from2);
|
||||||
|
@ -103,7 +103,7 @@ Warnings:
|
|||||||
Warning 1292 Truncated incorrect DOUBLE value: 'a'
|
Warning 1292 Truncated incorrect DOUBLE value: 'a'
|
||||||
select 10.0+cast('a' as decimal);
|
select 10.0+cast('a' as decimal);
|
||||||
10.0+cast('a' as decimal)
|
10.0+cast('a' as decimal)
|
||||||
10.00
|
10.0
|
||||||
Warnings:
|
Warnings:
|
||||||
Warning 1292 Truncated incorrect DECIMAL value: 'a'
|
Warning 1292 Truncated incorrect DECIMAL value: 'a'
|
||||||
select 10E+0+'a';
|
select 10E+0+'a';
|
||||||
@ -368,7 +368,9 @@ create table t1(s1 time);
|
|||||||
insert into t1 values ('11:11:11');
|
insert into t1 values ('11:11:11');
|
||||||
select cast(s1 as decimal(7,2)) from t1;
|
select cast(s1 as decimal(7,2)) from t1;
|
||||||
cast(s1 as decimal(7,2))
|
cast(s1 as decimal(7,2))
|
||||||
111111.00
|
99999.99
|
||||||
|
Warnings:
|
||||||
|
Error 1264 Out of range value for column 'cast(s1 as decimal(7,2))' at row 1
|
||||||
drop table t1;
|
drop table t1;
|
||||||
CREATE TABLE t1 (v varchar(10), tt tinytext, t text,
|
CREATE TABLE t1 (v varchar(10), tt tinytext, t text,
|
||||||
mt mediumtext, lt longtext);
|
mt mediumtext, lt longtext);
|
||||||
@ -376,7 +378,7 @@ INSERT INTO t1 VALUES ('1.01', '2.02', '3.03', '4.04', '5.05');
|
|||||||
SELECT CAST(v AS DECIMAL), CAST(tt AS DECIMAL), CAST(t AS DECIMAL),
|
SELECT CAST(v AS DECIMAL), CAST(tt AS DECIMAL), CAST(t AS DECIMAL),
|
||||||
CAST(mt AS DECIMAL), CAST(lt AS DECIMAL) from t1;
|
CAST(mt AS DECIMAL), CAST(lt AS DECIMAL) from t1;
|
||||||
CAST(v AS DECIMAL) CAST(tt AS DECIMAL) CAST(t AS DECIMAL) CAST(mt AS DECIMAL) CAST(lt AS DECIMAL)
|
CAST(v AS DECIMAL) CAST(tt AS DECIMAL) CAST(t AS DECIMAL) CAST(mt AS DECIMAL) CAST(lt AS DECIMAL)
|
||||||
1.01 2.02 3.03 4.04 5.05
|
1 2 3 4 5
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
select cast(NULL as decimal(6)) as t1;
|
select cast(NULL as decimal(6)) as t1;
|
||||||
t1
|
t1
|
||||||
|
@ -1418,3 +1418,30 @@ i2 count(distinct j)
|
|||||||
1.0 2
|
1.0 2
|
||||||
2.0 2
|
2.0 2
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
select cast(143.481 as decimal(4,1));
|
||||||
|
cast(143.481 as decimal(4,1))
|
||||||
|
143.5
|
||||||
|
select cast(143.481 as decimal(4,0));
|
||||||
|
cast(143.481 as decimal(4,0))
|
||||||
|
143
|
||||||
|
select cast(143.481 as decimal(2,1));
|
||||||
|
cast(143.481 as decimal(2,1))
|
||||||
|
9.9
|
||||||
|
Warnings:
|
||||||
|
Error 1264 Out of range value for column 'cast(143.481 as decimal(2,1))' at row 1
|
||||||
|
select cast(-3.4 as decimal(2,1));
|
||||||
|
cast(-3.4 as decimal(2,1))
|
||||||
|
-3.4
|
||||||
|
select cast(99.6 as decimal(2,0));
|
||||||
|
cast(99.6 as decimal(2,0))
|
||||||
|
99
|
||||||
|
Warnings:
|
||||||
|
Error 1264 Out of range value for column 'cast(99.6 as decimal(2,0))' at row 1
|
||||||
|
select cast(-13.4 as decimal(2,1));
|
||||||
|
cast(-13.4 as decimal(2,1))
|
||||||
|
-9.9
|
||||||
|
Warnings:
|
||||||
|
Error 1264 Out of range value for column 'cast(-13.4 as decimal(2,1))' at row 1
|
||||||
|
select cast(98.6 as decimal(2,0));
|
||||||
|
cast(98.6 as decimal(2,0))
|
||||||
|
99
|
||||||
|
@ -1787,7 +1787,7 @@ drop table t1;
|
|||||||
create view v1 as select cast(1 as decimal);
|
create view v1 as select cast(1 as decimal);
|
||||||
select * from v1;
|
select * from v1;
|
||||||
cast(1 as decimal)
|
cast(1 as decimal)
|
||||||
1.00
|
1
|
||||||
drop view v1;
|
drop view v1;
|
||||||
create table t1(f1 int);
|
create table t1(f1 int);
|
||||||
create table t2(f2 int);
|
create table t2(f2 int);
|
||||||
|
@ -1115,3 +1115,14 @@ insert into t1 values (1,1), (1,2), (2,3), (2,4);
|
|||||||
select i, count(distinct j) from t1 group by i;
|
select i, count(distinct j) from t1 group by i;
|
||||||
select i+0.0 as i2, count(distinct j) from t1 group by i2;
|
select i+0.0 as i2, count(distinct j) from t1 group by i2;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug#16172 DECIMAL data type processed incorrectly
|
||||||
|
#
|
||||||
|
select cast(143.481 as decimal(4,1));
|
||||||
|
select cast(143.481 as decimal(4,0));
|
||||||
|
select cast(143.481 as decimal(2,1));
|
||||||
|
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));
|
||||||
|
@ -463,7 +463,7 @@ Item *create_func_cast(Item *a, Cast_target cast_type, int len, int dec,
|
|||||||
case ITEM_CAST_TIME: res= new Item_time_typecast(a); break;
|
case ITEM_CAST_TIME: res= new Item_time_typecast(a); break;
|
||||||
case ITEM_CAST_DATETIME: res= new Item_datetime_typecast(a); break;
|
case ITEM_CAST_DATETIME: res= new Item_datetime_typecast(a); break;
|
||||||
case ITEM_CAST_DECIMAL:
|
case ITEM_CAST_DECIMAL:
|
||||||
res= new Item_decimal_typecast(a, (len>0) ? len : 10, dec ? dec : 2);
|
res= new Item_decimal_typecast(a, (len > 0) ? len : 10, dec);
|
||||||
break;
|
break;
|
||||||
case ITEM_CAST_CHAR:
|
case ITEM_CAST_CHAR:
|
||||||
res= new Item_char_typecast(a, len, cs ? cs :
|
res= new Item_char_typecast(a, len, cs ? cs :
|
||||||
|
@ -955,9 +955,32 @@ longlong Item_decimal_typecast::val_int()
|
|||||||
my_decimal *Item_decimal_typecast::val_decimal(my_decimal *dec)
|
my_decimal *Item_decimal_typecast::val_decimal(my_decimal *dec)
|
||||||
{
|
{
|
||||||
my_decimal tmp_buf, *tmp= args[0]->val_decimal(&tmp_buf);
|
my_decimal tmp_buf, *tmp= args[0]->val_decimal(&tmp_buf);
|
||||||
|
bool sign;
|
||||||
if ((null_value= args[0]->null_value))
|
if ((null_value= args[0]->null_value))
|
||||||
return NULL;
|
return NULL;
|
||||||
my_decimal_round(E_DEC_FATAL_ERROR, tmp, decimals, FALSE, dec);
|
my_decimal_round(E_DEC_FATAL_ERROR, tmp, decimals, FALSE, dec);
|
||||||
|
sign= dec->sign();
|
||||||
|
if (unsigned_flag)
|
||||||
|
{
|
||||||
|
if (sign)
|
||||||
|
{
|
||||||
|
my_decimal_set_zero(dec);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (max_length - 2 - decimals < (uint) my_decimal_intg(dec))
|
||||||
|
{
|
||||||
|
max_my_decimal(dec, max_length - 2, decimals);
|
||||||
|
dec->sign(sign);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
return dec;
|
||||||
|
|
||||||
|
err:
|
||||||
|
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
|
||||||
|
ER_WARN_DATA_OUT_OF_RANGE,
|
||||||
|
ER(ER_WARN_DATA_OUT_OF_RANGE),
|
||||||
|
name, 1);
|
||||||
return dec;
|
return dec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -383,5 +383,13 @@ int my_decimal_cmp(const my_decimal *a, const my_decimal *b)
|
|||||||
return decimal_cmp((decimal_t*) a, (decimal_t*) b);
|
return decimal_cmp((decimal_t*) a, (decimal_t*) b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline
|
||||||
|
int my_decimal_intg(const my_decimal *a)
|
||||||
|
{
|
||||||
|
return decimal_intg((decimal_t*) a);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif /*my_decimal_h*/
|
#endif /*my_decimal_h*/
|
||||||
|
|
||||||
|
@ -1896,6 +1896,14 @@ static int do_sub(decimal_t *from1, decimal_t *from2, decimal_t *to)
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int decimal_intg(decimal_t *from)
|
||||||
|
{
|
||||||
|
int res;
|
||||||
|
dec1 *tmp_res;
|
||||||
|
tmp_res= remove_leading_zeroes(from, &res);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
int decimal_add(decimal_t *from1, decimal_t *from2, decimal_t *to)
|
int decimal_add(decimal_t *from1, decimal_t *from2, decimal_t *to)
|
||||||
{
|
{
|
||||||
if (likely(from1->sign == from2->sign))
|
if (likely(from1->sign == from2->sign))
|
||||||
|
Reference in New Issue
Block a user