MDEV-6849 ON UPDATE CURRENT_TIMESTAMP doesn't always work
reset default fields not for every modified row, but only once, at the beginning, as the set of modified fields doesn't change. exception: INSERT ... ON DUPLICATE KEY UPDATE - the set of fields does change per row and in that case we reset default fields per row.
This commit is contained in:
parent
815667086c
commit
6a2c170141
@ -407,16 +407,29 @@ SELECT * FROM t1;
|
|||||||
UPDATE t1 SET c = 2;
|
UPDATE t1 SET c = 2;
|
||||||
SELECT * FROM t1;
|
SELECT * FROM t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Test that ON UPDATE CURRENT_TIMESTAMP works after non-changing UPDATE.
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
--echo # 2011-04-20 09:54:13 UTC
|
||||||
|
SET TIMESTAMP = 1303293253.794613;
|
||||||
|
|
||||||
|
UPDATE t1 SET c = 2, b = '2011-04-20 09:53:41.794613';
|
||||||
|
SELECT * FROM t1;
|
||||||
|
|
||||||
|
UPDATE t1 SET c = 3;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
--echo # Test of multiple-table UPDATE for ON UPDATE CURRENT_TIMESTAMP
|
--echo # Test of multiple-table UPDATE for ON UPDATE CURRENT_TIMESTAMP
|
||||||
--echo #
|
--echo #
|
||||||
--echo # 2011-04-20 15:06:13 UTC
|
--echo # 2011-04-20 15:06:13 UTC
|
||||||
SET TIMESTAMP = 1303311973.534231;
|
SET TIMESTAMP = 1303311973.534231;
|
||||||
|
|
||||||
UPDATE t1 t11, t1 t12 SET t11.c = 2;
|
UPDATE t1 t11, t1 t12 SET t11.c = 3;
|
||||||
SELECT * FROM t1;
|
SELECT * FROM t1;
|
||||||
|
|
||||||
UPDATE t1 t11, t1 t12 SET t11.c = 3;
|
UPDATE t1 t11, t1 t12 SET t11.c = 2;
|
||||||
SELECT * FROM t1;
|
SELECT * FROM t1;
|
||||||
|
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
@ -435,18 +435,31 @@ SELECT * FROM t1;
|
|||||||
a b c
|
a b c
|
||||||
2011-04-20 09:53:41 2011-04-20 09:53:41 2
|
2011-04-20 09:53:41 2011-04-20 09:53:41 2
|
||||||
#
|
#
|
||||||
|
# Test that ON UPDATE CURRENT_TIMESTAMP works after non-changing UPDATE.
|
||||||
|
#
|
||||||
|
# 2011-04-20 09:54:13 UTC
|
||||||
|
SET TIMESTAMP = 1303293253.794613;
|
||||||
|
UPDATE t1 SET c = 2, b = '2011-04-20 09:53:41.794613';
|
||||||
|
SELECT * FROM t1;
|
||||||
|
a b c
|
||||||
|
2011-04-20 09:53:41 2011-04-20 09:53:41 2
|
||||||
|
UPDATE t1 SET c = 3;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
a b c
|
||||||
|
2011-04-20 09:54:13 2011-04-20 09:54:13 3
|
||||||
|
#
|
||||||
# Test of multiple-table UPDATE for ON UPDATE CURRENT_TIMESTAMP
|
# Test of multiple-table UPDATE for ON UPDATE CURRENT_TIMESTAMP
|
||||||
#
|
#
|
||||||
# 2011-04-20 15:06:13 UTC
|
# 2011-04-20 15:06:13 UTC
|
||||||
SET TIMESTAMP = 1303311973.534231;
|
SET TIMESTAMP = 1303311973.534231;
|
||||||
UPDATE t1 t11, t1 t12 SET t11.c = 2;
|
|
||||||
SELECT * FROM t1;
|
|
||||||
a b c
|
|
||||||
2011-04-20 09:53:41 2011-04-20 09:53:41 2
|
|
||||||
UPDATE t1 t11, t1 t12 SET t11.c = 3;
|
UPDATE t1 t11, t1 t12 SET t11.c = 3;
|
||||||
SELECT * FROM t1;
|
SELECT * FROM t1;
|
||||||
a b c
|
a b c
|
||||||
2011-04-20 15:06:13 2011-04-20 15:06:13 3
|
2011-04-20 09:54:13 2011-04-20 09:54:13 3
|
||||||
|
UPDATE t1 t11, t1 t12 SET t11.c = 2;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
a b c
|
||||||
|
2011-04-20 15:06:13 2011-04-20 15:06:13 2
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
#
|
#
|
||||||
# Test of a multiple-table update where only one table is updated and
|
# Test of a multiple-table update where only one table is updated and
|
||||||
@ -1967,18 +1980,31 @@ SELECT * FROM t1;
|
|||||||
a b c
|
a b c
|
||||||
2011-04-20 09:53:41.794613 2011-04-20 09:53:41.794613 2
|
2011-04-20 09:53:41.794613 2011-04-20 09:53:41.794613 2
|
||||||
#
|
#
|
||||||
|
# Test that ON UPDATE CURRENT_TIMESTAMP works after non-changing UPDATE.
|
||||||
|
#
|
||||||
|
# 2011-04-20 09:54:13 UTC
|
||||||
|
SET TIMESTAMP = 1303293253.794613;
|
||||||
|
UPDATE t1 SET c = 2, b = '2011-04-20 09:53:41.794613';
|
||||||
|
SELECT * FROM t1;
|
||||||
|
a b c
|
||||||
|
2011-04-20 09:53:41.794613 2011-04-20 09:53:41.794613 2
|
||||||
|
UPDATE t1 SET c = 3;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
a b c
|
||||||
|
2011-04-20 09:54:13.794613 2011-04-20 09:54:13.794613 3
|
||||||
|
#
|
||||||
# Test of multiple-table UPDATE for ON UPDATE CURRENT_TIMESTAMP
|
# Test of multiple-table UPDATE for ON UPDATE CURRENT_TIMESTAMP
|
||||||
#
|
#
|
||||||
# 2011-04-20 15:06:13 UTC
|
# 2011-04-20 15:06:13 UTC
|
||||||
SET TIMESTAMP = 1303311973.534231;
|
SET TIMESTAMP = 1303311973.534231;
|
||||||
UPDATE t1 t11, t1 t12 SET t11.c = 2;
|
|
||||||
SELECT * FROM t1;
|
|
||||||
a b c
|
|
||||||
2011-04-20 09:53:41.794613 2011-04-20 09:53:41.794613 2
|
|
||||||
UPDATE t1 t11, t1 t12 SET t11.c = 3;
|
UPDATE t1 t11, t1 t12 SET t11.c = 3;
|
||||||
SELECT * FROM t1;
|
SELECT * FROM t1;
|
||||||
a b c
|
a b c
|
||||||
2011-04-20 15:06:13.534231 2011-04-20 15:06:13.534231 3
|
2011-04-20 09:54:13.794613 2011-04-20 09:54:13.794613 3
|
||||||
|
UPDATE t1 t11, t1 t12 SET t11.c = 2;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
a b c
|
||||||
|
2011-04-20 15:06:13.534231 2011-04-20 15:06:13.534231 2
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
#
|
#
|
||||||
# Test of a multiple-table update where only one table is updated and
|
# Test of a multiple-table update where only one table is updated and
|
||||||
|
@ -868,6 +868,8 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
|
|||||||
table_list->prepare_check_option(thd))
|
table_list->prepare_check_option(thd))
|
||||||
error= 1;
|
error= 1;
|
||||||
|
|
||||||
|
table->reset_default_fields();
|
||||||
|
|
||||||
while ((values= its++))
|
while ((values= its++))
|
||||||
{
|
{
|
||||||
if (fields.elements || !value_count)
|
if (fields.elements || !value_count)
|
||||||
@ -1661,6 +1663,13 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
|
|||||||
DBUG_ASSERT(table->insert_values != NULL);
|
DBUG_ASSERT(table->insert_values != NULL);
|
||||||
store_record(table,insert_values);
|
store_record(table,insert_values);
|
||||||
restore_record(table,record[1]);
|
restore_record(table,record[1]);
|
||||||
|
|
||||||
|
/*
|
||||||
|
in INSERT ... ON DUPLICATE KEY UPDATE the set of modified fields can
|
||||||
|
change per row. Thus, we have to do reset_default_fields() per row.
|
||||||
|
Twice (before insert and before update).
|
||||||
|
*/
|
||||||
|
table->reset_default_fields();
|
||||||
DBUG_ASSERT(info->update_fields->elements ==
|
DBUG_ASSERT(info->update_fields->elements ==
|
||||||
info->update_values->elements);
|
info->update_values->elements);
|
||||||
if (fill_record_n_invoke_before_triggers(thd, table, *info->update_fields,
|
if (fill_record_n_invoke_before_triggers(thd, table, *info->update_fields,
|
||||||
@ -1688,6 +1697,7 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
|
|||||||
if (res)
|
if (res)
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
table->reset_default_fields();
|
||||||
|
|
||||||
/* CHECK OPTION for VIEW ... ON DUPLICATE KEY UPDATE ... */
|
/* CHECK OPTION for VIEW ... ON DUPLICATE KEY UPDATE ... */
|
||||||
if (info->view &&
|
if (info->view &&
|
||||||
@ -3473,6 +3483,7 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
|
|||||||
table->file->ha_start_bulk_insert((ha_rows) 0);
|
table->file->ha_start_bulk_insert((ha_rows) 0);
|
||||||
}
|
}
|
||||||
restore_record(table,s->default_values); // Get empty record
|
restore_record(table,s->default_values); // Get empty record
|
||||||
|
table->reset_default_fields();
|
||||||
table->next_number_field=table->found_next_number_field;
|
table->next_number_field=table->found_next_number_field;
|
||||||
|
|
||||||
#ifdef HAVE_REPLICATION
|
#ifdef HAVE_REPLICATION
|
||||||
|
@ -478,6 +478,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
|
|||||||
thd_proc_info(thd, "reading file");
|
thd_proc_info(thd, "reading file");
|
||||||
if (!(error= MY_TEST(read_info.error)))
|
if (!(error= MY_TEST(read_info.error)))
|
||||||
{
|
{
|
||||||
|
table->reset_default_fields();
|
||||||
table->next_number_field=table->found_next_number_field;
|
table->next_number_field=table->found_next_number_field;
|
||||||
if (ignore ||
|
if (ignore ||
|
||||||
handle_duplicates == DUP_REPLACE)
|
handle_duplicates == DUP_REPLACE)
|
||||||
|
@ -717,6 +717,8 @@ int mysql_update(THD *thd,
|
|||||||
if (table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ)
|
if (table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ)
|
||||||
table->prepare_for_position();
|
table->prepare_for_position();
|
||||||
|
|
||||||
|
table->reset_default_fields();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
We can use compare_record() to optimize away updates if
|
We can use compare_record() to optimize away updates if
|
||||||
the table handler is returning all columns OR if
|
the table handler is returning all columns OR if
|
||||||
@ -1693,6 +1695,7 @@ int multi_update::prepare(List<Item> ¬_used_values,
|
|||||||
table->covering_keys.clear_all();
|
table->covering_keys.clear_all();
|
||||||
table->pos_in_table_list= tl;
|
table->pos_in_table_list= tl;
|
||||||
table->prepare_triggers_for_update_stmt_or_event();
|
table->prepare_triggers_for_update_stmt_or_event();
|
||||||
|
table->reset_default_fields();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
10
sql/table.cc
10
sql/table.cc
@ -6736,7 +6736,7 @@ int TABLE::update_default_fields()
|
|||||||
|
|
||||||
DBUG_ASSERT(default_field);
|
DBUG_ASSERT(default_field);
|
||||||
|
|
||||||
/* Iterate over virtual fields in the table */
|
/* Iterate over fields with default functions in the table */
|
||||||
for (dfield_ptr= default_field; *dfield_ptr; dfield_ptr++)
|
for (dfield_ptr= default_field; *dfield_ptr; dfield_ptr++)
|
||||||
{
|
{
|
||||||
dfield= (*dfield_ptr);
|
dfield= (*dfield_ptr);
|
||||||
@ -6753,12 +6753,16 @@ int TABLE::update_default_fields()
|
|||||||
if (res)
|
if (res)
|
||||||
DBUG_RETURN(res);
|
DBUG_RETURN(res);
|
||||||
}
|
}
|
||||||
/* Unset the explicit default flag for the next record. */
|
|
||||||
dfield->flags&= ~HAS_EXPLICIT_VALUE;
|
|
||||||
}
|
}
|
||||||
DBUG_RETURN(res);
|
DBUG_RETURN(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TABLE::reset_default_fields()
|
||||||
|
{
|
||||||
|
if (default_field)
|
||||||
|
for (Field **df= default_field; *df; df++)
|
||||||
|
(*df)->flags&= ~HAS_EXPLICIT_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Prepare triggers for INSERT-like statement.
|
Prepare triggers for INSERT-like statement.
|
||||||
|
@ -1377,6 +1377,7 @@ public:
|
|||||||
uint actual_n_key_parts(KEY *keyinfo);
|
uint actual_n_key_parts(KEY *keyinfo);
|
||||||
ulong actual_key_flags(KEY *keyinfo);
|
ulong actual_key_flags(KEY *keyinfo);
|
||||||
int update_default_fields();
|
int update_default_fields();
|
||||||
|
void reset_default_fields();
|
||||||
inline ha_rows stat_records() { return used_stat_records; }
|
inline ha_rows stat_records() { return used_stat_records; }
|
||||||
|
|
||||||
void prepare_triggers_for_insert_stmt_or_event();
|
void prepare_triggers_for_insert_stmt_or_event();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user