mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
Merge MySQL 5.1.35 into MySQL 5.4
This commit is contained in:
@ -2463,11 +2463,12 @@ typedef struct st_sargable_param
|
||||
*/
|
||||
|
||||
static bool
|
||||
make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
|
||||
make_join_statistics(JOIN *join, TABLE_LIST *tables_arg, COND *conds,
|
||||
DYNAMIC_ARRAY *keyuse_array)
|
||||
{
|
||||
int error;
|
||||
TABLE *table;
|
||||
TABLE_LIST *tables= tables_arg;
|
||||
uint i,table_count,const_count,key;
|
||||
table_map found_const_table_map, all_table_map, found_ref, refs;
|
||||
key_map const_ref, eq_part;
|
||||
@ -2505,10 +2506,10 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
|
||||
table_vector[i]=s->table=table=tables->table;
|
||||
table->pos_in_table_list= tables;
|
||||
error= table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
|
||||
if(error)
|
||||
if (error)
|
||||
{
|
||||
table->file->print_error(error, MYF(0));
|
||||
DBUG_RETURN(1);
|
||||
table->file->print_error(error, MYF(0));
|
||||
goto error;
|
||||
}
|
||||
table->quick_keys.clear_all();
|
||||
table->reginfo.join_tab=s;
|
||||
@ -2604,7 +2605,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
|
||||
{
|
||||
join->tables=0; // Don't use join->table
|
||||
my_message(ER_WRONG_OUTER_JOIN, ER(ER_WRONG_OUTER_JOIN), MYF(0));
|
||||
DBUG_RETURN(1);
|
||||
goto error;
|
||||
}
|
||||
s->key_dependent= s->dependent;
|
||||
}
|
||||
@ -2614,7 +2615,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
|
||||
if (update_ref_and_keys(join->thd, keyuse_array, stat, join->tables,
|
||||
conds, join->cond_equal,
|
||||
~outer_join, join->select_lex, &sargables))
|
||||
DBUG_RETURN(1);
|
||||
goto error;
|
||||
|
||||
/* Read tables with 0 or 1 rows (system tables) */
|
||||
join->const_table_map= 0;
|
||||
@ -2630,7 +2631,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
|
||||
if ((tmp=join_read_const_table(s, p_pos)))
|
||||
{
|
||||
if (tmp > 0)
|
||||
DBUG_RETURN(1); // Fatal error
|
||||
goto error; // Fatal error
|
||||
}
|
||||
else
|
||||
found_const_table_map|= s->table->map;
|
||||
@ -2702,7 +2703,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
|
||||
if ((tmp= join_read_const_table(s, join->positions+const_count-1)))
|
||||
{
|
||||
if (tmp > 0)
|
||||
DBUG_RETURN(1); // Fatal error
|
||||
goto error; // Fatal error
|
||||
}
|
||||
else
|
||||
found_const_table_map|= table->map;
|
||||
@ -2751,12 +2752,12 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
|
||||
set_position(join,const_count++,s,start_keyuse);
|
||||
if (create_ref_for_key(join, s, start_keyuse,
|
||||
found_const_table_map))
|
||||
DBUG_RETURN(1);
|
||||
goto error;
|
||||
if ((tmp=join_read_const_table(s,
|
||||
join->positions+const_count-1)))
|
||||
{
|
||||
if (tmp > 0)
|
||||
DBUG_RETURN(1); // Fatal error
|
||||
goto error; // Fatal error
|
||||
}
|
||||
else
|
||||
found_const_table_map|= table->map;
|
||||
@ -2833,7 +2834,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
|
||||
*s->on_expr_ref ? *s->on_expr_ref : conds,
|
||||
1, &error);
|
||||
if (!select)
|
||||
DBUG_RETURN(1);
|
||||
goto error;
|
||||
records= get_quick_record_count(join->thd, select, s->table,
|
||||
&s->const_keys, join->row_limit);
|
||||
s->quick=select->quick;
|
||||
@ -2879,7 +2880,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
|
||||
{
|
||||
optimize_keyuse(join, keyuse_array);
|
||||
if (choose_plan(join, all_table_map & ~join->const_table_map))
|
||||
DBUG_RETURN(TRUE);
|
||||
goto error;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2889,6 +2890,17 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
|
||||
}
|
||||
/* Generate an execution plan from the found optimal join order. */
|
||||
DBUG_RETURN(join->thd->killed || get_best_combination(join));
|
||||
|
||||
error:
|
||||
/*
|
||||
Need to clean up join_tab from TABLEs in case of error.
|
||||
They won't get cleaned up by JOIN::cleanup() because JOIN::join_tab
|
||||
may not be assigned yet by this function (which is building join_tab).
|
||||
Dangling TABLE::reginfo.join_tab may cause part_of_refkey to choke.
|
||||
*/
|
||||
for (tables= tables_arg; tables; tables= tables->next_leaf)
|
||||
tables->table->reginfo.join_tab= NULL;
|
||||
DBUG_RETURN (1);
|
||||
}
|
||||
|
||||
|
||||
@ -3467,14 +3479,6 @@ add_key_fields(JOIN *join, KEY_FIELD **key_fields, uint *and_level,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Add all keys with uses 'field' for some keypart.
|
||||
|
||||
If field->and_level != and_level then only mark key_part as const_part.
|
||||
|
||||
@todo
|
||||
ft-keys in non-ft queries. SerG
|
||||
*/
|
||||
|
||||
static uint
|
||||
max_part_bit(key_part_map bits)
|
||||
@ -3484,7 +3488,16 @@ max_part_bit(key_part_map bits)
|
||||
return found;
|
||||
}
|
||||
|
||||
static void
|
||||
/*
|
||||
Add all keys with uses 'field' for some keypart
|
||||
If field->and_level != and_level then only mark key_part as const_part
|
||||
|
||||
RETURN
|
||||
0 - OK
|
||||
1 - Out of memory.
|
||||
*/
|
||||
|
||||
static bool
|
||||
add_key_part(DYNAMIC_ARRAY *keyuse_array,KEY_FIELD *key_field)
|
||||
{
|
||||
Field *field=key_field->field;
|
||||
@ -3514,24 +3527,26 @@ add_key_part(DYNAMIC_ARRAY *keyuse_array,KEY_FIELD *key_field)
|
||||
keyuse.optimize= key_field->optimize & KEY_OPTIMIZE_REF_OR_NULL;
|
||||
keyuse.null_rejecting= key_field->null_rejecting;
|
||||
keyuse.cond_guard= key_field->cond_guard;
|
||||
VOID(insert_dynamic(keyuse_array,(uchar*) &keyuse));
|
||||
if (insert_dynamic(keyuse_array,(uchar*) &keyuse))
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
#define FT_KEYPART (MAX_REF_PARTS+10)
|
||||
|
||||
static void
|
||||
static bool
|
||||
add_ft_keys(DYNAMIC_ARRAY *keyuse_array,
|
||||
JOIN_TAB *stat,COND *cond,table_map usable_tables)
|
||||
{
|
||||
Item_func_match *cond_func=NULL;
|
||||
|
||||
if (!cond)
|
||||
return;
|
||||
return FALSE;
|
||||
|
||||
if (cond->type() == Item::FUNC_ITEM)
|
||||
{
|
||||
@ -3565,13 +3580,16 @@ add_ft_keys(DYNAMIC_ARRAY *keyuse_array,
|
||||
{
|
||||
Item *item;
|
||||
while ((item=li++))
|
||||
add_ft_keys(keyuse_array,stat,item,usable_tables);
|
||||
{
|
||||
if (add_ft_keys(keyuse_array,stat,item,usable_tables))
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!cond_func || cond_func->key == NO_SUCH_KEY ||
|
||||
!(usable_tables & cond_func->table->map))
|
||||
return;
|
||||
return FALSE;
|
||||
|
||||
KEYUSE keyuse;
|
||||
keyuse.table= cond_func->table;
|
||||
@ -3581,7 +3599,7 @@ add_ft_keys(DYNAMIC_ARRAY *keyuse_array,
|
||||
keyuse.used_tables=cond_func->key_item()->used_tables();
|
||||
keyuse.optimize= 0;
|
||||
keyuse.keypart_map= 0;
|
||||
VOID(insert_dynamic(keyuse_array,(uchar*) &keyuse));
|
||||
return insert_dynamic(keyuse_array,(uchar*) &keyuse);
|
||||
}
|
||||
|
||||
|
||||
@ -3735,7 +3753,8 @@ update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab,
|
||||
sargables);
|
||||
for (; field != end ; field++)
|
||||
{
|
||||
add_key_part(keyuse,field);
|
||||
if (add_key_part(keyuse,field))
|
||||
return TRUE;
|
||||
/* Mark that we can optimize LEFT JOIN */
|
||||
if (field->val->type() == Item::NULL_ITEM &&
|
||||
!field->field->real_maybe_null())
|
||||
@ -3773,11 +3792,15 @@ update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab,
|
||||
|
||||
/* fill keyuse with found key parts */
|
||||
for ( ; field != end ; field++)
|
||||
add_key_part(keyuse,field);
|
||||
{
|
||||
if (add_key_part(keyuse,field))
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (select_lex->ftfunc_list->elements)
|
||||
{
|
||||
add_ft_keys(keyuse,join_tab,cond,normal_tables);
|
||||
if (add_ft_keys(keyuse,join_tab,cond,normal_tables))
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -3798,7 +3821,8 @@ update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab,
|
||||
(qsort_cmp) sort_keyuse);
|
||||
|
||||
bzero((char*) &key_end,sizeof(key_end)); /* Add for easy testing */
|
||||
VOID(insert_dynamic(keyuse,(uchar*) &key_end));
|
||||
if (insert_dynamic(keyuse,(uchar*) &key_end))
|
||||
return TRUE;
|
||||
|
||||
use=save_pos=dynamic_element(keyuse,0,KEYUSE*);
|
||||
prev= &key_end;
|
||||
@ -7616,7 +7640,7 @@ static COND *build_equal_items_for_cond(THD *thd, COND *cond,
|
||||
if (and_level)
|
||||
{
|
||||
/*
|
||||
Retrieve all conjucts of this level detecting the equality
|
||||
Retrieve all conjuncts of this level detecting the equality
|
||||
that are subject to substitution by multiple equality items and
|
||||
removing each such predicate from the conjunction after having
|
||||
found/created a multiple equality whose inference the predicate is.
|
||||
@ -7632,6 +7656,15 @@ static COND *build_equal_items_for_cond(THD *thd, COND *cond,
|
||||
li.remove();
|
||||
}
|
||||
|
||||
/*
|
||||
Check if we eliminated all the predicates of the level, e.g.
|
||||
(a=a AND b=b AND a=a).
|
||||
*/
|
||||
if (!args->elements &&
|
||||
!cond_equal.current_level.elements &&
|
||||
!eq_list.elements)
|
||||
return new Item_int((longlong) 1, 1);
|
||||
|
||||
List_iterator_fast<Item_equal> it(cond_equal.current_level);
|
||||
while ((item_equal= it++))
|
||||
{
|
||||
@ -9779,6 +9812,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
|
||||
table->in_use= thd;
|
||||
table->quick_keys.init();
|
||||
table->covering_keys.init();
|
||||
table->merge_keys.init();
|
||||
table->keys_in_use_for_query.init();
|
||||
|
||||
table->s= share;
|
||||
@ -13447,6 +13481,7 @@ create_sort_index(THD *thd, JOIN *join, ORDER *order,
|
||||
{
|
||||
select->cleanup(); // filesort did select
|
||||
tab->select= 0;
|
||||
table->quick_keys.clear_all(); // as far as we cleanup select->quick
|
||||
}
|
||||
tab->select_cond=0;
|
||||
tab->last_inner= 0;
|
||||
|
Reference in New Issue
Block a user