summaryrefslogtreecommitdiff
path: root/sql/opt_subselect.cc
diff options
context:
space:
mode:
authorSergei Petrunia <psergey@askmonty.org>2019-09-10 23:51:42 +0300
committerSergei Petrunia <psergey@askmonty.org>2019-09-11 17:06:50 +0300
commitc8dc866fdeee551993ef91fb321135f9106ea00e (patch)
treed74301fbc473f28660e57b43bc836fc3b643f628 /sql/opt_subselect.cc
parent863a95173110e1528e7a47fe688fea8784eb67b6 (diff)
downloadmariadb-git-c8dc866fdeee551993ef91fb321135f9106ea00e.tar.gz
MDEV-20371: Invalid reads at plan refinement stage: join->positions...
best_access_path() is called from two optimization phases: 1. Plan choice phase, in choose_plan(). Here, the join prefix being considered is in join->positions[] 2. Plan refinement stage, in fix_semijoin_strategies_for_picked_join_order Here, the join prefix is in join->best_positions[] It used to access join->positions[] from stage #2. This didnt cause any valgrind or asan failures (as join->positions[] has been written-to before) but the effect was similar to that of reading the random data: The join prefix we've picked (in join->best_positions) could have nothing in common with the join prefix that was last to be considered (in join->positions).
Diffstat (limited to 'sql/opt_subselect.cc')
-rw-r--r--sql/opt_subselect.cc26
1 files changed, 16 insertions, 10 deletions
diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc
index 99fa1c7344f..1d3ebba4f4e 100644
--- a/sql/opt_subselect.cc
+++ b/sql/opt_subselect.cc
@@ -456,11 +456,6 @@ bool find_eq_ref_candidate(TABLE *table, table_map sj_inner_tables);
static SJ_MATERIALIZATION_INFO *
at_sjmat_pos(const JOIN *join, table_map remaining_tables, const JOIN_TAB *tab,
uint idx, bool *loose_scan);
-void best_access_path(JOIN *join, JOIN_TAB *s,
- table_map remaining_tables, uint idx,
- bool disable_jbuf, double record_count,
- POSITION *pos, POSITION *loose_scan_pos);
-
static Item *create_subq_in_equalities(THD *thd, SJ_MATERIALIZATION_INFO *sjm,
Item_in_subselect *subq_pred);
static void remove_sj_conds(THD *thd, Item **tree);
@@ -2756,6 +2751,13 @@ void advance_sj_state(JOIN *join, table_map remaining_tables, uint idx,
NULL,
};
+#ifdef HAVE_valgrind
+ new (&pos->firstmatch_picker) Firstmatch_picker;
+ new (&pos->loosescan_picker) LooseScan_picker;
+ new (&pos->sjmat_picker) Sj_materialization_picker;
+ new (&pos->dups_weedout_picker) Duplicate_weedout_picker;
+#endif
+
if (join->emb_sjm_nest)
{
/*
@@ -3045,7 +3047,8 @@ bool Sj_materialization_picker::check_qep(JOIN *join,
bool disable_jbuf= (join->thd->variables.join_cache_level == 0);
for (i= first_tab + mat_info->tables; i <= idx; i++)
{
- best_access_path(join, join->positions[i].table, rem_tables, i,
+ best_access_path(join, join->positions[i].table, rem_tables,
+ join->positions, i,
disable_jbuf, prefix_rec_count, &curpos, &dummy);
prefix_rec_count= COST_MULT(prefix_rec_count, curpos.records_read);
prefix_cost= COST_ADD(prefix_cost, curpos.read_time);
@@ -3661,7 +3664,8 @@ void fix_semijoin_strategies_for_picked_join_order(JOIN *join)
join->cur_sj_inner_tables= 0;
for (i= first + sjm->tables; i <= tablenr; i++)
{
- best_access_path(join, join->best_positions[i].table, rem_tables, i,
+ best_access_path(join, join->best_positions[i].table, rem_tables,
+ join->best_positions, i,
FALSE, prefix_rec_count,
join->best_positions + i, &dummy);
prefix_rec_count *= join->best_positions[i].records_read;
@@ -3693,8 +3697,9 @@ void fix_semijoin_strategies_for_picked_join_order(JOIN *join)
{
if (join->best_positions[idx].use_join_buffer)
{
- best_access_path(join, join->best_positions[idx].table,
- rem_tables, idx, TRUE /* no jbuf */,
+ best_access_path(join, join->best_positions[idx].table,
+ rem_tables, join->best_positions, idx,
+ TRUE /* no jbuf */,
record_count, join->best_positions + idx, &dummy);
}
record_count *= join->best_positions[idx].records_read;
@@ -3724,7 +3729,8 @@ void fix_semijoin_strategies_for_picked_join_order(JOIN *join)
if (join->best_positions[idx].use_join_buffer || (idx == first))
{
best_access_path(join, join->best_positions[idx].table,
- rem_tables, idx, TRUE /* no jbuf */,
+ rem_tables, join->best_positions, idx,
+ TRUE /* no jbuf */,
record_count, join->best_positions + idx,
&loose_scan_pos);
if (idx==first)