MDEV-11706 Assertion `is_stat_field || !table || (!table->write_set || bitmap_is_set(table->write_set, field_index) || (table->vcol_set && bitmap_is_set(table->vcol_set, field_index)))' failed in Field_time::store_TIME_with_warning

vcols and triggers. Revert 094f4cf77890c5a747a57cf2bed149b0b6933507,
backport the correct fix (Table_triggers_list::mark_fields_used() not
marking vcols) from 10.2.
This commit is contained in:
Sergei Golubchik 2017-01-11 19:12:21 +01:00
parent ab93a4d4df
commit 0d1d0d77f2
9 changed files with 39 additions and 39 deletions

View File

@ -110,7 +110,7 @@ drop table t1,t2;
drop procedure p1; drop procedure p1;
--echo # --echo #
--echo # Bug mdev-3845: values of virtual columns are not computed for triggers --echo # MDEV-3845 values of virtual columns are not computed for triggers
--echo # --echo #
CREATE TABLE t1 ( CREATE TABLE t1 (
@ -149,3 +149,10 @@ DROP TRIGGER t1_ins_aft;
DROP TRIGGER t1_del_bef; DROP TRIGGER t1_del_bef;
DROP TABLE t1,t2; DROP TABLE t1,t2;
#
# MDEV-11706 Assertion `is_stat_field || !table || (!table->write_set || bitmap_is_set(table->write_set, field_index) || (table->vcol_set && bitmap_is_set(table->vcol_set, field_index)))' failed in Field_time::store_TIME_with_warning
#
create table t1 (i int, t time not null, vt time(4) as (t) virtual);
create trigger trg before update on t1 for each row set @a = 1;
insert ignore into t1 (i) values (1);
drop table t1;

View File

