summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/type_newdecimal-big.result11
-rw-r--r--mysql-test/r/type_newdecimal.result56
-rw-r--r--mysql-test/t/type_newdecimal-big.test31
-rw-r--r--mysql-test/t/type_newdecimal.test64
-rw-r--r--sql/field.cc5
-rw-r--r--sql/my_decimal.cc19
-rw-r--r--strings/decimal.c14
7 files changed, 92 insertions, 108 deletions
diff --git a/mysql-test/r/type_newdecimal-big.result b/mysql-test/r/type_newdecimal-big.result
new file mode 100644
index 00000000000..e95f2f3f781
--- /dev/null
+++ b/mysql-test/r/type_newdecimal-big.result
@@ -0,0 +1,11 @@
+drop procedure if exists sp1;
+create procedure sp1 () begin
+declare v1, v2, v3, v4 decimal(16,12); declare v5 int;
+set v1 = 1; set v2 = 2; set v3 = 1000000000000; set v4 = 2000000000000; set v5 = 0;
+while v5 < 100000 do
+set v1 = v1 + 0.000000000001; set v2 = v2 - 0.000000000001; set v3 = v3 + 1; set v4 = v4 - 1; set v5 = v5 + 1;
+end while; select v1, v2, v3 * 0.000000000001, v4 * 0.000000000001; end;//
+call sp1()//
+v1 v2 v3 * 0.000000000001 v4 * 0.000000000001
+1.000000100000 1.999999900000 1.000000100000 1.999999900000
+drop procedure sp1;
diff --git a/mysql-test/r/type_newdecimal.result b/mysql-test/r/type_newdecimal.result
index 7d7fe7efa35..938dccc864c 100644
--- a/mysql-test/r/type_newdecimal.result
+++ b/mysql-test/r/type_newdecimal.result
@@ -678,16 +678,6 @@ select -18.3=18.3;
select 0.8 = 0.7 + 0.1;
0.8 = 0.7 + 0.1
1
-create procedure p1 () begin
-declare v1, v2, v3, v4 decimal(16,12); declare v5 int;
-set v1 = 1; set v2 = 2; set v3 = 1000000000000; set v4 = 2000000000000; set v5 = 0;
-while v5 < 100000 do
-set v1 = v1 + 0.000000000001; set v2 = v2 - 0.000000000001; set v3 = v3 + 1; set v4 = v4 - 1; set v5 = v5 + 1;
-end while; select v1, v2, v3 * 0.000000000001, v4 * 0.000000000001; end;//
-call p1()//
-v1 v2 v3 * 0.000000000001 v4 * 0.000000000001
-1.000000100000 1.999999900000 1.000000100000 1.999999900000
-drop procedure p1;
drop table if exists t1;
Warnings:
Note 1051 Unknown table 't1'
@@ -1267,34 +1257,6 @@ CAST(my_varchar AS DECIMAL(65,30)) my_varchar
0.011754943450000000000000000000 1.175494345e-2
0.117549434500000000000000000000 1.175494345e-1
UPDATE t1 SET my_decimal = my_float;
-Warnings:
-Note 1265 Data truncated for column 'my_decimal' at row 1
-Note 1265 Data truncated for column 'my_decimal' at row 2
-Note 1265 Data truncated for column 'my_decimal' at row 3
-Note 1265 Data truncated for column 'my_decimal' at row 4
-Note 1265 Data truncated for column 'my_decimal' at row 5
-Note 1265 Data truncated for column 'my_decimal' at row 6
-Note 1265 Data truncated for column 'my_decimal' at row 7
-Note 1265 Data truncated for column 'my_decimal' at row 8
-Note 1265 Data truncated for column 'my_decimal' at row 9
-Note 1265 Data truncated for column 'my_decimal' at row 10
-Note 1265 Data truncated for column 'my_decimal' at row 11
-Note 1265 Data truncated for column 'my_decimal' at row 12
-Note 1265 Data truncated for column 'my_decimal' at row 13
-Note 1265 Data truncated for column 'my_decimal' at row 14
-Note 1265 Data truncated for column 'my_decimal' at row 15
-Note 1265 Data truncated for column 'my_decimal' at row 16
-Note 1265 Data truncated for column 'my_decimal' at row 17
-Note 1265 Data truncated for column 'my_decimal' at row 19
-Note 1265 Data truncated for column 'my_decimal' at row 20
-Note 1265 Data truncated for column 'my_decimal' at row 21
-Note 1265 Data truncated for column 'my_decimal' at row 22
-Note 1265 Data truncated for column 'my_decimal' at row 23
-Note 1265 Data truncated for column 'my_decimal' at row 26
-Note 1265 Data truncated for column 'my_decimal' at row 27
-Note 1265 Data truncated for column 'my_decimal' at row 30
-Note 1265 Data truncated for column 'my_decimal' at row 31
-Note 1265 Data truncated for column 'my_decimal' at row 32
SELECT my_decimal, my_float FROM t1;
my_decimal my_float
0.000000000000000000000000000000 1.17549e-32
@@ -1330,24 +1292,6 @@ my_decimal my_float
0.011754943057894710000000000000 0.0117549
0.117549434304237400000000000000 0.117549
UPDATE t1 SET my_decimal = my_double;
-Warnings:
-Note 1265 Data truncated for column 'my_decimal' at row 1
-Note 1265 Data truncated for column 'my_decimal' at row 2
-Note 1265 Data truncated for column 'my_decimal' at row 3
-Note 1265 Data truncated for column 'my_decimal' at row 4
-Note 1265 Data truncated for column 'my_decimal' at row 5
-Note 1265 Data truncated for column 'my_decimal' at row 6
-Note 1265 Data truncated for column 'my_decimal' at row 7
-Note 1265 Data truncated for column 'my_decimal' at row 8
-Note 1265 Data truncated for column 'my_decimal' at row 9
-Note 1265 Data truncated for column 'my_decimal' at row 10
-Note 1265 Data truncated for column 'my_decimal' at row 11
-Note 1265 Data truncated for column 'my_decimal' at row 13
-Note 1265 Data truncated for column 'my_decimal' at row 14
-Note 1265 Data truncated for column 'my_decimal' at row 16
-Note 1265 Data truncated for column 'my_decimal' at row 18
-Note 1265 Data truncated for column 'my_decimal' at row 20
-Note 1265 Data truncated for column 'my_decimal' at row 31
SELECT my_decimal, my_double FROM t1;
my_decimal my_double
0.000000000000000000000000000000 1.175494345e-32
diff --git a/mysql-test/t/type_newdecimal-big.test b/mysql-test/t/type_newdecimal-big.test
new file mode 100644
index 00000000000..e200017f2ba
--- /dev/null
+++ b/mysql-test/t/type_newdecimal-big.test
@@ -0,0 +1,31 @@
+--source include/big_test.inc
+
+--disable_warnings
+drop procedure if exists sp1;
+--enable_warnings
+
+#
+#-- 2. Adding (one millionth) one million times should be the same as
+#-- adding 1. So a stored procedure with many iterations will show if
+#-- small errors accumulate.
+#
+
+delimiter //;
+#
+create procedure sp1 () begin
+ declare v1, v2, v3, v4 decimal(16,12); declare v5 int;
+ set v1 = 1; set v2 = 2; set v3 = 1000000000000; set v4 = 2000000000000; set v5 = 0;
+ while v5 < 100000 do
+ set v1 = v1 + 0.000000000001; set v2 = v2 - 0.000000000001; set v3 = v3 + 1; set v4 = v4 - 1; set v5 = v5 + 1;
+ end while; select v1, v2, v3 * 0.000000000001, v4 * 0.000000000001; end;//
+#
+call sp1()//
+#-- should return
+# -- v1=1.0000001
+# -- v2=1.999999900000
+# -- v3=1.0000001
+# -- v4=1.999999900000
+#
+delimiter ;//
+#
+drop procedure sp1;
diff --git a/mysql-test/t/type_newdecimal.test b/mysql-test/t/type_newdecimal.test
index ad71ffa02e5..e2fe9767432 100644
--- a/mysql-test/t/type_newdecimal.test
+++ b/mysql-test/t/type_newdecimal.test
@@ -473,7 +473,7 @@ drop table wl1612_4;
#
#-- Additional tests for WL#1612 Precision math
#
-#-- 1. Comparisons should show that a number is
+#-- Comparisons should show that a number is
#-- exactly equal to its value as displayed.
#
set sql_mode='';
@@ -487,34 +487,9 @@ select 18.3=18.3;
select -18.3=18.3;
#
select 0.8 = 0.7 + 0.1;
+
#
-#-- 2. Adding (one millionth) one million times should be the same as
-#-- adding 1. So a stored procedure with many iterations will show if
-#-- small errors accumulate.
-#
-#drop procedure p1;
-#
-delimiter //;
-#
-create procedure p1 () begin
- declare v1, v2, v3, v4 decimal(16,12); declare v5 int;
- set v1 = 1; set v2 = 2; set v3 = 1000000000000; set v4 = 2000000000000; set v5 = 0;
- while v5 < 100000 do
- set v1 = v1 + 0.000000000001; set v2 = v2 - 0.000000000001; set v3 = v3 + 1; set v4 = v4 - 1; set v5 = v5 + 1;
- end while; select v1, v2, v3 * 0.000000000001, v4 * 0.000000000001; end;//
-#
-call p1()//
-#-- should return
-# -- v1=1.0000001
-# -- v2=1.999999900000
-# -- v3=1.0000001
-# -- v4=1.999999900000
-#
-delimiter ;//
-#
-drop procedure p1;
-#
-#-- 3. It should be possible to define a column
+#-- It should be possible to define a column
#-- with up to 38 digits precision either before
#-- or after the decimal point. Any number which
#-- is inserted, if it's within the range, should
@@ -565,7 +540,7 @@ select * from t1;
#
drop table t1;
#
-#-- 4. The usual arithmetic operators / * + - should work.
+#-- The usual arithmetic operators / * + - should work.
#
#select 77777777777777777777777777777777777777 / 7777777777777777777777777777777777777 = 10;
#-- should return 0 (false).
@@ -668,7 +643,7 @@ select truncate(99999999999999999999999999999999999999,-31);
#drop procedure p1;
#drop table t1;
#
-#-- 7. When I say DECIMAL(x) I should be able to store x digits.
+#-- When I say DECIMAL(x) I should be able to store x digits.
#-- If I can't, there should be an error at CREATE time.
#
#drop table if exists t1;
@@ -676,7 +651,8 @@ select truncate(99999999999999999999999999999999999999,-31);
#create table t1 (col1 decimal(254));
#-- should return SQLSTATE 22003 numeric value out of range
#
-#-- 8. When I say DECIMAL(x,y) there should be no silent change of precision or scale.
+#-- When I say DECIMAL(x,y) there should be no silent change of precision or
+#-- scale.
#
#drop table if exists t1;
#
@@ -694,7 +670,7 @@ select truncate(99999999999999999999999999999999999999,-31);
#
#drop table t1;
#
-#-- 9. From WL#1612 "The future" point 2.:
+#-- From WL#1612 "The future" point 2.:
#-- The standard requires that we treat numbers like "0.5" as
#-- DECIMAL or NUMERIC, not as floating-point.
#
@@ -715,7 +691,7 @@ show create table t1;
#
drop table t1;
#
-#-- 10. From WL#1612, "The future", point 3.: We have to start rounding correctly.
+#-- From WL#1612, "The future", point 3.: We have to start rounding correctly.
#
select round(1.5),round(2.5);
#-- should return:
@@ -725,13 +701,13 @@ select round(1.5),round(2.5);
#| 2 | 3 |
#+------------+------------+
#
-#-- 11. From WL#1612, "The future", point 4.: "select 0.07 * 0.07;" should return 0.0049, not 0.00.
+#-- From WL#1612, "The future", point 4.: "select 0.07 * 0.07;" should return 0.0049, not 0.00.
#-- If operand#1 has scale X and operand#2 has scale Y, then result should have scale (X+Y).
#
select 0.07 * 0.07;
#-- should return 0.0049
#
-#-- 12. From WL#1612, "The future", point 5.: Division by zero is an error.
+#-- From WL#1612, "The future", point 5.: Division by zero is an error.
#
set sql_mode='traditional';
#
@@ -752,7 +728,7 @@ select 1 / 0;
#+-------+
#1 row in set, 1 warning (0.00 sec)
#
-#-- 13. From WL#1612 "The future" point 6.: Overflow is an error.
+#-- From WL#1612 "The future" point 6.: Overflow is an error.
#
#set sql_mode='';
#
@@ -793,7 +769,8 @@ select 1 / 0;
#drop table t2;
#drop table t1;
#
-#-- 15. From WL#1612 "The future" point 8.: Stop storing leading "+" signs and leading "0"s.
+#-- From WL#1612 "The future" point 8.: Stop storing leading "+" signs and
+# leading "0"s.
#
#drop table if exists t1;
#
@@ -805,7 +782,7 @@ select 1 / 0;
#
#drop table t1;
#
-#-- 16. From WL#1612, The future" point 9.:
+#-- From WL#1612, The future" point 9.:
#-- Accept the data type and precision and scale as the user
#-- asks, or return an error, but don't change to something else.
#
@@ -817,7 +794,7 @@ select 1 / 0;
#
#drop table t1;
#
-#-- 17. The scripts in the following bugs should work:
+#-- The scripts in the following bugs should work:
#
#BUG#559 Maximum precision for DECIMAL column ...
@@ -833,7 +810,7 @@ select 1 / 0;
#BUG#6048 Stored procedure causes operating system reboot
#BUG#6053 DOUBLE PRECISION literal
--- 18. Tests from 'traditional' mode tests
+-- Tests from 'traditional' mode tests
#
set sql_mode='ansi,traditional';
#
@@ -1077,10 +1054,17 @@ SELECT CAST(my_float AS DECIMAL(65,30)), my_float FROM t1;
SELECT CAST(my_double AS DECIMAL(65,30)), my_double FROM t1;
SELECT CAST(my_varchar AS DECIMAL(65,30)), my_varchar FROM t1;
+# We have to disable warnings here as the test in
+# Field_new_decimal::store(double):
+# if (nr2 != nr)
+# fails randomly depending on compiler options
+
+--disable_warnings
UPDATE t1 SET my_decimal = my_float;
SELECT my_decimal, my_float FROM t1;
UPDATE t1 SET my_decimal = my_double;
SELECT my_decimal, my_double FROM t1;
+--enable_warnings
UPDATE t1 SET my_decimal = my_varchar;
SELECT my_decimal, my_varchar FROM t1;
diff --git a/sql/field.cc b/sql/field.cc
index 55d6bf7e3a2..dbc8d2a49d7 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -2384,7 +2384,7 @@ bool Field_new_decimal::store_value(const my_decimal *decimal_value)
#ifndef DBUG_OFF
{
char dbug_buff[DECIMAL_MAX_STR_LENGTH+1];
- DBUG_PRINT("info", ("saving with precision %d, scale: %d, value %s",
+ DBUG_PRINT("info", ("saving with precision %d scale: %d value %s",
(int)precision, (int)dec,
dbug_decimal_as_string(dbug_buff, decimal_value)));
}
@@ -2399,7 +2399,8 @@ bool Field_new_decimal::store_value(const my_decimal *decimal_value)
my_decimal2binary(E_DEC_FATAL_ERROR, &buff, ptr, precision, dec);
error= 1;
}
- DBUG_EXECUTE("info", print_decimal_buff(decimal_value, (byte *) ptr, bin_size););
+ DBUG_EXECUTE("info", print_decimal_buff(decimal_value, (byte *) ptr,
+ bin_size););
DBUG_RETURN(error);
}
diff --git a/sql/my_decimal.cc b/sql/my_decimal.cc
index 1bd16940b47..89607129026 100644
--- a/sql/my_decimal.cc
+++ b/sql/my_decimal.cc
@@ -193,16 +193,23 @@ int str2my_decimal(uint mask, const char *from, uint length,
#ifndef DBUG_OFF
/* routines for debugging print */
+#define DIG_PER_DEC1 9
+#define ROUND_UP(X) (((X)+DIG_PER_DEC1-1)/DIG_PER_DEC1)
+
/* print decimal */
void
print_decimal(const my_decimal *dec)
{
- fprintf(DBUG_FILE,
- "\nDecimal: sign: %d intg: %d frac: %d \n\
-%09d,%09d,%09d,%09d,%09d,%09d,%09d,%09d\n",
- dec->sign(), dec->intg, dec->frac,
- dec->buf[0], dec->buf[1], dec->buf[2], dec->buf[3],
- dec->buf[4], dec->buf[5], dec->buf[6], dec->buf[7]);
+ int i, end;
+ char buff[512], *pos;
+ pos= buff;
+ pos+= my_sprintf(buff, (buff, "Decimal: sign: %d intg: %d frac: %d { ",
+ dec->sign(), dec->intg, dec->frac));
+ end= ROUND_UP(dec->frac)+ROUND_UP(dec->intg)-1;
+ for (i=0; i < end; i++)
+ pos+= my_sprintf(pos, (pos, "%09d, ", dec->buf[i]));
+ pos+= my_sprintf(pos, (pos, "%09d }\n", dec->buf[i]));
+ fputs(buff, DBUG_FILE);
}
diff --git a/strings/decimal.c b/strings/decimal.c
index 0c1f03016e0..9cf4a281be2 100644
--- a/strings/decimal.c
+++ b/strings/decimal.c
@@ -972,12 +972,18 @@ int decimal2double(decimal_t *from, double *to)
int double2decimal(double from, decimal_t *to)
{
/* TODO: fix it, when we'll have dtoa */
- char s[400], *end;
- sprintf(s, "%.16G", from);
- end= strend(s);
- return string2decimal(s, to, &end);
+ char buff[400], *end;
+ int length, res;
+ DBUG_ENTER("double2decimal");
+ length= my_sprintf(buff, (buff, "%.16G", from));
+ DBUG_PRINT("info",("from: %g from_as_str: %s", from, buff));
+ end= buff+length;
+ res= string2decimal(buff, to, &end);
+ DBUG_PRINT("exit", ("res: %d", res));
+ DBUG_RETURN(res);
}
+
static int ull2dec(ulonglong from, decimal_t *to)
{
int intg1, error=E_DEC_OK;