1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-30 16:24:05 +03:00

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().
This commit is contained in:
Nikita Malyavin
2021-06-26 20:11:56 +03:00
parent 6a89f346de
commit c47e4aab62
11 changed files with 111 additions and 10 deletions

View File

@ -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
****************************************************************************/