summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Barkov <bar@mariadb.com>2018-06-15 10:11:51 +0400
committerAlexander Barkov <bar@mariadb.com>2018-06-15 10:11:51 +0400
commitc55de8d40bba29503773a6a56d6f13f19ca7e339 (patch)
tree46bd1a7c74a16fa8b268df8bfe28a994ea752973
parentec4fdd574964d3611e904fa5f1751d88d8e8286f (diff)
downloadmariadb-git-c55de8d40bba29503773a6a56d6f13f19ca7e339.tar.gz
MDEV-9334 ALTER from DECIMAL to BIGINT UNSIGNED returns a wrong result
When altering from DECIMAL to *INT UNIGNED or to BIT, go through val_decimal(), to avoid truncation to the biggest possible signed integer (0x7FFFFFFFFFFFFFFF / 9223372036854775807).
-rw-r--r--mysql-test/r/type_bit.result19
-rw-r--r--mysql-test/r/type_int.result13
-rw-r--r--mysql-test/t/type_bit.test25
-rw-r--r--mysql-test/t/type_int.test12
-rw-r--r--sql/field.h4
5 files changed, 73 insertions, 0 deletions
diff --git a/mysql-test/r/type_bit.result b/mysql-test/r/type_bit.result
index 30cd94c9277..eeedc501dc4 100644
--- a/mysql-test/r/type_bit.result
+++ b/mysql-test/r/type_bit.result
@@ -830,3 +830,22 @@ def COALESCE(val, 1) 246 2 1 Y 32896 0 63
COALESCE(val, 1)
0
DROP TABLE t1;
+#
+# End of 10.1 tests
+#
+#
+# Start of 10.2 tests
+#
+#
+# MDEV-9334 ALTER from DECIMAL to BIGINT UNSIGNED returns a wrong result
+#
+CREATE TABLE t1 (a DECIMAL(30,0));
+INSERT INTO t1 VALUES (CAST(0xFFFFFFFFFFFFFFFF AS UNSIGNED));
+ALTER TABLE t1 MODIFY a BIT(64);
+SELECT a+0 FROM t1;
+a+0
+18446744073709551615
+DROP TABLE IF EXISTS t1;
+#
+# End of 10.2 tests
+#
diff --git a/mysql-test/r/type_int.result b/mysql-test/r/type_int.result
index 39e2e91ecc7..77e6ee14c25 100644
--- a/mysql-test/r/type_int.result
+++ b/mysql-test/r/type_int.result
@@ -91,5 +91,18 @@ a
10
DROP TABLE t1;
#
+# MDEV-9334 ALTER from DECIMAL to BIGINT UNSIGNED returns a wrong result
+#
+CREATE TABLE t1 (a DECIMAL(30,0));
+INSERT INTO t1 VALUES (CAST(0xFFFFFFFFFFFFFFFF AS UNSIGNED));
+SELECT * FROM t1;
+a
+18446744073709551615
+ALTER TABLE t1 MODIFY a BIGINT UNSIGNED;
+SELECT * FROM t1;
+a
+18446744073709551615
+DROP TABLE t1;
+#
# End of 10.2 tests
#
diff --git a/mysql-test/t/type_bit.test b/mysql-test/t/type_bit.test
index bb282fc15e5..04db1511833 100644
--- a/mysql-test/t/type_bit.test
+++ b/mysql-test/t/type_bit.test
@@ -458,3 +458,28 @@ DROP TABLE t2;
SELECT COALESCE(val, 1) FROM t1;
--disable_metadata
DROP TABLE t1;
+
+--echo #
+--echo # End of 10.1 tests
+--echo #
+
+
+--echo #
+--echo # Start of 10.2 tests
+--echo #
+
+--echo #
+--echo # MDEV-9334 ALTER from DECIMAL to BIGINT UNSIGNED returns a wrong result
+--echo #
+
+CREATE TABLE t1 (a DECIMAL(30,0));
+INSERT INTO t1 VALUES (CAST(0xFFFFFFFFFFFFFFFF AS UNSIGNED));
+ALTER TABLE t1 MODIFY a BIT(64);
+SELECT a+0 FROM t1;
+DROP TABLE IF EXISTS t1;
+
+
+--echo #
+--echo # End of 10.2 tests
+--echo #
+
diff --git a/mysql-test/t/type_int.test b/mysql-test/t/type_int.test
index 271b4d5862a..76ed7eee824 100644
--- a/mysql-test/t/type_int.test
+++ b/mysql-test/t/type_int.test
@@ -74,5 +74,17 @@ SELECT * FROM t1;
DROP TABLE t1;
--echo #
+--echo # MDEV-9334 ALTER from DECIMAL to BIGINT UNSIGNED returns a wrong result
+--echo #
+
+CREATE TABLE t1 (a DECIMAL(30,0));
+INSERT INTO t1 VALUES (CAST(0xFFFFFFFFFFFFFFFF AS UNSIGNED));
+SELECT * FROM t1;
+ALTER TABLE t1 MODIFY a BIGINT UNSIGNED;
+SELECT * FROM t1;
+DROP TABLE t1;
+
+
+--echo #
--echo # End of 10.2 tests
--echo #
diff --git a/sql/field.h b/sql/field.h
index ca85a7c276f..e554f92031c 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -1636,6 +1636,8 @@ public:
bool eq_def(const Field *field) const;
Copy_func *get_copy_func(const Field *from) const
{
+ if (unsigned_flag && from->cmp_type() == DECIMAL_RESULT)
+ return do_field_decimal;
return do_field_int;
}
int save_in_field(Field *to)
@@ -3661,6 +3663,8 @@ public:
}
Copy_func *get_copy_func(const Field *from) const
{
+ if (from->cmp_type() == DECIMAL_RESULT)
+ return do_field_decimal;
return do_field_int;
}
int save_in_field(Field *to) { return to->store(val_int(), true); }