summaryrefslogtreecommitdiff
path: root/sql/opt_split.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/opt_split.cc')
-rw-r--r--sql/opt_split.cc71
1 files changed, 57 insertions, 14 deletions
diff --git a/sql/opt_split.cc b/sql/opt_split.cc
index d272638f00c..a356335855c 100644
--- a/sql/opt_split.cc
+++ b/sql/opt_split.cc
@@ -310,6 +310,8 @@ struct SplM_field_ext_info: public SplM_field_info
occurred also in the select list of this join
9. There are defined some keys usable for ref access of fields from C
with available statistics.
+ 10. The select doesn't use WITH ROLLUP (This limitation can probably be
+ lifted)
@retval
true if the answer is positive
@@ -326,7 +328,8 @@ bool JOIN::check_for_splittable_materialized()
(unit->first_select()->next_select()) || // !(3)
(derived->prohibit_cond_pushdown) || // !(4)
(derived->is_recursive_with_table()) || // !(5)
- (table_count == 0 || const_tables == top_join_tab_count)) // !(6)
+ (table_count == 0 || const_tables == top_join_tab_count) || // !(6)
+ rollup.state != ROLLUP::STATE_NONE) // (10)
return false;
if (group_list) // (7.1)
{
@@ -1045,16 +1048,16 @@ SplM_plan_info * JOIN_TAB::choose_best_splitting(double record_count,
Inject equalities for splitting used by the materialization join
@param
- remaining_tables used to filter out the equalities that cannot
+ excluded_tables used to filter out the equalities that cannot
be pushed.
@details
- This function is called by JOIN_TAB::fix_splitting that is used
- to fix the chosen splitting of a splittable materialized table T
- in the final query execution plan. In this plan the table T
- is joined just before the 'remaining_tables'. So all equalities
- usable for splitting whose right parts do not depend on any of
- remaining tables can be pushed into join for T.
+ This function injects equalities pushed into a derived table T for which
+ the split optimization has been chosen by the optimizer. The function
+ is called by JOIN::inject_splitting_cond_for_all_tables_with_split_op().
+ All equalities usable for splitting T whose right parts do not depend on
+ any of the 'excluded_tables' can be pushed into the where clause of the
+ derived table T.
The function also marks the select that specifies T as
UNCACHEABLE_DEPENDENT_INJECTED.
@@ -1063,7 +1066,7 @@ SplM_plan_info * JOIN_TAB::choose_best_splitting(double record_count,
true on failure
*/
-bool JOIN::inject_best_splitting_cond(table_map remaining_tables)
+bool JOIN::inject_best_splitting_cond(table_map excluded_tables)
{
Item *inj_cond= 0;
List<Item> *inj_cond_list= &spl_opt_info->inj_cond_list;
@@ -1071,7 +1074,7 @@ bool JOIN::inject_best_splitting_cond(table_map remaining_tables)
KEY_FIELD *added_key_field;
while ((added_key_field= li++))
{
- if (remaining_tables & added_key_field->val->used_tables())
+ if (excluded_tables & added_key_field->val->used_tables())
continue;
if (inj_cond_list->push_back(added_key_field->cond, thd->mem_root))
return true;
@@ -1088,7 +1091,7 @@ bool JOIN::inject_best_splitting_cond(table_map remaining_tables)
if (inj_cond)
inj_cond->fix_fields(thd,0);
- if (inject_cond_into_where(inj_cond))
+ if (inject_cond_into_where(inj_cond->copy_andor_structure(thd)))
return true;
select_lex->uncacheable|= UNCACHEABLE_DEPENDENT_INJECTED;
@@ -1165,8 +1168,6 @@ bool JOIN_TAB::fix_splitting(SplM_plan_info *spl_plan,
memcpy((char *) md_join->best_positions,
(char *) spl_plan->best_positions,
sizeof(POSITION) * md_join->table_count);
- if (md_join->inject_best_splitting_cond(remaining_tables))
- return true;
/*
This is called for a proper work of JOIN::get_best_combination()
called for the join that materializes T
@@ -1210,7 +1211,8 @@ bool JOIN::fix_all_splittings_in_plan()
if (tab->table->is_splittable())
{
SplM_plan_info *spl_plan= cur_pos->spl_plan;
- if (tab->fix_splitting(spl_plan, all_tables & ~prev_tables,
+ if (tab->fix_splitting(spl_plan,
+ all_tables & ~prev_tables,
tablenr < const_tables ))
return true;
}
@@ -1218,3 +1220,44 @@ bool JOIN::fix_all_splittings_in_plan()
}
return false;
}
+
+
+/**
+ @brief
+ Inject splitting conditions into WHERE of split derived
+
+ @details
+ The function calls JOIN_TAB::inject_best_splitting_cond() for each
+ materialized derived table T used in this join for which the split
+ optimization has been chosen by the optimizer. It is done in order to
+ inject equalities pushed into the where clause of the specification
+ of T that would be helpful to employ the splitting technique.
+
+ @retval
+ false on success
+ true on failure
+*/
+
+bool JOIN::inject_splitting_cond_for_all_tables_with_split_opt()
+{
+ table_map prev_tables= 0;
+ table_map all_tables= (table_map(1) << table_count) - 1;
+ for (uint tablenr= 0; tablenr < table_count; tablenr++)
+ {
+ POSITION *cur_pos= &best_positions[tablenr];
+ JOIN_TAB *tab= cur_pos->table;
+ prev_tables|= tab->table->map;
+ if (!(tab->table->is_splittable() && cur_pos->spl_plan))
+ continue;
+ SplM_opt_info *spl_opt_info= tab->table->spl_opt_info;
+ JOIN *join= spl_opt_info->join;
+ /*
+ Currently the equalities referencing columns of SJM tables with
+ look-up access cannot be pushed into materialized derived.
+ */
+ if (join->inject_best_splitting_cond((all_tables & ~prev_tables) |
+ sjm_lookup_tables))
+ return true;
+ }
+ return false;
+}