diff --git a/mysql-test/suite/sql_sequence/other.result b/mysql-test/suite/sql_sequence/other.result index a77c70a964b..92c881a60b3 100644 --- a/mysql-test/suite/sql_sequence/other.result +++ b/mysql-test/suite/sql_sequence/other.result @@ -394,4 +394,20 @@ create table t (id bigint default(nextval(s))) engine=myisam; insert delayed into t () values(); drop table t; drop sequence s; +# +# MDEV-37345 Item_func_nextval::val_int() crash on INSERT...SELECT with subqueries +# +create sequence s; +create table t1 (a int, b int default(nextval(s))); +insert into t1 () values (); +create table t2 (c int); +create procedure p() update t1 set a = 0; +create trigger tr after insert on t2 for each row +begin +insert into t1 () values (); +call p(); +end $ +insert into t2 values (); +drop table t1, t2, s; +drop procedure p; # End of 10.11 tests diff --git a/mysql-test/suite/sql_sequence/other.test b/mysql-test/suite/sql_sequence/other.test index f0aaed0a4c1..0d9e457e236 100644 --- a/mysql-test/suite/sql_sequence/other.test +++ b/mysql-test/suite/sql_sequence/other.test @@ -428,4 +428,24 @@ insert delayed into t () values(); drop table t; drop sequence s; +--echo # +--echo # MDEV-37345 Item_func_nextval::val_int() crash on INSERT...SELECT with subqueries +--echo # +# sequence and prelocking. +create sequence s; +create table t1 (a int, b int default(nextval(s))); +insert into t1 () values (); +create table t2 (c int); +create procedure p() update t1 set a = 0; +--delimiter $ +create trigger tr after insert on t2 for each row +begin + insert into t1 () values (); + call p(); +end $ +--delimiter ; +insert into t2 values (); +drop table t1, t2, s; +drop procedure p; + --echo # End of 10.11 tests diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 1eea27607ed..8259d4170c2 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -2010,7 +2010,18 @@ bool open_table(THD *thd, TABLE_LIST *table_list, Open_table_context *ot_ctx) table->query_id == 0)) { int distance= ((int) table->reginfo.lock_type - - (int) table_list->lock_type); + (int) table_list->lock_type) * 2; + TABLE_LIST *tl= thd->locked_tables_mode == LTM_PRELOCKED + ? table->pos_in_table_list : table->pos_in_locked_tables; + /* + note, that merge table children are automatically added to + prelocking set in ha_myisammrg::add_children_list(), but their + TABLE_LIST's are on the execution arena, so tl will be invalid + on the second execution. Let's just skip them below. + */ + if (table_list->parent_l || !tl || + table_list->for_insert_data != tl->for_insert_data) + distance|= 1; /* Find a table that either has the exact lock type requested,