From f5987a0c3ef089439d400217a5784c10fd991f52 Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Sat, 1 Oct 2011 00:10:03 +0400 Subject: BUG#860553: Crash in create_ref_for_key with semijoin + materialization - The problem was that JOIN::save/restore_query_plan() did not save/restore parts of the query plan that are located inside SJ_MATERIALIZATION_INFO structures. This could cause parts of one plan to be used with another, which led get_best_combination() to constructing non-sensical join plans (and crash). Fixed by saving/restoring SJM parts of the query plans. - check_and_do_in_subquery_rewrites() will not set SUBS_MATERIALIZATION flag when it records that the subquery predicate is to be converted into semi-join. If convert_join_subqueries_to_semijoins() later decides not to convert to semi-join, let it set SUBS_MATERIALIZATION flag, if appropriate. --- sql/sql_select.cc | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'sql/sql_select.cc') diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 3d9698d6247..7e32c750ab9 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -21576,6 +21576,15 @@ void JOIN::save_query_plan(Join_plan_state *save_to) memcpy((uchar*) save_to->best_positions, (uchar*) best_positions, sizeof(POSITION) * (table_count + 1)); memset(best_positions, 0, sizeof(POSITION) * (table_count + 1)); + + /* Save SJM nests */ + List_iterator it(select_lex->sj_nests); + TABLE_LIST *tlist; + SJ_MATERIALIZATION_INFO **p_info= save_to->sj_mat_info; + while ((tlist= it++)) + { + *(p_info++)= tlist->sj_mat_info; + } } @@ -21616,6 +21625,14 @@ void JOIN::restore_query_plan(Join_plan_state *restore_from) } memcpy((uchar*) best_positions, (uchar*) restore_from->best_positions, sizeof(POSITION) * (table_count + 1)); + /* Restore SJM nests */ + List_iterator it(select_lex->sj_nests); + TABLE_LIST *tlist; + SJ_MATERIALIZATION_INFO **p_info= restore_from->sj_mat_info; + while ((tlist= it++)) + { + tlist->sj_mat_info= *(p_info++); + } } @@ -21705,6 +21722,9 @@ JOIN::reoptimize(Item *added_where, table_map join_tables, return REOPT_ERROR; optimize_keyuse(this, &keyuse); + if (optimize_semijoin_nests(this, join_tables)) + return REOPT_ERROR; + /* Re-run the join optimizer to compute a new query plan. */ if (choose_plan(this, join_tables)) return REOPT_ERROR; -- cgit v1.2.1