diff --git a/mysql-test/main/temp_table.result b/mysql-test/main/temp_table.result index 75f9cd1eed6a6..a4f01fbdad830 100644 --- a/mysql-test/main/temp_table.result +++ b/mysql-test/main/temp_table.result @@ -746,3 +746,14 @@ SELECT * FROM tmp_38716_2 where b=20; a b c NULL 20 21 DROP TABLE tmp_38716_2; +# +# MDEV-38830 +# +CREATE TEMPORARY TABLE tmp_38830 (c INT KEY); +INSERT INTO tmp_38830 VALUES (1); +ALTER TABLE tmp_38830 ADD COLUMN (d TIMESTAMP ON UPDATE CURRENT_TIMESTAMP); +UPDATE tmp_38830 SET c=c+1; +select * from tmp_38830; +c d +2 2001-01-01 10:20:30 +DROP TEMPORARY TABLE tmp_38830; diff --git a/mysql-test/main/temp_table.test b/mysql-test/main/temp_table.test index ea6201c45ab7e..fd4a93fbbfad0 100644 --- a/mysql-test/main/temp_table.test +++ b/mysql-test/main/temp_table.test @@ -810,3 +810,15 @@ INSERT INTO tmp_38716_2 (b) VALUES (20); SELECT * FROM tmp_38716_2 where b=20; DROP TABLE tmp_38716_2; + + +--echo # +--echo # MDEV-38830 +--echo # +CREATE TEMPORARY TABLE tmp_38830 (c INT KEY); +INSERT INTO tmp_38830 VALUES (1); +ALTER TABLE tmp_38830 ADD COLUMN (d TIMESTAMP ON UPDATE CURRENT_TIMESTAMP); +UPDATE tmp_38830 SET c=c+1; +select * from tmp_38830; + +DROP TEMPORARY TABLE tmp_38830; diff --git a/mysql-test/suite/maria/alter.result b/mysql-test/suite/maria/alter.result index 36d7ae9c302b5..06282f6690deb 100644 --- a/mysql-test/suite/maria/alter.result +++ b/mysql-test/suite/maria/alter.result @@ -63,7 +63,7 @@ DELETE FROM t2 ORDER BY c LIMIT 1; INSERT IGNORE INTO t2 SELECT * FROM t2; OPTIMIZE TABLE t2; Table Op Msg_type Msg_text -test.t2 optimize status OK +test.t2 optimize status Table is already up to date SELECT count(a),sum(a) FROM t2; count(a) sum(a) 0 NULL @@ -73,7 +73,6 @@ SELECT count(a),sum(a) FROM t2; count(a) sum(a) 0 NULL ALTER TABLE t2 CHANGE IF EXISTS d c INT; -ERROR 22007: Truncated incorrect datetime value: '4' SELECT count(a),sum(a) FROM t2; count(a) sum(a) 0 NULL diff --git a/mysql-test/suite/maria/alter.test b/mysql-test/suite/maria/alter.test index a68b5f2e0d721..2c18d6508c061 100644 --- a/mysql-test/suite/maria/alter.test +++ b/mysql-test/suite/maria/alter.test @@ -64,7 +64,6 @@ SELECT count(a),sum(a) FROM t2; INSERT IGNORE INTO t2 SELECT * FROM t2; SET SQL_MODE= 'STRICT_ALL_TABLES'; SELECT count(a),sum(a) FROM t2; ---error ER_TRUNCATED_WRONG_VALUE ALTER TABLE t2 CHANGE IF EXISTS d c INT; SELECT count(a),sum(a) FROM t2; ALTER IGNORE TABLE t2 ADD IF NOT EXISTS e BIT; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index c0795cb2ab562..15a9d36b8d573 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -13073,16 +13073,14 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to, for new fields added to the table (i.e those which should get new default values). Now that the data copy is done, the to->default_field list needs to be restored to include all fields that have default values to fill. - - First, if to->default_field is NULL, it means it was nullified to prevent - trying to update any default values during the copy process because there - were no new fields added with default values to fill in. The list needs to - be restored to the original location so future records in this session can - get default values. - - Then, because to->default_field was reset and now only considers new - fields, it is missing fields that have ON UPDATE clauses (i.e. TIMESTAMP - and DATETIME). So add those back in. + Either: + 1) to->default_field is NULL, in which case either dfield_ptr is also + NULL or the pre-alter table has fields with default values and the + alter doesn't add any new fields with default values. In either case, + simply restore the original default_field list. + 2) Otherwise, to->default_field has been modified in-place and needs to + be manually restored. I.e., it is missing fields that have ON UPDATE + clauses (i.e. TIMESTAMP and DATETIME). So add those back in. Notes: * The code is similar to the dfield_ptr modification earlier in the @@ -13091,19 +13089,15 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to, data, which requires the table's default_fields to be set up */ if (!to->default_field) + { to->default_field= dfield_ptr; -#ifndef DBUG_OFF + } else { /* - If to->default_field exists, dfield_ptr should point to the NULL list - terminator in the default_field list. + to->default_list was modified in-place, so we need to check to manually + add back missing fields. */ - DBUG_ASSERT(dfield_ptr && !*dfield_ptr); - } -#endif - if (dfield_ptr) - { it.rewind(); for (Field **ptr= to->field; *ptr; ptr++) { @@ -13111,10 +13105,10 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to, if (def->field && def->field->has_update_default_function()) *(dfield_ptr++)= *ptr; } - if (dfield_ptr == to->default_field) - to->default_field= NULL; // No default fields - else - *dfield_ptr= NULL; // Mark end of default field pointers + /* + Mark end of list + */ + *dfield_ptr= NULL; } #ifdef HAVE_REPLICATION