Commit 849f56e8 authored by unknown's avatar unknown

MWL#89

- fixed incorrect query plans that resulted from emptying the
  keyuse array with the access methods of the non-modified query
  plan.
- fixed compiler warning.
parent 6a4ae290
......@@ -29,9 +29,9 @@ static TABLE_LIST *alloc_join_nest(THD *thd);
static
void fix_list_after_tbl_changes(SELECT_LEX *new_parent, List<TABLE_LIST> *tlist);
static uint get_tmp_table_rec_length(List<Item> &items);
static double get_tmp_table_lookup_cost(THD *thd, ha_rows row_count,
static double get_tmp_table_lookup_cost(THD *thd, double row_count,
uint row_size);
static double get_tmp_table_write_cost(THD *thd, ha_rows row_count,
static double get_tmp_table_write_cost(THD *thd, double row_count,
uint row_size);
bool find_eq_ref_candidate(TABLE *table, table_map sj_inner_tables);
static SJ_MATERIALIZATION_INFO *
......@@ -1350,7 +1350,8 @@ static uint get_tmp_table_rec_length(List<Item> &items)
@return the cost of one lookup
*/
static double get_tmp_table_lookup_cost(THD *thd, ha_rows row_count, uint row_size)
static double
get_tmp_table_lookup_cost(THD *thd, double row_count, uint row_size)
{
if (row_count * row_size > thd->variables.max_heap_table_size)
return (double) DISK_TEMPTABLE_LOOKUP_COST;
......@@ -1369,7 +1370,8 @@ static double get_tmp_table_lookup_cost(THD *thd, ha_rows row_count, uint row_si
@return the cost of writing one row
*/
static double get_tmp_table_write_cost(THD *thd, ha_rows row_count, uint row_size)
static double
get_tmp_table_write_cost(THD *thd, double row_count, uint row_size)
{
double lookup_cost= get_tmp_table_lookup_cost(thd, row_count, row_size);
/*
......
......@@ -19727,12 +19727,9 @@ void JOIN::save_query_plan(Query_plan_state *save_to)
if (keyuse.elements)
{
DYNAMIC_ARRAY tmp_keyuse;
// TODO: isn't this allocated by update_ref_and_keys
//if (my_init_dynamic_array(save_keyuse, sizeof(KEYUSE), 20, 64))
// return 1;
/* Swap the current and the backup keyuse arrays. */
/* Swap the current and the backup keyuse internal arrays. */
tmp_keyuse= keyuse;
keyuse= save_to->keyuse;
keyuse= save_to->keyuse; /* keyuse is reset to an empty array. */
save_to->keyuse= tmp_keyuse;
for (uint i= 0; i < tables; i++)
......@@ -19785,9 +19782,9 @@ void JOIN::restore_query_plan(Query_plan_state *restore_from)
@param save_to If != NULL, save here the state of the current query plan
@notes
Given a query plan that already optimized taking into account some WHERE clause
'C', reoptimize this plan with a new WHERE clause 'C AND added_where'. The
reoptimization works as follows:
Given a query plan that was already optimized taking into account some WHERE
clause 'C', reoptimize this plan with a new WHERE clause 'C AND added_where'.
The reoptimization works as follows:
1. Call update_ref_and_keys *only* for the new conditions 'added_where'
that are about to be injected into the query.
......@@ -19808,6 +19805,7 @@ JOIN::reoptimize(Item *added_where, table_map join_tables,
{
DYNAMIC_ARRAY added_keyuse;
SARGABLE_PARAM *sargables= 0; /* Used only as a dummy parameter. */
uint org_keyuse_elements;
/* Re-run the REF optimizer to take into account the new conditions. */
if (update_ref_and_keys(thd, &added_keyuse, join_tab, tables, added_where,
......@@ -19826,18 +19824,32 @@ JOIN::reoptimize(Item *added_where, table_map join_tables,
if (save_to)
save_query_plan(save_to);
/* Add the new access methods to the keyuse array. */
if (!keyuse.buffer &&
my_init_dynamic_array(&keyuse, sizeof(KEYUSE), 20, 64))
{
delete_dynamic(&added_keyuse);
return REOPT_ERROR;
}
allocate_dynamic(&keyuse, keyuse.elements + added_keyuse.elements);
org_keyuse_elements= save_to ? save_to->keyuse.elements : keyuse.elements;
allocate_dynamic(&keyuse, org_keyuse_elements + added_keyuse.elements);
/* If needed, add the access methods from the original query plan. */
if (save_to)
{
DBUG_ASSERT(!keyuse.elements);
memcpy(keyuse.buffer,
save_to->keyuse.buffer,
(size_t) save_to->keyuse.elements * keyuse.size_of_element);
keyuse.elements= save_to->keyuse.elements;
}
/* Add the new access methods to the keyuse array. */
memcpy(keyuse.buffer + keyuse.elements * keyuse.size_of_element,
added_keyuse.buffer,
(size_t) added_keyuse.elements * added_keyuse.size_of_element);
keyuse.elements+= added_keyuse.elements;
/* added_keyuse contents is copied, and it is no longer needed. */
delete_dynamic(&added_keyuse);
if (sort_and_filter_keyuse(&keyuse))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment