summaryrefslogtreecommitdiff
path: root/sql/sql_select.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sql_select.cc')
-rw-r--r--sql/sql_select.cc40
1 files changed, 31 insertions, 9 deletions
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 9a085ec6314..4c02f19926f 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -1295,9 +1295,20 @@ JOIN::optimize()
Item *ref_item= *ref_item_ptr;
if (!ref_item->used_tables() && !(select_options & SELECT_DESCRIBE))
continue;
- COND_EQUAL *equals= tab->first_inner ? tab->first_inner->cond_equal :
- cond_equal;
- ref_item= substitute_for_best_equal_field(tab, ref_item, equals, map2table);
+ COND_EQUAL *equals= cond_equal;
+ JOIN_TAB *first_inner= tab->first_inner;
+ while (equals)
+ {
+ ref_item= substitute_for_best_equal_field(tab, ref_item,
+ equals, map2table);
+ if (first_inner)
+ {
+ equals= first_inner->cond_equal;
+ first_inner= first_inner->first_upper;
+ }
+ else
+ equals= 0;
+ }
ref_item->update_used_tables();
if (*ref_item_ptr != ref_item)
{
@@ -9311,7 +9322,7 @@ uint check_join_cache_usage(JOIN_TAB *tab,
Check whether table tab and the previous one belong to the same nest of
inner tables and if so do not use join buffer when joining table tab.
*/
- if (tab->first_inner)
+ if (tab->first_inner && tab != tab->first_inner)
{
for (JOIN_TAB *first_inner= tab[-1].first_inner;
first_inner;
@@ -9321,7 +9332,7 @@ uint check_join_cache_usage(JOIN_TAB *tab,
goto no_join_cache;
}
}
- else if (tab->first_sj_inner_tab &&
+ else if (tab->first_sj_inner_tab && tab != tab->first_sj_inner_tab &&
tab->first_sj_inner_tab == tab[-1].first_sj_inner_tab)
goto no_join_cache;
}
@@ -10569,10 +10580,22 @@ return_zero_rows(JOIN *join, select_result *result, List<TABLE_LIST> &tables,
if (send_row)
{
+ /*
+ Set all tables to have NULL row. This is needed as we will be evaluating
+ HAVING condition.
+ */
List_iterator<TABLE_LIST> ti(tables);
TABLE_LIST *table;
while ((table= ti++))
- mark_as_null_row(table->table); // All fields are NULL
+ {
+ /*
+ Don't touch semi-join materialization tables, as the above join_free()
+ call has freed them (and HAVING clause can't have references to them
+ anyway).
+ */
+ if (!table->is_jtbm())
+ mark_as_null_row(table->table); // All fields are NULL
+ }
if (having &&
!having->walk(&Item::clear_sum_processor, FALSE, NULL) &&
having->val_int() == 0)
@@ -12819,9 +12842,8 @@ optimize_cond(JOIN *join, COND *conds, List<TABLE_LIST> *join_list,
multiple equality contains a constant.
*/
DBUG_EXECUTE("where", print_where(conds, "original", QT_ORDINARY););
- conds= build_equal_items(join->thd, conds, NULL, join_list,
- &join->cond_equal);
- DBUG_EXECUTE("where",print_where(conds,"after equal_items", QT_ORDINARY););
+ conds= build_equal_items(join->thd, conds, NULL, join_list, cond_equal);
+ DBUG_EXECUTE("where",print_where(conds,"after equal_items", QT_ORDINARY););
/* change field = field to field = const for each found field = const */
propagate_cond_constants(thd, (I_List<COND_CMP> *) 0, conds, conds);