1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-29 05:21:33 +03:00

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).
This commit is contained in:
Sergei Petrunia
2019-09-10 23:51:42 +03:00
parent 863a951731
commit c8dc866fde
4 changed files with 52 additions and 28 deletions

View File

@ -88,6 +88,7 @@ class Loose_scan_opt
KEYUSE *best_loose_scan_start_key;
uint best_max_loose_keypart;
table_map best_ref_depend_map;
public:
Loose_scan_opt():
@ -250,13 +251,14 @@ public:
best_loose_scan_records= records;
best_max_loose_keypart= max_loose_keypart;
best_loose_scan_start_key= start_key;
best_ref_depend_map= 0;
}
}
}
}
void check_ref_access_part2(uint key, KEYUSE *start_key, double records,
double read_time)
double read_time, table_map ref_depend_map_arg)
{
if (part1_conds_met && read_time < best_loose_scan_cost)
{
@ -266,6 +268,7 @@ public:
best_loose_scan_records= records;
best_max_loose_keypart= max_loose_keypart;
best_loose_scan_start_key= start_key;
best_ref_depend_map= ref_depend_map_arg;
}
}
@ -281,6 +284,7 @@ public:
best_loose_scan_records= rows2double(quick->records);
best_max_loose_keypart= quick_max_loose_keypart;
best_loose_scan_start_key= NULL;
best_ref_depend_map= 0;
}
}
@ -296,7 +300,7 @@ public:
pos->loosescan_picker.loosescan_parts= best_max_loose_keypart + 1;
pos->use_join_buffer= FALSE;
pos->table= tab;
// todo need ref_depend_map ?
pos->ref_depend_map= best_ref_depend_map;
DBUG_PRINT("info", ("Produced a LooseScan plan, key %s, %s",
tab->table->key_info[best_loose_scan_key].name,
best_loose_scan_start_key? "(ref access)":