summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorSergey Petrunya <psergey@askmonty.org>2013-11-21 11:21:53 +0400
committerSergey Petrunya <psergey@askmonty.org>2013-11-21 11:21:53 +0400
commit89ea0fc0346504602d5ed0c7b83c2a4db36dc959 (patch)
treeca06df8e1175dc21fc43bc9b58a4c6fc58801424 /sql
parentc7355b19828c37d8efb9f1d4b5010544aa110bd4 (diff)
parentc4defdc8d971cdcc186de549bae9ac4351c7aade (diff)
downloadmariadb-git-89ea0fc0346504602d5ed0c7b83c2a4db36dc959.tar.gz
Merge
Diffstat (limited to 'sql')
-rw-r--r--sql/opt_subselect.cc19
-rw-r--r--sql/sql_select.cc47
2 files changed, 60 insertions, 6 deletions
diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc
index 47771a10ae7..ec56994f16a 100644
--- a/sql/opt_subselect.cc
+++ b/sql/opt_subselect.cc
@@ -1921,11 +1921,25 @@ int pull_out_semijoin_tables(JOIN *join)
}
}
-
table_map pulled_tables= 0;
+ table_map dep_tables= 0;
if (have_join_nest_children)
goto skip;
+ /*
+ Calculate set of tables within this semi-join nest that have
+ other dependent tables
+ */
+ child_li.rewind();
+ while ((tbl= child_li++))
+ {
+ TABLE *const table= tbl->table;
+ if (table &&
+ (table->reginfo.join_tab->dependent &
+ sj_nest->nested_join->used_tables))
+ dep_tables|= table->reginfo.join_tab->dependent;
+ }
+
/* Action #1: Mark the constant tables to be pulled out */
child_li.rewind();
while ((tbl= child_li++))
@@ -1976,7 +1990,8 @@ int pull_out_semijoin_tables(JOIN *join)
child_li.rewind();
while ((tbl= child_li++))
{
- if (tbl->table && !(pulled_tables & tbl->table->map))
+ if (tbl->table && !(pulled_tables & tbl->table->map) &&
+ !(dep_tables & tbl->table->map))
{
if (find_eq_ref_candidate(tbl->table,
sj_nest->nested_join->used_tables &
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index cd81b41d0ec..d7a672b210f 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -241,7 +241,8 @@ static ORDER *create_distinct_group(THD *thd, Item **ref_pointer_array,
List<Item> &all_fields,
bool *all_order_by_fields_used);
static bool test_if_subpart(ORDER *a,ORDER *b);
-static TABLE *get_sort_by_table(ORDER *a,ORDER *b,List<TABLE_LIST> &tables);
+static TABLE *get_sort_by_table(ORDER *a,ORDER *b,List<TABLE_LIST> &tables,
+ table_map const_tables);
static void calc_group_buffer(JOIN *join,ORDER *group);
static bool make_group_fields(JOIN *main_join, JOIN *curr_join);
static bool alloc_group_fields(JOIN *join,ORDER *group);
@@ -1211,7 +1212,8 @@ JOIN::optimize()
goto setup_subq_exit;
}
error= -1; // Error is sent to client
- sort_by_table= get_sort_by_table(order, group_list, select_lex->leaf_tables);
+ /* get_sort_by_table() call used to be here: */
+ MEM_UNDEFINED(&sort_by_table, sizeof(sort_by_table));
/* Calculate how to do the join */
thd_proc_info(thd, "statistics");
@@ -3583,6 +3585,9 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list,
}
} while (join->const_table_map & found_ref && ref_changed);
+ join->sort_by_table= get_sort_by_table(join->order, join->group_list,
+ join->select_lex->leaf_tables,
+ join->const_table_map);
/*
Update info on indexes that can be used for search lookups as
reading const tables may has added new sargable predicates.
@@ -10284,7 +10289,23 @@ make_join_readinfo(JOIN *join, ulonglong options, uint no_jbuf_after)
join->group_list ?
join->join_tab+join->const_tables :
join->get_sort_by_join_tab();
- if (sort_by_tab)
+ /*
+ It could be that sort_by_tab==NULL, and the plan is to use filesort()
+ on the first table.
+ */
+ if (join->order)
+ {
+ join->simple_order= 0;
+ join->need_tmp= 1;
+ }
+
+ if (join->group && !join->group_optimized_away)
+ {
+ join->need_tmp= 1;
+ join->simple_group= 0;
+ }
+
+ if (sort_by_tab)
{
join->need_tmp= 1;
join->simple_order= join->simple_group= 0;
@@ -20714,7 +20735,8 @@ test_if_subpart(ORDER *a,ORDER *b)
*/
static TABLE *
-get_sort_by_table(ORDER *a,ORDER *b, List<TABLE_LIST> &tables)
+get_sort_by_table(ORDER *a,ORDER *b, List<TABLE_LIST> &tables,
+ table_map const_tables)
{
TABLE_LIST *table;
List_iterator<TABLE_LIST> ti(tables);
@@ -20728,6 +20750,23 @@ get_sort_by_table(ORDER *a,ORDER *b, List<TABLE_LIST> &tables)
for (; a && b; a=a->next,b=b->next)
{
+ /* Skip elements of a that are constant */
+ while (!((*a->item)->used_tables() & ~const_tables))
+ {
+ if (!(a= a->next))
+ break;
+ }
+
+ /* Skip elements of b that are constant */
+ while (!((*b->item)->used_tables() & ~const_tables))
+ {
+ if (!(b= b->next))
+ break;
+ }
+
+ if (!a || !b)
+ break;
+
if (!(*a->item)->eq(*b->item,1))
DBUG_RETURN(0);
map|=a->item[0]->used_tables();