1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-30 16:24:05 +03:00

5.3.4 merge

This commit is contained in:
Sergei Golubchik
2012-02-15 18:08:08 +01:00
117 changed files with 4695 additions and 2204 deletions

View File

@ -131,7 +131,8 @@ static COND *build_equal_items(THD *thd, COND *cond,
COND_EQUAL *inherited,
List<TABLE_LIST> *join_list,
COND_EQUAL **cond_equal_ref);
static COND* substitute_for_best_equal_field(COND *cond,
static COND* substitute_for_best_equal_field(JOIN_TAB *context_tab,
COND *cond,
COND_EQUAL *cond_equal,
void *table_join_idx);
static COND *simplify_joins(JOIN *join, List<TABLE_LIST> *join_list,
@ -1254,7 +1255,8 @@ JOIN::optimize()
*/
if (conds)
{
conds= substitute_for_best_equal_field(conds, cond_equal, map2table);
conds= substitute_for_best_equal_field(NO_PARTICULAR_TAB, conds,
cond_equal, map2table);
conds->update_used_tables();
DBUG_EXECUTE("where",
print_where(conds,
@ -1271,7 +1273,8 @@ JOIN::optimize()
{
if (*tab->on_expr_ref)
{
*tab->on_expr_ref= substitute_for_best_equal_field(*tab->on_expr_ref,
*tab->on_expr_ref= substitute_for_best_equal_field(NO_PARTICULAR_TAB,
*tab->on_expr_ref,
tab->cond_equal,
map2table);
(*tab->on_expr_ref)->update_used_tables();
@ -1294,7 +1297,7 @@ JOIN::optimize()
continue;
COND_EQUAL *equals= tab->first_inner ? tab->first_inner->cond_equal :
cond_equal;
ref_item= substitute_for_best_equal_field(ref_item, equals, map2table);
ref_item= substitute_for_best_equal_field(tab, ref_item, equals, map2table);
ref_item->update_used_tables();
if (*ref_item_ptr != ref_item)
{
@ -3596,6 +3599,7 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list,
for (i= 0; i < join->table_count ; i++)
records*= join->best_positions[i].records_read ?
(ha_rows)join->best_positions[i].records_read : 1;
set_if_smaller(records, unit->select_limit_cnt);
join->select_lex->increase_derived_records(records);
}
}
@ -8997,7 +9001,7 @@ void revise_cache_usage(JOIN_TAB *join_tab)
first_inner;
first_inner= first_inner->first_upper)
{
for (tab= end_tab-1; tab >= first_inner; tab--)
for (tab= end_tab; tab >= first_inner; tab--)
set_join_cache_denial(tab);
end_tab= first_inner;
}
@ -9005,7 +9009,7 @@ void revise_cache_usage(JOIN_TAB *join_tab)
else if (join_tab->first_sj_inner_tab)
{
first_inner= join_tab->first_sj_inner_tab;
for (tab= join_tab-1; tab >= first_inner; tab--)
for (tab= join_tab; tab >= first_inner; tab--)
{
set_join_cache_denial(tab);
}
@ -9247,6 +9251,9 @@ uint check_join_cache_usage(JOIN_TAB *tab,
if (tab->use_quick == 2)
goto no_join_cache;
if (tab->table->map & join->complex_firstmatch_tables)
goto no_join_cache;
/*
Don't use join cache if we're inside a join tab range covered by LooseScan
@ -9457,7 +9464,7 @@ void check_join_cache_usage_for_tables(JOIN *join, ulonglong options,
{
tab->used_join_cache_level= join->max_allowed_join_cache_level;
}
uint idx= join->const_tables;
for (tab= first_linear_tab(join, WITHOUT_CONST_TABLES);
tab;
@ -9542,6 +9549,8 @@ make_join_readinfo(JOIN *join, ulonglong options, uint no_jbuf_after)
bool statistics= test(!(join->select_options & SELECT_DESCRIBE));
bool sorted= 1;
join->complex_firstmatch_tables= table_map(0);
if (!join->select_lex->sj_nests.is_empty() &&
setup_semijoin_dups_elimination(join, options, no_jbuf_after))
DBUG_RETURN(TRUE); /* purecov: inspected */
@ -10422,6 +10431,15 @@ remove_const(JOIN *join,ORDER *first_order, COND *cond,
}
/*
Cleanup to avoid interference of calls of this function for
ORDER BY and GROUP BY
*/
for (JOIN_TAB *tab= join->join_tab + join->const_tables;
tab < join->join_tab + join->table_count;
tab++)
tab->cached_eq_ref_table= FALSE;
prev_ptr= &first_order;
*simple_order= *join->join_tab[join->const_tables].on_expr_ref ? 0 : 1;
@ -11582,7 +11600,7 @@ Item *eliminate_item_equal(COND *cond, COND_EQUAL *upper_levels,
else
{
TABLE_LIST *emb_nest;
head= item_equal->get_first(NULL);
head= item_equal->get_first(NO_PARTICULAR_TAB, NULL);
it++;
if ((emb_nest= embedding_sjm(head)))
{
@ -11609,7 +11627,7 @@ Item *eliminate_item_equal(COND *cond, COND_EQUAL *upper_levels,
}
/*
Check if "item_field=head" equality is already guaranteed to be true
Check if "field_item=head" equality is already guaranteed to be true
on upper AND-levels.
*/
if (upper)
@ -11621,7 +11639,8 @@ Item *eliminate_item_equal(COND *cond, COND_EQUAL *upper_levels,
Item_equal_fields_iterator li(*item_equal);
while ((item= li++) != field_item)
{
if (item->find_item_equal(upper_levels) == upper)
if (embedding_sjm(item) == field_sjm &&
item->find_item_equal(upper_levels) == upper)
break;
}
}
@ -11691,6 +11710,7 @@ Item *eliminate_item_equal(COND *cond, COND_EQUAL *upper_levels,
return cond;
}
/**
Substitute every field reference in a condition by the best equal field
and eliminate all multiple equality predicates.
@ -11705,6 +11725,9 @@ Item *eliminate_item_equal(COND *cond, COND_EQUAL *upper_levels,
After this the function retrieves all other conjuncted
predicates substitute every field reference by the field reference
to the first equal field or equal constant if there are any.
@param context_tab Join tab that 'cond' will be attached to, or
NO_PARTICULAR_TAB. See notes above.
@param cond condition to process
@param cond_equal multiple equalities to take into consideration
@param table_join_idx index to tables determining field preference
@ -11715,11 +11738,37 @@ Item *eliminate_item_equal(COND *cond, COND_EQUAL *upper_levels,
new fields in multiple equality item of lower levels. We want
the order in them to comply with the order of upper levels.
context_tab may be used to specify which join tab `cond` will be
attached to. There are two possible cases:
1. context_tab != NO_PARTICULAR_TAB
We're doing substitution for an Item which will be evaluated in the
context of a particular item. For example, if the optimizer does a
ref access on "tbl1.key= expr" then
= equality substitution will be perfomed on 'expr'
= it is known in advance that 'expr' will be evaluated when
table t1 is accessed.
Note that in this kind of substution we never have to replace Item_equal
objects. For example, for
t.key= func(col1=col2 AND col2=const)
we will not build Item_equal or do equality substution (if we decide to,
this function will need to be fixed to handle it)
2. context_tab == NO_PARTICULAR_TAB
We're doing substitution in WHERE/ON condition, which is not yet
attached to any particular join_tab. We will use information about the
chosen join order to make "optimal" substitions, i.e. those that allow
to apply filtering as soon as possible. See eliminate_item_equal() and
Item_equal::get_first() for details.
@return
The transformed condition
*/
static COND* substitute_for_best_equal_field(COND *cond,
static COND* substitute_for_best_equal_field(JOIN_TAB *context_tab,
COND *cond,
COND_EQUAL *cond_equal,
void *table_join_idx)
{
@ -11735,7 +11784,7 @@ static COND* substitute_for_best_equal_field(COND *cond,
if (and_level)
{
cond_equal= &((Item_cond_and *) cond)->cond_equal;
cond_list->disjoin((List<Item> *) &cond_equal->current_level);
cond_list->disjoin((List<Item> *) &cond_equal->current_level);/* remove Item_equal objects from the AND. */
List_iterator_fast<Item_equal> it(cond_equal->current_level);
while ((item_equal= it++))
@ -11748,7 +11797,8 @@ static COND* substitute_for_best_equal_field(COND *cond,
Item *item;
while ((item= li++))
{
Item *new_item= substitute_for_best_equal_field(item, cond_equal,
Item *new_item= substitute_for_best_equal_field(context_tab,
item, cond_equal,
table_join_idx);
/*
This works OK with PS/SP re-execution as changes are made to
@ -11795,7 +11845,8 @@ static COND* substitute_for_best_equal_field(COND *cond,
List_iterator_fast<Item_equal> it(cond_equal->current_level);
while((item_equal= it++))
{
cond= cond->transform(&Item::replace_equal_field, (uchar *) item_equal);
REPLACE_EQUAL_FIELD_ARG arg= {item_equal, context_tab};
cond= cond->transform(&Item::replace_equal_field, (uchar *) &arg);
}
cond_equal= cond_equal->upper_levels;
}
@ -15589,7 +15640,7 @@ sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records)
if (join_tab->loosescan_match_tab &&
join_tab->loosescan_match_tab->found_match)
{
KEY *key= join_tab->table->key_info + join_tab->index;
KEY *key= join_tab->table->key_info + join_tab->loosescan_key;
key_copy(join_tab->loosescan_buf, join_tab->table->record[0], key,
join_tab->loosescan_key_len);
skip_over= TRUE;
@ -15599,7 +15650,7 @@ sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records)
if (skip_over && !error)
{
if(!key_cmp(join_tab->table->key_info[join_tab->index].key_part,
if(!key_cmp(join_tab->table->key_info[join_tab->loosescan_key].key_part,
join_tab->loosescan_buf, join_tab->loosescan_key_len))
{
/*
@ -18395,7 +18446,6 @@ create_sort_index(THD *thd, JOIN *join, ORDER *order,
table->sort.io_cache= NULL;
select->cleanup(); // filesort did select
tab->select= 0;
table->quick_keys.clear_all(); // as far as we cleanup select->quick
table->intersect_keys.clear_all();
table->sort.io_cache= tablesort_result_cache;