Commit 656c284d authored by Sergey Petrunya's avatar Sergey Petrunya

BUG#913030: better comments and function names.

parent d734a13d
...@@ -5635,6 +5635,15 @@ best_access_path(JOIN *join, ...@@ -5635,6 +5635,15 @@ best_access_path(JOIN *join,
} }
/*
Find JOIN_TAB's embedding (i.e, parent) subquery.
- For merged semi-joins, tables inside the semi-join nest have their
semi-join nest as parent. We intentionally ignore results of table
pullout action here.
- For non-merged semi-joins (JTBM tabs), the embedding subquery is the
JTBM join tab itself.
*/
static TABLE_LIST* get_emb_subq(JOIN_TAB *tab) static TABLE_LIST* get_emb_subq(JOIN_TAB *tab)
{ {
TABLE_LIST *tlist= tab->table->pos_in_table_list; TABLE_LIST *tlist= tab->table->pos_in_table_list;
...@@ -5648,8 +5657,21 @@ static TABLE_LIST* get_emb_subq(JOIN_TAB *tab) ...@@ -5648,8 +5657,21 @@ static TABLE_LIST* get_emb_subq(JOIN_TAB *tab)
/* /*
Choose initial table order that "helps" semi-join optimizations.
The idea is that we should start with the order that is the same as the one
we would have had if we had semijoin=off:
- Top-level tables go first
- subquery tables are grouped together by the subquery they are in,
- subquery tables are attached where the subquery predicate would have been
attached if we had semi-join off.
This function relies on join_tab_cmp()/join_tab_cmp_straight() to produce
certain pre-liminary ordering, see compare_embedding_subqueries() for its
description.
*/ */
static void pre_sort_tables(JOIN *join)
static void choose_initial_table_order(JOIN *join)
{ {
TABLE_LIST *emb_subq; TABLE_LIST *emb_subq;
JOIN_TAB **tab= join->best_ref + join->const_tables; JOIN_TAB **tab= join->best_ref + join->const_tables;
...@@ -5660,10 +5682,12 @@ static void pre_sort_tables(JOIN *join) ...@@ -5660,10 +5682,12 @@ static void pre_sort_tables(JOIN *join)
if ((emb_subq= get_emb_subq(*tab))) if ((emb_subq= get_emb_subq(*tab)))
break; break;
} }
/* Copy the subquery JOIN_TABs to a separate array */
uint n_subquery_tabs= tabs_end - tab; uint n_subquery_tabs= tabs_end - tab;
if (!n_subquery_tabs) if (!n_subquery_tabs)
return; return;
/* Copy the subquery JOIN_TABs to a separate array */
JOIN_TAB *subquery_tabs[MAX_TABLES]; JOIN_TAB *subquery_tabs[MAX_TABLES];
memcpy(subquery_tabs, tab, sizeof(JOIN_TAB*) * n_subquery_tabs); memcpy(subquery_tabs, tab, sizeof(JOIN_TAB*) * n_subquery_tabs);
...@@ -5787,7 +5811,7 @@ choose_plan(JOIN *join, table_map join_tables) ...@@ -5787,7 +5811,7 @@ choose_plan(JOIN *join, table_map join_tables)
if (!join->emb_sjm_nest) if (!join->emb_sjm_nest)
{ {
pre_sort_tables(join); choose_initial_table_order(join);
} }
join->cur_sj_inner_tables= 0; join->cur_sj_inner_tables= 0;
...@@ -5828,6 +5852,18 @@ choose_plan(JOIN *join, table_map join_tables) ...@@ -5828,6 +5852,18 @@ choose_plan(JOIN *join, table_map join_tables)
} }
/*
Compare two join tabs based on the subqueries they are from.
- top-level join tabs go first
- then subqueries are ordered by their select_id (we're using this
criteria because we need a cross-platform, deterministic ordering)
@return
0 - equal
-1 - jt1 < jt2
1 - jt1 > jt2
*/
static int compare_embedding_subqueries(JOIN_TAB *jt1, JOIN_TAB *jt2) static int compare_embedding_subqueries(JOIN_TAB *jt1, JOIN_TAB *jt2)
{ {
/* Determine if the first table is originally from a subquery */ /* Determine if the first table is originally from a subquery */
...@@ -5865,7 +5901,8 @@ static int compare_embedding_subqueries(JOIN_TAB *jt1, JOIN_TAB *jt2) ...@@ -5865,7 +5901,8 @@ static int compare_embedding_subqueries(JOIN_TAB *jt1, JOIN_TAB *jt2)
/* /*
Put top-level tables in front. Tables from within subqueries must follow, Put top-level tables in front. Tables from within subqueries must follow,
grouped by their owner subquery. We don't care about the order that grouped by their owner subquery. We don't care about the order that
subquery groups are in, because pre_sort_tables() will move the groups. subquery groups are in, because choose_initial_table_order() will re-order
the groups.
*/ */
if (tbl1_select_no != tbl2_select_no) if (tbl1_select_no != tbl2_select_no)
return tbl1_select_no > tbl2_select_no ? 1 : -1; return tbl1_select_no > tbl2_select_no ? 1 : -1;
...@@ -5890,6 +5927,9 @@ static int compare_embedding_subqueries(JOIN_TAB *jt1, JOIN_TAB *jt2) ...@@ -5890,6 +5927,9 @@ static int compare_embedding_subqueries(JOIN_TAB *jt1, JOIN_TAB *jt2)
b: dependent = 0x0 table->map = 0x2 found_records = 3 ptr = 0x907e838 b: dependent = 0x0 table->map = 0x2 found_records = 3 ptr = 0x907e838
c: dependent = 0x6 table->map = 0x10 found_records = 2 ptr = 0x907ecd0 c: dependent = 0x6 table->map = 0x10 found_records = 2 ptr = 0x907ecd0
As for subuqueries, this function must produce order that can be fed to
choose_initial_table_order().
@retval @retval
1 if first is bigger 1 if first is bigger
@retval @retval
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment