summaryrefslogtreecommitdiff
path: root/sql/sql_select.cc
diff options
context:
space:
mode:
authorIgor Babaev <igor@askmonty.org>2010-10-06 13:27:12 -0700
committerIgor Babaev <igor@askmonty.org>2010-10-06 13:27:12 -0700
commitd64ce287e344094fa4dec70d86b1392901a80b51 (patch)
tree5e25d464f11921aaf51073cdf80ed4fb8a174dfe /sql/sql_select.cc
parenteecf033d81be2e5f059069dd7e68468ebb6f3ec4 (diff)
downloadmariadb-git-d64ce287e344094fa4dec70d86b1392901a80b51.tar.gz
Ported the fix for bug #57024 (a performance issue for outer joins).
Employed the same kind of optimization as in the fix for the cases when join buffer is used. The optimization performs early evaluation of the conditions from on expression with table references to only outer tables of an outer join.
Diffstat (limited to 'sql/sql_select.cc')
-rwxr-xr-xsql/sql_select.cc39
1 files changed, 23 insertions, 16 deletions
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 7aab9591960..c2381204a82 100755
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -7090,9 +7090,13 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
used_tables2|= current_map;
COND *tmp_cond= make_cond_for_table(on_expr, used_tables2,
current_map, FALSE);
+ add_cond_and_fix(&tmp_cond, tab->on_precond);
if (tmp_cond)
{
JOIN_TAB *cond_tab= tab < first_inner_tab ? first_inner_tab : tab;
+ Item **sel_cond_ref= tab < first_inner_tab ?
+ &first_inner_tab->on_precond :
+ &tab->select_cond;
/*
First add the guards for match variables of
all embedding outer join operations.
@@ -7115,15 +7119,15 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
tmp_cond->quick_fix_field();
/* Add the predicate to other pushed down predicates */
DBUG_PRINT("info", ("Item_cond_and"));
- cond_tab->select_cond= !cond_tab->select_cond ? tmp_cond :
- new Item_cond_and(cond_tab->select_cond,
- tmp_cond);
+ *sel_cond_ref= !(*sel_cond_ref) ?
+ tmp_cond :
+ new Item_cond_and(*sel_cond_ref, tmp_cond);
DBUG_PRINT("info", ("Item_cond_and 0x%lx",
- (ulong)cond_tab->select_cond));
- if (!cond_tab->select_cond)
- DBUG_RETURN(1);
- cond_tab->select_cond->update_used_tables();
- cond_tab->select_cond->quick_fix_field();
+ (ulong)(*sel_cond_ref)));
+ if (!(*sel_cond_ref))
+ DBUG_RETURN(1);
+ (*sel_cond_ref)->quick_fix_field();
+ (*sel_cond_ref)->update_used_tables();
if (cond_tab->select)
cond_tab->select->cond= cond_tab->select_cond;
}
@@ -13246,7 +13250,7 @@ sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records)
DBUG_RETURN(nls);
}
int error;
- enum_nested_loop_state rc;
+ enum_nested_loop_state rc= NESTED_LOOP_OK;
READ_RECORD *info= &join_tab->read_record;
if (join_tab->flush_weedout_table)
@@ -13279,18 +13283,21 @@ sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records)
/* Set first_unmatched for the last inner table of this group */
join_tab->last_inner->first_unmatched= join_tab;
- }
+ if (join_tab->on_precond && !join_tab->on_precond->val_int())
+ rc= NESTED_LOOP_NO_MORE_ROWS;
+ }
join->thd->row_count= 0;
if (join_tab->loosescan_match_tab)
join_tab->loosescan_match_tab->found_match= FALSE;
- error= (*join_tab->read_first_record)(join_tab);
-
- if (join_tab->keep_current_rowid)
- join_tab->table->file->position(join_tab->table->record[0]);
-
- rc= evaluate_join_record(join, join_tab, error);
+ if (rc != NESTED_LOOP_NO_MORE_ROWS)
+ {
+ error= (*join_tab->read_first_record)(join_tab);
+ if (join_tab->keep_current_rowid)
+ join_tab->table->file->position(join_tab->table->record[0]);
+ rc= evaluate_join_record(join, join_tab, error);
+ }
}
/*