@ -86,7 +86,7 @@ a b c
drop table t1,t2; drop table t1,t2;
drop procedure p1; drop procedure p1;
# #
# Bug mdev-3845: values of virtual columns are not computed for triggers # MDEV-3845 values of virtual columns are not computed for triggers
# #
CREATE TABLE t1 ( CREATE TABLE t1 (
a INTEGER UNSIGNED NULL DEFAULT NULL, a INTEGER UNSIGNED NULL DEFAULT NULL,
@ -125,3 +125,9 @@ c
DROP TRIGGER t1_ins_aft; DROP TRIGGER t1_ins_aft;
DROP TRIGGER t1_del_bef; DROP TRIGGER t1_del_bef;
DROP TABLE t1,t2; DROP TABLE t1,t2;
create table t1 (i int, t time not null, vt time(4) as (t) virtual);
create trigger trg before update on t1 for each row set @a = 1;
insert ignore into t1 (i) values (1);
Warnings:
Warning 1364 Field 't' doesn't have a default value
drop table t1;

View File

@ -86,7 +86,7 @@ a b c
drop table t1,t2; drop table t1,t2;
drop procedure p1; drop procedure p1;
# #
# Bug mdev-3845: values of virtual columns are not computed for triggers # MDEV-3845 values of virtual columns are not computed for triggers
# #
CREATE TABLE t1 ( CREATE TABLE t1 (
a INTEGER UNSIGNED NULL DEFAULT NULL, a INTEGER UNSIGNED NULL DEFAULT NULL,
@ -125,3 +125,9 @@ c
DROP TRIGGER t1_ins_aft; DROP TRIGGER t1_ins_aft;
DROP TRIGGER t1_del_bef; DROP TRIGGER t1_del_bef;
DROP TABLE t1,t2; DROP TABLE t1,t2;
create table t1 (i int, t time not null, vt time(4) as (t) virtual);
create trigger trg before update on t1 for each row set @a = 1;
insert ignore into t1 (i) values (1);
Warnings:
Warning 1364 Field 't' doesn't have a default value
drop table t1;

View File

@ -9033,9 +9033,7 @@ fill_record(THD * thd, List<Item> &fields, List<Item> &values,
/* Update virtual fields*/ /* Update virtual fields*/
thd->abort_on_warning= FALSE; thd->abort_on_warning= FALSE;
if (vcol_table && vcol_table->vfield && if (vcol_table && vcol_table->vfield &&
update_virtual_fields(thd, vcol_table, update_virtual_fields(thd, vcol_table, VCOL_UPDATE_FOR_WRITE))
vcol_table->triggers ? VCOL_UPDATE_ALL :
VCOL_UPDATE_FOR_WRITE))
goto err; goto err;
thd->abort_on_warning= save_abort_on_warning; thd->abort_on_warning= save_abort_on_warning;
thd->no_errors= save_no_errors; thd->no_errors= save_no_errors;
@ -9099,9 +9097,7 @@ fill_record_n_invoke_before_triggers(THD *thd, List<Item> &fields,
if (item_field && item_field->field && if (item_field && item_field->field &&
(table= item_field->field->table) && (table= item_field->field->table) &&
table->vfield) table->vfield)
result= update_virtual_fields(thd, table, result= update_virtual_fields(thd, table, VCOL_UPDATE_FOR_WRITE);
table->triggers ? VCOL_UPDATE_ALL :
VCOL_UPDATE_FOR_WRITE);
} }
} }
return result; return result;
@ -9186,9 +9182,7 @@ fill_record(THD *thd, Field **ptr, List<Item> &values, bool ignore_errors,
/* Update virtual fields*/ /* Update virtual fields*/
thd->abort_on_warning= FALSE; thd->abort_on_warning= FALSE;
if (table->vfield && if (table->vfield &&
update_virtual_fields(thd, table, update_virtual_fields(thd, table, VCOL_UPDATE_FOR_WRITE))
table->triggers ? VCOL_UPDATE_ALL :
VCOL_UPDATE_FOR_WRITE))
goto err; goto err;
thd->abort_on_warning= abort_on_warning_saved; thd->abort_on_warning= abort_on_warning_saved;
DBUG_RETURN(thd->is_error()); DBUG_RETURN(thd->is_error());
@ -9241,9 +9235,7 @@ fill_record_n_invoke_before_triggers(THD *thd, Field **ptr,
{ {
TABLE *table= (*ptr)->table; TABLE *table= (*ptr)->table;
if (table->vfield) if (table->vfield)
result= update_virtual_fields(thd, table, result= update_virtual_fields(thd, table, VCOL_UPDATE_FOR_WRITE);
table->triggers ? VCOL_UPDATE_ALL :
VCOL_UPDATE_FOR_WRITE);
} }
return result; return result;

View File

@ -328,9 +328,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
! thd->is_error()) ! thd->is_error())
{ {
if (table->vfield) if (table->vfield)
update_virtual_fields(thd, table, update_virtual_fields(thd, table, VCOL_UPDATE_FOR_READ);
table->triggers ? VCOL_UPDATE_ALL :
VCOL_UPDATE_FOR_READ);
thd->examined_row_count++; thd->examined_row_count++;
// thd->is_error() is tested to disallow delete row on error // thd->is_error() is tested to disallow delete row on error
if (!select || select->skip_record(thd) > 0) if (!select || select->skip_record(thd) > 0)
@ -1073,4 +1071,3 @@ bool multi_delete::send_eof()
} }
return 0; return 0;
} }

View File

@ -2246,6 +2246,9 @@ void Table_triggers_list::mark_fields_used(trg_event_type event)
bitmap_set_bit(trigger_table->read_set, trg_field->field_idx); bitmap_set_bit(trigger_table->read_set, trg_field->field_idx);
if (trg_field->get_settable_routine_parameter()) if (trg_field->get_settable_routine_parameter())
bitmap_set_bit(trigger_table->write_set, trg_field->field_idx); bitmap_set_bit(trigger_table->write_set, trg_field->field_idx);
if (trigger_table->field[trg_field->field_idx]->vcol_info)
trigger_table->mark_virtual_col(trigger_table->
field[trg_field->field_idx]);
} }
} }
} }

View File

