summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/opt_subselect.cc10
-rw-r--r--sql/sql_select.cc32
2 files changed, 28 insertions, 14 deletions
diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc
index bdf5175fc8b..ae0c1e4f0a5 100644
--- a/sql/opt_subselect.cc
+++ b/sql/opt_subselect.cc
@@ -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);
/*
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index e1dfb4a3519..2e460c3d64a 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -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))