diff options
author | Nikita Malyavin <nikitamalyavin@gmail.com> | 2021-06-26 20:11:56 +0300 |
---|---|---|
committer | Nikita Malyavin <nikitamalyavin@gmail.com> | 2021-07-16 13:31:19 +0300 |
commit | c47e4aab62c65e1a1d431f9888ba1bc6b9841687 (patch) | |
tree | 6f50b28b85c00320651d9589ada644e996c48262 /sql/sql_base.cc | |
parent | 6a89f346dea852b267994e6f32e1c163e7688b34 (diff) | |
download | mariadb-git-c47e4aab62c65e1a1d431f9888ba1bc6b9841687.tar.gz |
MDEV-23597 Assertion `marked_for_read()' failed while evaluating DEFAULT
The columns that are part of DEFAULT expression were not read-marked
in statements like UPDATE...SET b=DEFAULT.
The problem is `F(DEFAULT)` expression depends of the left-hand side of an
assignment. However, setup_fields accepts only right-hand side value.
Neither Item::fix_fields does.
Suchwise, b=DEFAULT(b) works fine, because Item_default_field has
information on what field it is default of:
if (thd->mark_used_columns != MARK_COLUMNS_NONE)
def_field->default_value->expr->update_used_tables();
in Item_default_value::fix_fields().
It is not reasonable to pass a left-hand side to Item:fix_fields, because
the case is rare, so the rewrite
b= F(DEFAULT) -> b= F(DEFAULT(b))
is made instead.
Both UPDATE and multi-UPDATE are affected, however any form of INSERT
is not: it marks all the fields in DEFAULT expressions for read in
TABLE::mark_default_fields_for_write().
Diffstat (limited to 'sql/sql_base.cc')
-rw-r--r-- | sql/sql_base.cc | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 3471297ac7d..9a66b27a454 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -7193,6 +7193,18 @@ int setup_wild(THD *thd, TABLE_LIST *tables, List<Item> &fields, DBUG_RETURN(0); } +/** Transforms b= F(DEFAULT) -> b= F(DEFAULT(b)) */ +void setup_defaults(THD *thd, List<Item> &fields, List<Item> &values) +{ + List_iterator<Item> fit(fields); + List_iterator<Item> vit(values); + + for (Item *value= vit++, *f_item= fit++; value; value= vit++, f_item= fit++) + { + value->walk(&Item::enchant_default_with_arg_processor, false, f_item); + } +} + /**************************************************************************** ** Check that all given fields exists and fill struct with current data ****************************************************************************/ |