@ -569,9 +569,7 @@ int mysql_update(THD *thd,
while (!(error=info.read_record(&info)) && !thd->killed) while (!(error=info.read_record(&info)) && !thd->killed)
{ {
if (table->vfield) if (table->vfield)
update_virtual_fields(thd, table, update_virtual_fields(thd, table, VCOL_UPDATE_FOR_READ);
table->triggers ? VCOL_UPDATE_ALL :
VCOL_UPDATE_FOR_READ);
thd->examined_row_count++; thd->examined_row_count++;
if (!select || (error= select->skip_record(thd)) > 0) if (!select || (error= select->skip_record(thd)) > 0)
{ {
@ -695,9 +693,7 @@ int mysql_update(THD *thd,
while (!(error=info.read_record(&info)) && !thd->killed) while (!(error=info.read_record(&info)) && !thd->killed)
{ {
if (table->vfield) if (table->vfield)
update_virtual_fields(thd, table, update_virtual_fields(thd, table, VCOL_UPDATE_FOR_READ);
table->triggers ? VCOL_UPDATE_ALL :
VCOL_UPDATE_FOR_READ);
thd->examined_row_count++; thd->examined_row_count++;
if (!select || select->skip_record(thd) > 0) if (!select || select->skip_record(thd) > 0)
{ {
@ -2235,10 +2231,7 @@ int multi_update::do_updates()
{ {
int error; int error;
if (table->vfield && if (table->vfield &&
update_virtual_fields(thd, table, update_virtual_fields(thd, table, VCOL_UPDATE_FOR_WRITE))
(table->triggers ?
VCOL_UPDATE_ALL :
VCOL_UPDATE_FOR_WRITE)))
goto err2; 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)

View File

@ -6557,11 +6557,9 @@ bool is_simple_order(ORDER *order)
@details @details
The function computes the values of the virtual columns of the table and The function computes the values of the virtual columns of the table and
stores them in the table record buffer. stores them in the table record buffer.
If vcol_update_mode is set to VCOL_UPDATE_ALL then all virtual column are Only fields from vcol_set are computed: all of them, if vcol_update_mode is
computed. Otherwise, only fields from vcol_set are computed: all of them, set to VCOL_UPDATE_FOR_WRITE, and, only those with the stored_in_db flag
if vcol_update_mode is set to VCOL_UPDATE_FOR_WRITE, and, only those with set to false, if vcol_update_mode is equal to VCOL_UPDATE_FOR_READ.
the stored_in_db flag set to false, if vcol_update_mode is equal to
VCOL_UPDATE_FOR_READ.
@retval @retval
0 Success 0 Success
@ -6583,9 +6581,8 @@ int update_virtual_fields(THD *thd, TABLE *table,
{ {
vfield= (*vfield_ptr); vfield= (*vfield_ptr);
DBUG_ASSERT(vfield->vcol_info && vfield->vcol_info->expr_item); DBUG_ASSERT(vfield->vcol_info && vfield->vcol_info->expr_item);
if ((bitmap_is_set(table->vcol_set, vfield->field_index) && if (bitmap_is_set(table->vcol_set, vfield->field_index) &&
(vcol_update_mode == VCOL_UPDATE_FOR_WRITE || !vfield->stored_in_db)) || (vcol_update_mode == VCOL_UPDATE_FOR_WRITE || !vfield->stored_in_db))
vcol_update_mode == VCOL_UPDATE_ALL)
{ {
/* Compute the actual value of the virtual fields */ /* Compute the actual value of the virtual fields */
error= vfield->vcol_info->expr_item->save_in_field(vfield, 0); error= vfield->vcol_info->expr_item->save_in_field(vfield, 0);

View File

@ -302,8 +302,7 @@ enum release_type { RELEASE_NORMAL, RELEASE_WAIT_FOR_DROP };
enum enum_vcol_update_mode enum enum_vcol_update_mode
{ {
VCOL_UPDATE_FOR_READ= 0, VCOL_UPDATE_FOR_READ= 0,
VCOL_UPDATE_FOR_WRITE, VCOL_UPDATE_FOR_WRITE
VCOL_UPDATE_ALL
}; };
typedef struct st_filesort_info typedef struct st_filesort_info