summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Didriksen <tor.didriksen@oracle.com>2011-08-29 11:24:36 +0200
committerTor Didriksen <tor.didriksen@oracle.com>2011-08-29 11:24:36 +0200
commitf610c5658748ae97a5e2c1e1afbd229f2121a082 (patch)
treecfdb33c49ffc624e6202046c039fea6682c55126
parent5618a7d69df06ee7ad3b41a269cba8b57f99a8c5 (diff)
downloadmariadb-git-f610c5658748ae97a5e2c1e1afbd229f2121a082.tar.gz
BUG#12911710 - VALGRIND FAILURE IN ROW-DEBUG:PERFSCHEMA.SOCKET_SUMMARY_BY_INSTANCE_FUNC
Converting the number zero to binary and back yielded the number zero, but with no digits, i.e. zero precision. This made the multiply algorithm go haywire in various ways. include/decimal.h: Document struct st_decimal_t mysql-test/r/type_newdecimal.result: New test case (valgrind warnings) mysql-test/t/type_newdecimal.test: New test case (valgrind warnings) sql/my_decimal.h: Remove the HAVE_purify enabled/disabled code. strings/decimal.c: Make a proper zero, with non-zero precision.
-rw-r--r--include/decimal.h9
-rw-r--r--mysql-test/r/type_newdecimal.result11
-rw-r--r--mysql-test/t/type_newdecimal.test14
-rw-r--r--sql/my_decimal.h6
-rw-r--r--strings/decimal.c9
5 files changed, 43 insertions, 6 deletions
diff --git a/include/decimal.h b/include/decimal.h
index 530ed9e1757..c377bd4a400 100644
--- a/include/decimal.h
+++ b/include/decimal.h
@@ -21,6 +21,15 @@ typedef enum
decimal_round_mode;
typedef int32 decimal_digit_t;
+/**
+ intg is the number of *decimal* digits (NOT number of decimal_digit_t's !)
+ before the point
+ frac is the number of decimal digits after the point
+ len is the length of buf (length of allocated space) in decimal_digit_t's,
+ not in bytes
+ sign false means positive, true means negative
+ buf is an array of decimal_digit_t's
+ */
typedef struct st_decimal_t {
int intg, frac, len;
my_bool sign;
diff --git a/mysql-test/r/type_newdecimal.result b/mysql-test/r/type_newdecimal.result
index c301a7dd629..0c6c1333e9b 100644
--- a/mysql-test/r/type_newdecimal.result
+++ b/mysql-test/r/type_newdecimal.result
@@ -1927,3 +1927,14 @@ f1
0.000000000000000000000000
DROP TABLE IF EXISTS t1;
End of 5.1 tests
+#
+# BUG#12911710 - VALGRIND FAILURE IN
+# ROW-DEBUG:PERFSCHEMA.SOCKET_SUMMARY_BY_INSTANCE_FUNC
+#
+CREATE TABLE t1(d1 DECIMAL(60,0) NOT NULL,
+d2 DECIMAL(60,0) NOT NULL);
+INSERT INTO t1 (d1, d2) VALUES(0.0, 0.0);
+SELECT d1 * d2 FROM t1;
+d1 * d2
+0
+DROP TABLE t1;
diff --git a/mysql-test/t/type_newdecimal.test b/mysql-test/t/type_newdecimal.test
index 31a8808da55..567d6c0b6a1 100644
--- a/mysql-test/t/type_newdecimal.test
+++ b/mysql-test/t/type_newdecimal.test
@@ -1526,3 +1526,17 @@ DROP TABLE IF EXISTS t1;
--echo End of 5.1 tests
+
+--echo #
+--echo # BUG#12911710 - VALGRIND FAILURE IN
+--echo # ROW-DEBUG:PERFSCHEMA.SOCKET_SUMMARY_BY_INSTANCE_FUNC
+--echo #
+
+CREATE TABLE t1(d1 DECIMAL(60,0) NOT NULL,
+ d2 DECIMAL(60,0) NOT NULL);
+
+INSERT INTO t1 (d1, d2) VALUES(0.0, 0.0);
+SELECT d1 * d2 FROM t1;
+
+DROP TABLE t1;
+
diff --git a/sql/my_decimal.h b/sql/my_decimal.h
index c7a99e10233..21f485560da 100644
--- a/sql/my_decimal.h
+++ b/sql/my_decimal.h
@@ -101,12 +101,8 @@ public:
{
len= DECIMAL_BUFF_LENGTH;
buf= buffer;
-#if !defined (HAVE_purify) && !defined(DBUG_OFF)
- /* Set buffer to 'random' value to find wrong buffer usage */
- for (uint i= 0; i < DECIMAL_BUFF_LENGTH; i++)
- buffer[i]= i;
-#endif
}
+
my_decimal()
{
init();
diff --git a/strings/decimal.c b/strings/decimal.c
index 43957c7dc19..6c89657004c 100644
--- a/strings/decimal.c
+++ b/strings/decimal.c
@@ -1423,11 +1423,18 @@ int bin2decimal(const uchar *from, decimal_t *to, int precision, int scale)
buf++;
}
my_afree(d_copy);
+
+ /*
+ No digits? We have read the number zero, of unspecified precision.
+ Make it a proper zero, with non-zero precision.
+ */
+ if (to->intg == 0 && to->frac == 0)
+ decimal_make_zero(to);
return error;
err:
my_afree(d_copy);
- decimal_make_zero(((decimal_t*) to));
+ decimal_make_zero(to);
return(E_DEC_BAD_NUM);
}