diff options
author | Oleksandr Byelkin <sanja@mariadb.com> | 2015-06-06 16:13:51 +0200 |
---|---|---|
committer | Oleksandr Byelkin <sanja@mariadb.com> | 2015-06-06 16:13:51 +0200 |
commit | 6264451f25143c43e1ad8e045054b720effaf8cb (patch) | |
tree | ab0f44608429ecf9714ed3abf04c4d7574c6bd61 /sql | |
parent | 9a3b975da677e77d63f72f0e6bf0450161b4672d (diff) | |
download | mariadb-git-6264451f25143c43e1ad8e045054b720effaf8cb.tar.gz |
MDEV-8114: server crash on updates with joins still on 10.0.18
Check that leaf table list is really built before storing it.
Diffstat (limited to 'sql')
-rw-r--r-- | sql/sql_base.cc | 3 | ||||
-rw-r--r-- | sql/sql_lex.cc | 14 | ||||
-rw-r--r-- | sql/sql_lex.h | 3 |
3 files changed, 16 insertions, 4 deletions
diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 592215da4d0..fcd17b25b2d 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -8291,9 +8291,10 @@ bool setup_tables(THD *thd, Name_resolution_context *context, if (select_lex->first_cond_optimization) { leaves.empty(); - if (!select_lex->is_prep_leaf_list_saved) + if (select_lex->prep_leaf_list_state != SELECT_LEX::SAVED) { make_leaves_list(leaves, tables, full_table_list, first_select_table); + select_lex->prep_leaf_list_state= SELECT_LEX::READY; select_lex->leaf_tables_exec.empty(); } else diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index a71051e801b..1d62acdbe4b 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -1882,7 +1882,7 @@ void st_select_lex::init_query() exclude_from_table_unique_test= no_wrap_view_item= FALSE; nest_level= 0; link_next= 0; - is_prep_leaf_list_saved= FALSE; + prep_leaf_list_state= UNINIT; bzero((char*) expr_cache_may_be_used, sizeof(expr_cache_may_be_used)); m_non_agg_field_used= false; m_agg_func_used= false; @@ -4129,12 +4129,22 @@ bool st_select_lex::save_prep_leaf_tables(THD *thd) { List_iterator_fast<TABLE_LIST> li(leaf_tables); TABLE_LIST *table; + + /* + Check that the SELECT_LEX was really prepared and so tables are setup. + + It can be subquery in SET clause of UPDATE which was not prepared yet, so + its tables are not yet setup and ready for storing. + */ + if (prep_leaf_list_state != READY) + return FALSE; + while ((table= li++)) { if (leaf_tables_prep.push_back(table)) return TRUE; } - is_prep_leaf_list_saved= TRUE; + prep_leaf_list_state= SAVED; for (SELECT_LEX_UNIT *u= first_inner_unit(); u; u= u->next_unit()) { for (SELECT_LEX *sl= u->first_select(); sl; sl= sl->next_select()) diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 69ee5cc9be0..a0f8e456800 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -789,7 +789,8 @@ public: List<TABLE_LIST> leaf_tables; List<TABLE_LIST> leaf_tables_exec; List<TABLE_LIST> leaf_tables_prep; - bool is_prep_leaf_list_saved; + enum leaf_list_state {UNINIT, READY, SAVED}; + enum leaf_list_state prep_leaf_list_state; uint insert_tables; st_select_lex *merged_into; /* select which this select is merged into */ /* (not 0 only for views/derived tables) */ |