summaryrefslogtreecommitdiff
path: root/sql/sql_select.cc
diff options
context:
space:
mode:
authorMikael Ronstrom <mikael@mysql.com>2009-06-11 12:07:59 +0200
committerMikael Ronstrom <mikael@mysql.com>2009-06-11 12:07:59 +0200
commita22c8c5be5ceadd23eed707ae2f1308ced2de977 (patch)
tree796cc97d1d103e18e0672d9b57dee4c54857073c /sql/sql_select.cc
parent510835a0727fc1ebe98e2808cae91c8ab014d27e (diff)
parent585cf08fe6a8d6e237732daa94a969f93e5c84ec (diff)
downloadmariadb-git-a22c8c5be5ceadd23eed707ae2f1308ced2de977.tar.gz
Merge MySQL 5.1.35 into MySQL 5.4
Diffstat (limited to 'sql/sql_select.cc')
-rw-r--r--sql/sql_select.cc99
1 files changed, 67 insertions, 32 deletions
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 9dd72ab55ba..b6cf3848eee 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -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;