summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorOleksandr Byelkin <sanja@mariadb.com>2015-06-06 16:13:51 +0200
committerOleksandr Byelkin <sanja@mariadb.com>2015-06-06 16:13:51 +0200
commit6264451f25143c43e1ad8e045054b720effaf8cb (patch)
treeab0f44608429ecf9714ed3abf04c4d7574c6bd61 /sql
parent9a3b975da677e77d63f72f0e6bf0450161b4672d (diff)
downloadmariadb-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.cc3
-rw-r--r--sql/sql_lex.cc14
-rw-r--r--sql/sql_lex.h3
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) */