diff --git a/mysql-test/t/range.test b/mysql-test/t/range.test index 75cbb756998..a1d227459fd 100644 --- a/mysql-test/t/range.test +++ b/mysql-test/t/range.test @@ -323,8 +323,12 @@ insert into t2(id, uid, name) select id, uid, name from t1; select count(*) from t1; select count(*) from t2; +analyze table t1,t2; + explain select * from t1, t2 where t1.uid=t2.uid AND t1.uid > 0; +explain select * from t1, t2 where t1.uid=t2.uid AND t2.uid > 0; explain select * from t1, t2 where t1.uid=t2.uid AND t1.uid != 0; +explain select * from t1, t2 where t1.uid=t2.uid AND t2.uid != 0; select * from t1, t2 where t1.uid=t2.uid AND t1.uid > 0; select * from t1, t2 where t1.uid=t2.uid AND t1.uid != 0; diff --git a/sql/sql_list.h b/sql/sql_list.h index f11951f5c6d..b276c68c16a 100644 --- a/sql/sql_list.h +++ b/sql/sql_list.h @@ -271,8 +271,8 @@ public: inline T* head() {return (T*) base_list::head(); } inline T** head_ref() {return (T**) base_list::head_ref(); } inline T* pop() {return (T*) base_list::pop(); } - inline void concat(List *list) { return base_list::concat(list); } - inline void disjoin(List *list) { return base_list::disjoin(list); } + inline void concat(List *list) { base_list::concat(list); } + inline void disjoin(List *list) { base_list::disjoin(list); } void delete_elements(void) { list_node *element,*next; @@ -283,7 +283,6 @@ public: } empty(); } - inline void concat(List *list) { base_list::concat(list); } }; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 7687a37f8ca..53aed32d0c6 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -77,6 +77,7 @@ static Item *flatten_condition(COND *cond); static COND *build_all_equal_items(COND *cond, COND_EQUAL *inherited); static COND* substitute_for_best_equal_field(COND *cond, + COND_EQUAL *cond_equal, void *table_join_idx); static COND *optimize_cond(COND *conds,Item::cond_result *cond_value); static COND *remove_eq_conds(COND *cond,Item::cond_result *cond_value); @@ -690,7 +691,7 @@ JOIN::optimize() */ if (conds) { - conds= substitute_for_best_equal_field(conds, map2table); + conds= substitute_for_best_equal_field(conds, cond_equal, map2table); conds->update_used_tables(); } { @@ -700,6 +701,7 @@ JOIN::optimize() if (tables->on_expr) { tables->on_expr= substitute_for_best_equal_field(tables->on_expr, + cond_equal, map2table); tables->on_expr->update_used_tables(); map2table[tables->table->tablenr]->on_expr= tables->on_expr; @@ -4703,11 +4705,8 @@ static Item *eliminate_item_equal(COND *cond, COND_EQUAL *cond_equal, Item_field *item= item_field; if (upper) { - if (item_const) - { - if (upper->get_const()) - item= 0; - } + if (item_const && upper->get_const()) + item= 0; else { Item_equal_iterator li(*item_equal); @@ -4745,6 +4744,7 @@ static Item *eliminate_item_equal(COND *cond, COND_EQUAL *cond_equal, SYNOPSIS substitute_for_best_equal_field() cond condition to process + cond_equal multiple equalities to take into consideration table_join_idx index to tables determining field preference DESCRIPTION @@ -4770,6 +4770,7 @@ static Item *eliminate_item_equal(COND *cond, COND_EQUAL *cond_equal, */ static COND* substitute_for_best_equal_field(COND *cond, + COND_EQUAL *cond_equal, void *table_join_idx) { Item_equal *item_equal; @@ -4777,7 +4778,6 @@ static COND* substitute_for_best_equal_field(COND *cond, if (cond->type() == Item::COND_ITEM) { List *cond_list= ((Item_cond*) cond)->argument_list(); - COND_EQUAL *cond_equal= 0; bool and_level= ((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC; @@ -4797,7 +4797,7 @@ static COND* substitute_for_best_equal_field(COND *cond, Item *item; while ((item= li++)) { - Item *new_item =substitute_for_best_equal_field(item, + Item *new_item =substitute_for_best_equal_field(item, cond_equal, table_join_idx); if (new_item != item) li.replace(new_item); @@ -4817,7 +4817,9 @@ static COND* substitute_for_best_equal_field(COND *cond, { item_equal= (Item_equal *) cond; item_equal->sort(table_join_idx); - return eliminate_item_equal(0, 0, item_equal); + if (cond_equal && cond_equal->current_level.head() == item_equal) + cond_equal= 0; + return eliminate_item_equal(0, cond_equal, item_equal); } else cond->walk(&Item::replace_equal_field_processor, 0);