1
0
mirror of https://github.com/MariaDB/server.git synced 2026-01-06 05:22:24 +03:00

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.
This commit is contained in:
Sergey Petrunya
2011-10-01 00:10:03 +04:00
parent 134e417895
commit f5987a0c3e
7 changed files with 183 additions and 51 deletions

View File

@@ -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<TABLE_LIST> 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<TABLE_LIST> 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;