summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorMichael Widenius <monty@mariadb.org>2018-06-27 13:17:18 +0300
committerMichael Widenius <monty@mariadb.org>2018-06-27 13:41:19 +0300
commit937c19318819f63d72a66dac5a60c638386512d6 (patch)
treef067609149558da6528ea8352570ce12e7af0000 /sql
parentfaef2e6a44de8e1c1301104671d08dfc1deef1e0 (diff)
downloadmariadb-git-937c19318819f63d72a66dac5a60c638386512d6.tar.gz
Fixed MDEV-16512, crashing on re-execution of failing SP
MDEV-16512 Server crashes in find_field_in_table_ref on 2nd execution of SP referring to non-existing field Problem was in the natural join code that it changed TABLE_LIST and Item_fields but didn't restore changed things if things goes wrong and was not able to re-execute after failure. Some of the problems could have been avoided if we would have run fix_fields before doing natural join transformations. Fixed by marking functions complete AFTER they had executed, instead at start. I had also to change some tests that checked if Item_fields are usable. This doesn't fix all known problems, but at least avoids some crashes. What should be done in the near future is to mark the statement in the SP as 'not re-executable' and force a reparse of it on next execution. Reviewer: Sergei Petrunia <psergey@askmonty.org>
Diffstat (limited to 'sql')
-rw-r--r--sql/sql_base.cc12
-rw-r--r--sql/table.cc6
2 files changed, 10 insertions, 8 deletions
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 71bbb538b5c..8ffb7bc118b 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -7687,6 +7687,7 @@ store_natural_using_join_columns(THD *thd, TABLE_LIST *natural_using_join,
Query_arena *arena, backup;
bool result= TRUE;
List<Natural_join_column> *non_join_columns;
+ List<Natural_join_column> *join_columns;
DBUG_ENTER("store_natural_using_join_columns");
DBUG_ASSERT(!natural_using_join->join_columns);
@@ -7694,7 +7695,7 @@ store_natural_using_join_columns(THD *thd, TABLE_LIST *natural_using_join,
arena= thd->activate_stmt_arena_if_needed(&backup);
if (!(non_join_columns= new List<Natural_join_column>) ||
- !(natural_using_join->join_columns= new List<Natural_join_column>))
+ !(join_columns= new List<Natural_join_column>))
goto err;
/* Append the columns of the first join operand. */
@@ -7703,7 +7704,7 @@ store_natural_using_join_columns(THD *thd, TABLE_LIST *natural_using_join,
nj_col_1= it_1.get_natural_column_ref();
if (nj_col_1->is_common)
{
- natural_using_join->join_columns->push_back(nj_col_1);
+ join_columns->push_back(nj_col_1);
/* Reset the common columns for the next call to mark_common_columns. */
nj_col_1->is_common= FALSE;
}
@@ -7724,7 +7725,7 @@ store_natural_using_join_columns(THD *thd, TABLE_LIST *natural_using_join,
{
const char *using_field_name_ptr= using_field_name->c_ptr();
List_iterator_fast<Natural_join_column>
- it(*(natural_using_join->join_columns));
+ it(*join_columns);
Natural_join_column *common_field;
for (;;)
@@ -7757,7 +7758,8 @@ store_natural_using_join_columns(THD *thd, TABLE_LIST *natural_using_join,
}
if (non_join_columns->elements > 0)
- natural_using_join->join_columns->concat(non_join_columns);
+ join_columns->concat(non_join_columns);
+ natural_using_join->join_columns= join_columns;
natural_using_join->is_join_columns_complete= TRUE;
result= FALSE;
@@ -7989,7 +7991,6 @@ static bool setup_natural_join_row_types(THD *thd,
DBUG_PRINT("info", ("using cached setup_natural_join_row_types"));
DBUG_RETURN(false);
}
- context->select_lex->first_natural_join_processing= false;
List_iterator_fast<TABLE_LIST> table_ref_it(*from_clause);
TABLE_LIST *table_ref; /* Current table reference. */
@@ -8034,6 +8035,7 @@ static bool setup_natural_join_row_types(THD *thd,
change on re-execution
*/
context->natural_join_first_table= context->first_name_resolution_table;
+ context->select_lex->first_natural_join_processing= false;
DBUG_RETURN (false);
}
diff --git a/sql/table.cc b/sql/table.cc
index 87a249defa0..48aa445e1aa 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -5487,7 +5487,7 @@ Field_iterator_table_ref::get_or_create_column_ref(THD *thd, TABLE_LIST *parent_
nj_col= natural_join_it.column_ref();
DBUG_ASSERT(nj_col);
}
- DBUG_ASSERT(!nj_col->table_field ||
+ DBUG_ASSERT(!nj_col->table_field || !nj_col->table_field->field ||
nj_col->table_ref->table == nj_col->table_field->field->table);
/*
@@ -5536,7 +5536,7 @@ Field_iterator_table_ref::get_or_create_column_ref(THD *thd, TABLE_LIST *parent_
RETURN
# Pointer to a column of a natural join (or its operand)
- NULL No memory to allocate the column
+ NULL We didn't originally have memory to allocate the column
*/
Natural_join_column *
@@ -5552,7 +5552,7 @@ Field_iterator_table_ref::get_natural_column_ref()
*/
nj_col= natural_join_it.column_ref();
DBUG_ASSERT(nj_col &&
- (!nj_col->table_field ||
+ (!nj_col->table_field || !nj_col->table_field->field ||
nj_col->table_ref->table == nj_col->table_field->field->table));
return nj_col;
}