diff options
author | Alexander Barkov <bar@mariadb.org> | 2015-12-29 19:37:11 +0400 |
---|---|---|
committer | Alexander Barkov <bar@mariadb.org> | 2015-12-29 19:37:11 +0400 |
commit | 2ba7ed77aab05004f0c853a77850e325b78a1892 (patch) | |
tree | 943659d76215e16d0d1946c28683c562debeff34 /sql/sql_base.cc | |
parent | 63f0669fd6dc430b60ffd5de0bff9854622a1c1a (diff) | |
parent | 1bb66ea88c4679d6bd3ad1472d75983e66f679ae (diff) | |
download | mariadb-git-2ba7ed77aab05004f0c853a77850e325b78a1892.tar.gz |
Merge remote-tracking branch 'origin/10.1' into 10.2
Diffstat (limited to 'sql/sql_base.cc')
-rw-r--r-- | sql/sql_base.cc | 77 |
1 files changed, 69 insertions, 8 deletions
diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 5c3b7c236c0..1ff3625e2db 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -8818,7 +8818,61 @@ err: } -/* +/** + Prepare Item_field's for fill_record_n_invoke_before_triggers() + + This means redirecting from table->field to + table->field_to_fill(), if needed. +*/ +void switch_to_nullable_trigger_fields(List<Item> &items, TABLE *table) +{ + Field** field= table->field_to_fill(); + + if (field != table->field) + { + List_iterator_fast<Item> it(items); + Item *item; + + while ((item= it++)) + item->walk(&Item::switch_to_nullable_fields_processor, 1, (uchar*)field); + table->triggers->reset_extra_null_bitmap(); + } +} + + +/** + Test NOT NULL constraint after BEFORE triggers +*/ +static bool not_null_fields_have_null_values(TABLE *table) +{ + Field **orig_field= table->field; + Field **filled_field= table->field_to_fill(); + + if (filled_field != orig_field) + { + THD *thd=table->in_use; + for (uint i=0; i < table->s->fields; i++) + { + Field *of= orig_field[i]; + Field *ff= filled_field[i]; + if (ff != of) + { + // copy after-update flags to of, copy before-update flags to ff + swap_variables(uint32, of->flags, ff->flags); + if (ff->is_real_null()) + { + ff->set_notnull(); // for next row WHERE condition in UPDATE + if (convert_null_to_field_value_or_error(of) || thd->is_error()) + return true; + } + } + } + } + + return false; +} + +/** Fill fields in list with values from the list of items and invoke before triggers. @@ -8846,14 +8900,18 @@ fill_record_n_invoke_before_triggers(THD *thd, TABLE *table, List<Item> &fields, { bool result; Table_triggers_list *triggers= table->triggers; - result= (fill_record(thd, table, fields, values, ignore_errors) || - (triggers && triggers->process_triggers(thd, event, - TRG_ACTION_BEFORE, TRUE))); + + result= fill_record(thd, table, fields, values, ignore_errors); + + if (!result && triggers) + result= triggers->process_triggers(thd, event, TRG_ACTION_BEFORE, TRUE) || + not_null_fields_have_null_values(table); + /* Re-calculate virtual fields to cater for cases when base columns are updated by the triggers. */ - if (!result && triggers && table) + if (!result && triggers) { List_iterator_fast<Item> f(fields); Item *fld; @@ -8994,9 +9052,12 @@ fill_record_n_invoke_before_triggers(THD *thd, TABLE *table, Field **ptr, { bool result; Table_triggers_list *triggers= table->triggers; - result= (fill_record(thd, table, ptr, values, ignore_errors, FALSE) || - (triggers && triggers->process_triggers(thd, event, - TRG_ACTION_BEFORE, TRUE))); + + result= fill_record(thd, table, ptr, values, ignore_errors, FALSE); + + if (!result && triggers && *ptr) + result= triggers->process_triggers(thd, event, TRG_ACTION_BEFORE, TRUE) || + not_null_fields_have_null_values(table); /* Re-calculate virtual fields to cater for cases when base columns are updated by the triggers. |