Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions mysql-test/main/temp_table.result
Original file line number Diff line number Diff line change
Expand Up @@ -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;
12 changes: 12 additions & 0 deletions mysql-test/main/temp_table.test
Original file line number Diff line number Diff line change
Expand Up @@ -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;
3 changes: 1 addition & 2 deletions mysql-test/suite/maria/alter.result
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
1 change: 0 additions & 1 deletion mysql-test/suite/maria/alter.test
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
38 changes: 16 additions & 22 deletions sql/sql_table.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -13091,30 +13089,26 @@ 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++)
{
def= it++;
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
Expand Down
Loading