diff options
Diffstat (limited to 'sql/sql_select.cc')
-rw-r--r-- | sql/sql_select.cc | 24 |
1 files changed, 21 insertions, 3 deletions
diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 3c3d3a62ef5..5f52ef9f856 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1644,6 +1644,11 @@ JOIN::reinit() if (join_tab_save) memcpy(join_tab, join_tab_save, sizeof(JOIN_TAB) * tables); + /* need to reset ref access state (see join_read_key) */ + if (join_tab) + for (uint i= 0; i < tables; i++) + join_tab[i].ref.key_err= TRUE; + if (tmp_join) restore_tmp(); @@ -5971,6 +5976,7 @@ inline void add_cond_and_fix(Item **e1, Item *e2) { *e1= res; res->quick_fix_field(); + res->update_used_tables(); } } else @@ -7229,7 +7235,19 @@ remove_const(JOIN *join,ORDER *first_order, COND *cond, for (order=first_order; order ; order=order->next) { table_map order_tables=order->item[0]->used_tables(); - if (order->item[0]->with_sum_func) + if (order->item[0]->with_sum_func || + /* + If the outer table of an outer join is const (either by itself or + after applying WHERE condition), grouping on a field from such a + table will be optimized away and filesort without temporary table + will be used unless we prevent that now. Filesort is not fit to + handle joins and the join condition is not applied. We can't detect + the case without an expensive test, however, so we force temporary + table for all queries containing more than one table, ROLLUP, and an + outer join. + */ + (join->tables > 1 && join->rollup.state == ROLLUP::STATE_INITED && + join->outer_join)) *simple_order=0; // Must do a temp table to sort else if (!(order_tables & not_const_tables)) { @@ -7637,7 +7655,7 @@ static bool check_simple_equality(Item *left_item, Item *right_item, already contains a constant and its value is not equal to the value of const_item. */ - item_equal->add(const_item); + item_equal->add(const_item, field_item); } else { @@ -13655,7 +13673,7 @@ check_reverse_order: select->quick=tmp; } } - else if (tab->type != JT_NEXT && + else if (tab->type != JT_NEXT && tab->type != JT_REF_OR_NULL && tab->ref.key >= 0 && tab->ref.key_parts <= used_key_parts) { /* |