← Back to team overview

maria-developers team mailing list archive

MDEV-9709 Unexpected modification of value and warning about out of range value upon ALTER

 

Hi Elena,

can you please review a patch for MDEV-9709?

I'm quite sure about the code change, it's trivial.
Please have a look into the tests.

Thanks.
diff --git a/mysql-test/r/type_float.result b/mysql-test/r/type_float.result
index e7267f0..3da5484 100644
--- a/mysql-test/r/type_float.result
+++ b/mysql-test/r/type_float.result
@@ -638,3 +638,75 @@ DROP TABLE t1;
 #
 # End of 10.1 tests
 #
+#
+# Start of 10.2 tests
+#
+#
+# MDEV-9709 Unexpected modification of value and warning about out of range value upon ALTER
+#
+CREATE TABLE t1 (
+f FLOAT,
+d10_10 DOUBLE PRECISION (10,10),
+d53_10 DOUBLE(53,10) 
+);
+INSERT INTO t1 (f,d10_10,d53_10) VALUES (
+-9999999999999999999999999999999999999999999.9999999999,
+-9999999999999999999999999999999999999999999.9999999999,
+-9999999999999999999999999999999999999999999.9999999999
+);
+Warnings:
+Warning	1264	Out of range value for column 'f' at row 1
+Warning	1264	Out of range value for column 'd10_10' at row 1
+SELECT * FROM t1;
+f	-3.40282e38
+d10_10	-0.9999999999
+d53_10	-10000000000000000000000000000000000000000000.0000000000
+INSERT INTO t1 (f,d10_10,d53_10) SELECT d53_10, d53_10, d53_10 FROM t1;
+Warnings:
+Level	Warning
+Code	1264
+Message	Out of range value for column 'f' at row 1
+Level	Warning
+Code	1264
+Message	Out of range value for column 'd10_10' at row 1
+SELECT * FROM t1;
+f	-3.40282e38
+d10_10	-0.9999999999
+d53_10	-10000000000000000000000000000000000000000000.0000000000
+f	-3.40282e38
+d10_10	-0.9999999999
+d53_10	-10000000000000000000000000000000000000000000.0000000000
+ALTER TABLE t1 ADD COLUMN i INT;
+SELECT * FROM t1;
+f	-3.40282e38
+d10_10	-0.9999999999
+d53_10	-10000000000000000000000000000000000000000000.0000000000
+i	NULL
+f	-3.40282e38
+d10_10	-0.9999999999
+d53_10	-10000000000000000000000000000000000000000000.0000000000
+i	NULL
+DROP TABLE t1;
+CREATE TABLE t1 (d10_10 DOUBLE (10,10));
+CREATE TABLE t2 (d53_10 DOUBLE (53,10));
+INSERT INTO t2 VALUES (-9999999999999999999999999999999999999999999.9999999999);
+INSERT INTO t1 (d10_10) SELECT d53_10 FROM t2;
+Warnings:
+Warning	1264	Out of range value for column 'd10_10' at row 1
+SELECT * FROM t1;
+d10_10
+-0.9999999999
+DROP TABLE t1,t2;
+CREATE TABLE t1 (d2_2 FLOAT (2,2));
+CREATE TABLE t2 (d4_2 FLOAT (4,2));
+INSERT INTO t2 VALUES (99.99);
+INSERT INTO t1 (d2_2) SELECT d4_2 FROM t2;
+Warnings:
+Warning	1264	Out of range value for column 'd2_2' at row 1
+SELECT * FROM t1;
+d2_2
+0.99
+DROP TABLE t1,t2;
+#
+# End of 10.2 tests
+#
diff --git a/mysql-test/t/type_float.test b/mysql-test/t/type_float.test
index 3717dc0..b2d9a70 100644
--- a/mysql-test/t/type_float.test
+++ b/mysql-test/t/type_float.test
@@ -458,3 +458,48 @@ DROP TABLE t1;
 --echo #
 --echo # End of 10.1 tests
 --echo #
+
+--echo #
+--echo # Start of 10.2 tests
+--echo #
+
+--echo #
+--echo # MDEV-9709 Unexpected modification of value and warning about out of range value upon ALTER
+--echo #
+
+CREATE TABLE t1 (
+  f FLOAT,
+  d10_10 DOUBLE PRECISION (10,10),
+  d53_10 DOUBLE(53,10) 
+);
+INSERT INTO t1 (f,d10_10,d53_10) VALUES (
+  -9999999999999999999999999999999999999999999.9999999999,
+  -9999999999999999999999999999999999999999999.9999999999,
+  -9999999999999999999999999999999999999999999.9999999999
+);
+--vertical_results
+SELECT * FROM t1;
+INSERT INTO t1 (f,d10_10,d53_10) SELECT d53_10, d53_10, d53_10 FROM t1;
+SELECT * FROM t1;
+ALTER TABLE t1 ADD COLUMN i INT;
+SELECT * FROM t1;
+DROP TABLE t1;
+--horizontal_results
+
+CREATE TABLE t1 (d10_10 DOUBLE (10,10));
+CREATE TABLE t2 (d53_10 DOUBLE (53,10));
+INSERT INTO t2 VALUES (-9999999999999999999999999999999999999999999.9999999999);
+INSERT INTO t1 (d10_10) SELECT d53_10 FROM t2;
+SELECT * FROM t1;
+DROP TABLE t1,t2;
+
+CREATE TABLE t1 (d2_2 FLOAT (2,2));
+CREATE TABLE t2 (d4_2 FLOAT (4,2));
+INSERT INTO t2 VALUES (99.99);
+INSERT INTO t1 (d2_2) SELECT d4_2 FROM t2;
+SELECT * FROM t1;
+DROP TABLE t1,t2;
+
+--echo #
+--echo # End of 10.2 tests
+--echo #
diff --git a/sql/field.h b/sql/field.h
index 8869c16..3c6e318 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -1707,6 +1707,16 @@ class Field_real :public Field_num {
     return do_field_real;
   }
   int save_in_field(Field *to) { return to->store(val_real()); }
+  bool memcpy_field_possible(const Field *from) const
+  {
+    /*
+      Cannot do memcpy from a longer field to a shorter field,
+      e.g. a DOUBLE(53,10) into a DOUBLE(10,10).
+      But it should be OK the other way around.
+    */
+    return Field_num::memcpy_field_possible(from) &&
+           field_length >= from->field_length;
+  }
   int store_decimal(const my_decimal *);
   int  store_time_dec(MYSQL_TIME *ltime, uint dec);
   bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate);