summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/decimal.h1
-rw-r--r--mysql-test/r/cast.result8
-rw-r--r--mysql-test/r/type_newdecimal.result27
-rw-r--r--mysql-test/r/view.result2
-rw-r--r--mysql-test/t/type_newdecimal.test11
-rw-r--r--sql/item_create.cc2
-rw-r--r--sql/item_func.cc23
-rw-r--r--sql/my_decimal.h8
-rw-r--r--strings/decimal.c8
9 files changed, 85 insertions, 5 deletions
diff --git a/include/decimal.h b/include/decimal.h
index 2648e04c1cf..3b4cafbfd26 100644
--- a/include/decimal.h
+++ b/include/decimal.h
@@ -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 param);
+int decimal_intg(decimal_t *from);
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_cmp(decimal_t *from1, decimal_t *from2);
diff --git a/mysql-test/r/cast.result b/mysql-test/r/cast.result
index 5e8f5dca711..eb2d83e7be4 100644
--- a/mysql-test/r/cast.result
+++ b/mysql-test/r/cast.result
@@ -103,7 +103,7 @@ Warnings:
Warning 1292 Truncated incorrect DOUBLE value: 'a'
select 10.0+cast('a' as decimal);
10.0+cast('a' as decimal)
-10.00
+10.0
Warnings:
Warning 1292 Truncated incorrect DECIMAL value: 'a'
select 10E+0+'a';
@@ -368,7 +368,9 @@ create table t1(s1 time);
insert into t1 values ('11:11:11');
select cast(s1 as decimal(7,2)) from t1;
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;
CREATE TABLE t1 (v varchar(10), tt tinytext, t text,
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),
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)
-1.01 2.02 3.03 4.04 5.05
+1 2 3 4 5
DROP TABLE t1;
select cast(NULL as decimal(6)) as t1;
t1
diff --git a/mysql-test/r/type_newdecimal.result b/mysql-test/r/type_newdecimal.result
index 9755083ab1c..95da4be6830 100644
--- a/mysql-test/r/type_newdecimal.result
+++ b/mysql-test/r/type_newdecimal.result
@@ -1418,3 +1418,30 @@ i2 count(distinct j)
1.0 2
2.0 2
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
diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result
index 2de47f44556..4ef13a0f307 100644
--- a/mysql-test/r/view.result
+++ b/mysql-test/r/view.result
@@ -1787,7 +1787,7 @@ drop table t1;
create view v1 as select cast(1 as decimal);
select * from v1;
cast(1 as decimal)
-1.00
+1
drop view v1;
create table t1(f1 int);
create table t2(f2 int);
diff --git a/mysql-test/t/type_newdecimal.test b/mysql-test/t/type_newdecimal.test
index 7afdb857ca2..e877c6d2948 100644
--- a/mysql-test/t/type_newdecimal.test
+++ b/mysql-test/t/type_newdecimal.test
@@ -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+0.0 as i2, count(distinct j) from t1 group by i2;
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));
diff --git a/sql/item_create.cc b/sql/item_create.cc
index 7147142d8a7..e02ba384717 100644
--- a/sql/item_create.cc
+++ b/sql/item_create.cc
@@ -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_DATETIME: res= new Item_datetime_typecast(a); break;
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;
case ITEM_CAST_CHAR:
res= new Item_char_typecast(a, len, cs ? cs :
diff --git a/sql/item_func.cc b/sql/item_func.cc
index e901eaf8654..250dec6ae57 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -955,9 +955,32 @@ longlong Item_decimal_typecast::val_int()
my_decimal *Item_decimal_typecast::val_decimal(my_decimal *dec)
{
my_decimal tmp_buf, *tmp= args[0]->val_decimal(&tmp_buf);
+ bool sign;
if ((null_value= args[0]->null_value))
return NULL;
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;
}
diff --git a/sql/my_decimal.h b/sql/my_decimal.h
index b02abacf0a3..3ce8cfee75d 100644
--- a/sql/my_decimal.h
+++ b/sql/my_decimal.h
@@ -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);
}
+
+inline
+int my_decimal_intg(const my_decimal *a)
+{
+ return decimal_intg((decimal_t*) a);
+}
+
+
#endif /*my_decimal_h*/
diff --git a/strings/decimal.c b/strings/decimal.c
index 736dc2e57c4..4ff2b5a693a 100644
--- a/strings/decimal.c
+++ b/strings/decimal.c
@@ -1896,6 +1896,14 @@ static int do_sub(decimal_t *from1, decimal_t *from2, decimal_t *to)
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)
{
if (likely(from1->sign == from2->sign))