Skip to content
/ server Public

Commit aa18585

Browse files
committed
MDEV-38716: Part 2
The last patch was incorrect - it did not consider columns with both DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP and these records would be re-written with new timestamps. The fix is to add the ON UPDATE based default_fields back to the destination table after the actual data copy. Reviewed-by: TODO Signed-off-by: Brandon Nesterenko <[email protected]>
1 parent 8e7131e commit aa18585

File tree

1 file changed

+37
-16
lines changed

1 file changed

+37
-16
lines changed

sql/sql_table.cc

Lines changed: 37 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12720,16 +12720,6 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to,
1272012720
goto err;
1272112721
(copy_end++)->set(*ptr,def->field,0);
1272212722
}
12723-
12724-
/*
12725-
Ensure that TIMESTAMP or DATETIME fields with ON UPDATE clauses
12726-
have their default_fields copied, so they are executed after ALTER.
12727-
*/
12728-
if (dfield_ptr && def->field->has_update_default_function())
12729-
{
12730-
*(dfield_ptr++)= *ptr;
12731-
++to->s->default_fields;
12732-
}
1273312723
}
1273412724
else
1273512725
{
@@ -12746,13 +12736,16 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to,
1274612736
}
1274712737
}
1274812738
}
12739+
12740+
/*
12741+
Mark end of default field pointers. Note this is somewhat temporarily done,
12742+
as default_fields are re-considered later in the function for ON UPDATE
12743+
defaults (TIMESTAMP and DATETIME). That is, at the end of this function,
12744+
dfield_ptr may be overridden from this NULL reset to point to an ON UPDATE
12745+
field.
12746+
*/
1274912747
if (dfield_ptr)
12750-
{
12751-
if (dfield_ptr == to->default_field)
12752-
to->default_field= NULL; // No default fields left
12753-
else
12754-
*dfield_ptr= NULL; // Mark end of default field pointers
12755-
}
12748+
*dfield_ptr= NULL;
1275612749

1275712750
if (order)
1275812751
{
@@ -13114,6 +13107,34 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to,
1311413107
to->file->extra(HA_EXTRA_PREPARE_FOR_DROP);
1311513108
}
1311613109

13110+
/*
13111+
To prevent this data copy from re-writing previously set default values,
13112+
this function previously has overridden to->default_fields to only account
13113+
for new fields added to the table (i.e those which should get new default
13114+
values). Now that the data copy is done, the to->default_field list is
13115+
missing fields that have ON UPDATE clauses (i.e. TIMESTAMP and DATETIME).
13116+
So restore these fields to the default_fields list.
13117+
13118+
Note the code is similar to the dfield_ptr modification earlier in the
13119+
funciton.
13120+
*/
13121+
it.rewind();
13122+
for (Field **ptr=to->field ; *ptr ; ptr++)
13123+
{
13124+
def=it++;
13125+
if (def->field && dfield_ptr && def->field->has_update_default_function())
13126+
{
13127+
*(dfield_ptr++)= *ptr;
13128+
}
13129+
}
13130+
if (dfield_ptr)
13131+
{
13132+
if (dfield_ptr == to->default_field)
13133+
to->default_field= NULL; // No default fields left
13134+
else
13135+
*dfield_ptr= NULL; // Mark end of default field pointers
13136+
}
13137+
1311713138
DEBUG_SYNC(thd, "copy_data_between_tables_before_reset_backup_lock");
1311813139
if (backup_reset_alter_copy_lock(thd))
1311913140
error= 1;

0 commit comments

Comments
 (0)