diff options
author | Mikael Ronstrom <mikael@mysql.com> | 2009-06-11 12:07:59 +0200 |
---|---|---|
committer | Mikael Ronstrom <mikael@mysql.com> | 2009-06-11 12:07:59 +0200 |
commit | a22c8c5be5ceadd23eed707ae2f1308ced2de977 (patch) | |
tree | 796cc97d1d103e18e0672d9b57dee4c54857073c /sql/sql_select.cc | |
parent | 510835a0727fc1ebe98e2808cae91c8ab014d27e (diff) | |
parent | 585cf08fe6a8d6e237732daa94a969f93e5c84ec (diff) | |
download | mariadb-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.cc | 99 |
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; |