← Back to team overview

maria-developers team mailing list archive

MDEV-12574 MAX(old_decimal) produces a column of the old DECIMAL type

 

  Hi Sergei,

Please review a patch for MDEV-12574.


I suggest we push it into 10.2 (not into 10.3).

Thanks!
diff --git a/mysql-test/r/type_decimal.result b/mysql-test/r/type_decimal.result
index d5232ff..b858d1e 100644
--- a/mysql-test/r/type_decimal.result
+++ b/mysql-test/r/type_decimal.result
@@ -1033,5 +1033,30 @@ c1	c2
 0.123456	0.123456
 SET sql_mode=DEFAULT;
 #
+# MDEV-12574 MAX(old_decimal) produces a column of the old DECIMAL type
+#
+SHOW CREATE TABLE t1dec102;
+Table	Create Table
+t1dec102	CREATE TABLE `t1dec102` (
+  `a` decimal(10,2)/*old*/ DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+CREATE TABLE t1 AS SELECT a, MAX(a), COALESCE(a) FROM t1dec102;
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` decimal(10,2) DEFAULT NULL,
+  `MAX(a)` decimal(10,2) DEFAULT NULL,
+  `COALESCE(a)` decimal(12,2) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1;
+CREATE TABLE t1 AS SELECT a FROM t1dec102 UNION SELECT a FROM t1dec102;
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` decimal(12,2) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1;
+DROP TABLE t1dec102;
+#
 # End of 10.2 tests
 #
diff --git a/mysql-test/t/type_decimal.test b/mysql-test/t/type_decimal.test
index e8b3ecb..c5b6484 100644
--- a/mysql-test/t/type_decimal.test
+++ b/mysql-test/t/type_decimal.test
@@ -628,5 +628,26 @@ SELECT
 SET sql_mode=DEFAULT;
 
 --echo #
+--echo # MDEV-12574 MAX(old_decimal) produces a column of the old DECIMAL type
+--echo #
+
+let $MYSQLD_DATADIR= `select @@datadir`;
+--copy_file std_data/old_decimal/t1dec102.frm $MYSQLD_DATADIR/test/t1dec102.frm
+--copy_file std_data/old_decimal/t1dec102.MYD $MYSQLD_DATADIR/test/t1dec102.MYD
+--copy_file std_data/old_decimal/t1dec102.MYI $MYSQLD_DATADIR/test/t1dec102.MYI
+
+SHOW CREATE TABLE t1dec102;
+
+CREATE TABLE t1 AS SELECT a, MAX(a), COALESCE(a) FROM t1dec102;
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 AS SELECT a FROM t1dec102 UNION SELECT a FROM t1dec102;
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+
+DROP TABLE t1dec102;
+
+--echo #
 --echo # End of 10.2 tests
 --echo #
diff --git a/sql/field.cc b/sql/field.cc
index f540c58..e84658b 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -2973,6 +2973,23 @@ void Field_decimal::sql_type(String &res) const
 }
 
 
+Field *Field_decimal::make_new_field(MEM_ROOT *root, TABLE *new_table,
+                                     bool keep_type)
+{
+  if (keep_type)
+    return Field_real::make_new_field(root, new_table, keep_type);
+
+  Field *field= new (root) Field_new_decimal(NULL, field_length,
+                                             maybe_null() ? (uchar*) "" : 0, 0,
+                                             NONE, field_name,
+                                             dec, flags & ZEROFILL_FLAG,
+                                             unsigned_flag);
+  if (field)
+    field->init_for_make_new_field(new_table, orig_table);
+  return field;
+}
+
+
 /****************************************************************************
 ** Field_new_decimal
 ****************************************************************************/
@@ -7439,15 +7456,7 @@ Field *Field_string::make_new_field(MEM_ROOT *root, TABLE *new_table,
       This is done to ensure that ALTER TABLE will convert old VARCHAR fields
       to now VARCHAR fields.
     */
-    field->init(new_table);
-    /*
-      Normally orig_table is different from table only if field was
-      created via ::make_new_field.  Here we alter the type of field,
-      so ::make_new_field is not applicable. But we still need to
-      preserve the original field metadata for the client-server
-      protocol.
-    */
-    field->orig_table= orig_table;
+    field->init_for_make_new_field(new_table, orig_table);
   }
   return field;
 }
diff --git a/sql/field.h b/sql/field.h
index 820cc5f..22c2764 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -1368,6 +1368,18 @@ class Field: public Value_source
     orig_table= table= table_arg;
     set_table_name(&table_arg->alias);
   }
+  void init_for_make_new_field(TABLE *new_table_arg, TABLE *orig_table_arg)
+  {
+    init(new_table_arg);
+    /*
+      Normally orig_table is different from table only if field was
+      created via ::make_new_field.  Here we alter the type of field,
+      so ::make_new_field is not applicable. But we still need to
+      preserve the original field metadata for the client-server
+      protocol.
+    */
+    orig_table= orig_table_arg;
+  }
 
   /* maximum possible display length */
   virtual uint32 max_display_length()= 0;
@@ -1828,6 +1840,7 @@ class Field_decimal :public Field_real {
                 unireg_check_arg, field_name_arg,
                 dec_arg, zero_arg, unsigned_arg)
     {}
+  Field *make_new_field(MEM_ROOT *root, TABLE *new_table, bool keep_type);
   enum_field_types type() const { return MYSQL_TYPE_DECIMAL;}
   enum ha_base_keytype key_type() const
   { return zerofill ? HA_KEYTYPE_BINARY : HA_KEYTYPE_NUM; }

Follow ups