Commit c7c481f4 authored by Sergei Golubchik's avatar Sergei Golubchik

MDEV-20403 Assertion `0' or Assertion `btr_validate_index(index, 0)' failed in...

MDEV-20403 Assertion `0' or Assertion `btr_validate_index(index, 0)' failed in row_upd_sec_index_entry or error code 126: Index is corrupted upon UPDATE with TIMESTAMP..ON UPDATE

Three issues here:
* ON UPDATE DEFAULT NOW columns were updated after generated columns
  were computed - this broke indexed virtual columns
* ON UPDATE DEFAULT NOW columns were updated after BEFORE triggers,
  so triggers didn't see the correct NEW value
* in case of a multi-update generated columns were also updated
  after BEFORE triggers
parent 3789692d
...@@ -3093,3 +3093,26 @@ a b ...@@ -3093,3 +3093,26 @@ a b
1999-12-01 11:22:33.000000 1999-12-01 11:22:33.000000 1999-12-01 11:22:33.000000 1999-12-01 11:22:33.000000
2001-09-09 04:46:40.000000 2001-09-09 04:46:40.000000 2001-09-09 04:46:40.000000 2001-09-09 04:46:40.000000
DROP TABLE t1; DROP TABLE t1;
create table t1 (t timestamp, i int, v timestamp as (t) virtual, key(v));
insert t1 (t,i) values ('2006-03-01 23:59:59',1);
update t1 set i = 2;
check table t1;
Table Op Msg_type Msg_text
test.t1 check status OK
drop table t1;
create table t1 (t timestamp, i int);
create trigger tr1 before update on t1 for each row set @new:=new.t;
insert t1 (t,i) values ('2006-03-01 23:59:59', 1);
update t1 set i = 2;
select if(@new = t, 'correct', 'wrong') from t1;
if(@new = t, 'correct', 'wrong')
correct
drop table t1;
create table t1 (i int, j int as (i));
create trigger tr1 before update on t1 for each row set @new:=new.j;
insert t1 (i) values (1);
update t1, t1 as t2 set t1.i = 2;
select if(@new = j, 'correct', 'wrong') from t1;
if(@new = j, 'correct', 'wrong')
correct
drop table t1;
...@@ -19,3 +19,30 @@ let $now=NOW(6); ...@@ -19,3 +19,30 @@ let $now=NOW(6);
let $timestamp=TIMESTAMP(6); let $timestamp=TIMESTAMP(6);
let $datetime=DATETIME(6); let $datetime=DATETIME(6);
source 'include/function_defaults.inc'; source 'include/function_defaults.inc';
#
# MDEV-20403 Assertion `0' or Assertion `btr_validate_index(index, 0)' failed in row_upd_sec_index_entry or error code 126: Index is corrupted upon UPDATE with TIMESTAMP..ON UPDATE
#
# ON UPDATE DEFAULT NOW and indexed virtual columns
create table t1 (t timestamp, i int, v timestamp as (t) virtual, key(v));
insert t1 (t,i) values ('2006-03-01 23:59:59',1);
update t1 set i = 2;
check table t1;
drop table t1;
# ON UPDATE DEFAULT NOW and triggers
create table t1 (t timestamp, i int);
create trigger tr1 before update on t1 for each row set @new:=new.t;
insert t1 (t,i) values ('2006-03-01 23:59:59', 1);
update t1 set i = 2;
select if(@new = t, 'correct', 'wrong') from t1;
drop table t1;
# triggers, virtual columns, multi-update
create table t1 (i int, j int as (i));
create trigger tr1 before update on t1 for each row set @new:=new.j;
insert t1 (i) values (1);
update t1, t1 as t2 set t1.i = 2;
select if(@new = j, 'correct', 'wrong') from t1;
drop table t1;
...@@ -8071,9 +8071,13 @@ fill_record(THD *thd, TABLE *table_arg, List<Item> &fields, List<Item> &values, ...@@ -8071,9 +8071,13 @@ fill_record(THD *thd, TABLE *table_arg, List<Item> &fields, List<Item> &values,
rfield->set_explicit_default(value); rfield->set_explicit_default(value);
} }
if (!update && table_arg->default_field && if (update)
table_arg->update_default_fields(ignore_errors)) table_arg->evaluate_update_default_function();
goto err; else
if (table_arg->default_field &&
table_arg->update_default_fields(ignore_errors))
goto err;
/* Update virtual fields */ /* Update virtual fields */
if (table_arg->vfield && if (table_arg->vfield &&
table_arg->update_virtual_fields(table_arg->file, VCOL_UPDATE_FOR_WRITE)) table_arg->update_virtual_fields(table_arg->file, VCOL_UPDATE_FOR_WRITE))
......
...@@ -66,12 +66,15 @@ bool compare_record(const TABLE *table) ...@@ -66,12 +66,15 @@ bool compare_record(const TABLE *table)
{ {
DBUG_ASSERT(records_are_comparable(table)); DBUG_ASSERT(records_are_comparable(table));
if ((table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ) != 0) if (table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ ||
table->s->has_update_default_function)
{ {
/* /*
Storage engine may not have read all columns of the record. Fields Storage engine may not have read all columns of the record. Fields
(including NULL bits) not in the write_set may not have been read and (including NULL bits) not in the write_set may not have been read and
can therefore not be compared. can therefore not be compared.
Or ON UPDATE DEFAULT NOW() could've changed field values, including
NULL bits.
*/ */
for (Field **ptr= table->field ; *ptr != NULL; ptr++) for (Field **ptr= table->field ; *ptr != NULL; ptr++)
{ {
...@@ -762,8 +765,6 @@ int mysql_update(THD *thd, ...@@ -762,8 +765,6 @@ int mysql_update(THD *thd,
if (!can_compare_record || compare_record(table)) if (!can_compare_record || compare_record(table))
{ {
if (table->default_field)
table->evaluate_update_default_function();
if ((res= table_list->view_check_option(thd, ignore)) != if ((res= table_list->view_check_option(thd, ignore)) !=
VIEW_CHECK_OK) VIEW_CHECK_OK)
{ {
...@@ -2154,9 +2155,6 @@ int multi_update::send_data(List<Item> &not_used_values) ...@@ -2154,9 +2155,6 @@ int multi_update::send_data(List<Item> &not_used_values)
{ {
int error; int error;
if (table->default_field)
table->evaluate_update_default_function();
if ((error= cur_table->view_check_option(thd, ignore)) != if ((error= cur_table->view_check_option(thd, ignore)) !=
VIEW_CHECK_OK) VIEW_CHECK_OK)
{ {
...@@ -2472,6 +2470,10 @@ int multi_update::do_updates() ...@@ -2472,6 +2470,10 @@ int multi_update::do_updates()
copy_field_ptr->to_field->set_has_explicit_value(); copy_field_ptr->to_field->set_has_explicit_value();
} }
table->evaluate_update_default_function();
if (table->vfield &&
table->update_virtual_fields(table->file, VCOL_UPDATE_FOR_WRITE))
goto err2;
if (table->triggers && if (table->triggers &&
table->triggers->process_triggers(thd, TRG_EVENT_UPDATE, table->triggers->process_triggers(thd, TRG_EVENT_UPDATE,
TRG_ACTION_BEFORE, TRUE)) TRG_ACTION_BEFORE, TRUE))
...@@ -2480,11 +2482,6 @@ int multi_update::do_updates() ...@@ -2480,11 +2482,6 @@ int multi_update::do_updates()
if (!can_compare_record || compare_record(table)) if (!can_compare_record || compare_record(table))
{ {
int error; int error;
if (table->default_field)
table->evaluate_update_default_function();
if (table->vfield &&
table->update_virtual_fields(table->file, VCOL_UPDATE_FOR_WRITE))
goto err2;
if ((error= cur_table->view_check_option(thd, ignore)) != if ((error= cur_table->view_check_option(thd, ignore)) !=
VIEW_CHECK_OK) VIEW_CHECK_OK)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment