mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
MWL#90: Address review feedback part #7
This commit is contained in:
@ -1223,6 +1223,7 @@ static void create_subquery_temptable_name(char *to, uint number)
|
||||
to[1]= 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Convert subquery predicate into non-mergeable semi-join nest.
|
||||
|
||||
|
@ -33,8 +33,7 @@
|
||||
|
||||
#define NO_MORE_RECORDS_IN_BUFFER (uint)(-1)
|
||||
|
||||
void save_or_restore_used_tabs(JOIN_TAB *join_tab, bool save);
|
||||
JOIN_TAB *next_linear_tab(JOIN* join, JOIN_TAB* tab, bool include_bush_roots);
|
||||
static void save_or_restore_used_tabs(JOIN_TAB *join_tab, bool save);
|
||||
|
||||
/*****************************************************************************
|
||||
* Join cache module
|
||||
@ -168,27 +167,46 @@ void JOIN_CACHE::calc_record_fields()
|
||||
if (join_tab->bush_root_tab)
|
||||
{
|
||||
/*
|
||||
If the tab we're attached to is inside an SJM-nest, start from the
|
||||
first tab in that SJM nest
|
||||
--ot1--SJM1--------------ot2--...
|
||||
|
|
||||
|
|
||||
+-it1--...--itN
|
||||
^____________ this->join_tab is somewhere here,
|
||||
inside an sjm nest.
|
||||
|
||||
The join buffer should store the values of it1.*, it2.*, ..
|
||||
It should not store values of ot1.*.
|
||||
*/
|
||||
tab= join_tab->bush_root_tab->bush_children->start;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
The tab we're attached to is not inside an SJM-nest. Start from the
|
||||
first non-const table.
|
||||
-ot1--ot2--SJM1--SJM2--------------ot3--...--otN
|
||||
| | ^
|
||||
| +-it21--...--it2N |
|
||||
| \-- we're somewhere here,
|
||||
+-it11--...--it1N at the top level
|
||||
|
||||
The join buffer should store the values of
|
||||
|
||||
ot1.*, ot2.*, it1{i}, it2{j}.*, ot3.*, ...
|
||||
|
||||
that is, we should start from the first non-const top-level table.
|
||||
|
||||
We will need to store columns of SJ-inner tables (it_X_Y.*), but we're
|
||||
not interested in storing the columns of materialization tables
|
||||
themselves. Beause of that, if the first non-const top-level table is a
|
||||
materialized table, we move to its bush_children:
|
||||
*/
|
||||
tab= join->join_tab + join->const_tables;
|
||||
if (tab->bush_children)
|
||||
tab= tab->bush_children->start;
|
||||
}
|
||||
}
|
||||
start_tab= tab;
|
||||
if (start_tab->bush_children)
|
||||
start_tab= start_tab->bush_children->start;
|
||||
DBUG_ASSERT(!start_tab->bush_children);
|
||||
|
||||
tab= start_tab;
|
||||
|
||||
start_tab= tab;
|
||||
fields= 0;
|
||||
blobs= 0;
|
||||
flag_fields= 0;
|
||||
@ -254,7 +272,8 @@ void JOIN_CACHE::collect_info_on_key_args()
|
||||
cache= this;
|
||||
do
|
||||
{
|
||||
for (tab= cache->start_tab; tab != cache->join_tab; tab= next_linear_tab(join, tab, FALSE))
|
||||
for (tab= cache->start_tab; tab != cache->join_tab;
|
||||
tab= next_linear_tab(join, tab, FALSE))
|
||||
{
|
||||
uint key_args;
|
||||
bitmap_clear_all(&tab->table->tmp_set);
|
||||
@ -3248,7 +3267,8 @@ int JOIN_TAB_SCAN::next()
|
||||
@param save TRUE save
|
||||
FALSE restore
|
||||
*/
|
||||
void save_or_restore_used_tabs(JOIN_TAB *join_tab, bool save)
|
||||
|
||||
static void save_or_restore_used_tabs(JOIN_TAB *join_tab, bool save)
|
||||
{
|
||||
JOIN_TAB *first= join_tab->bush_root_tab?
|
||||
join_tab->bush_root_tab->bush_children->start :
|
||||
|
@ -6378,12 +6378,28 @@ JOIN_TAB *first_linear_tab(JOIN *join, bool after_const_tables)
|
||||
A helper function to loop over all join's join_tab in sequential fashion
|
||||
|
||||
DESCRIPTION
|
||||
Depending on include_bush_roots parameter, JOIN_TABS that represent
|
||||
SJM-scan/lookups are produced or omitted.
|
||||
Depending on include_bush_roots parameter, JOIN_TABs that represent
|
||||
SJM-scan/lookups are either returned or omitted.
|
||||
|
||||
SJM-Bush children are returned right after (or in place of) their container
|
||||
join tab (TODO: does anybody depend on this? A: make_join_readinfo() seems
|
||||
to.)
|
||||
to)
|
||||
|
||||
For example, if we have this structure:
|
||||
|
||||
ot1--ot2--sjm1----------------ot3-...
|
||||
|
|
||||
+--it1--it2--it3
|
||||
|
||||
calls to next_linear_tab( include_bush_roots=TRUE) will return:
|
||||
|
||||
ot1 ot2 sjm1 it1 it2 it3 ot3 ...
|
||||
|
||||
while calls to next_linear_tab( include_bush_roots=FALSE) will return:
|
||||
|
||||
ot1 ot2 it1 it2 it3 ot3 ...
|
||||
|
||||
(note that sjm1 won't be returned).
|
||||
*/
|
||||
|
||||
JOIN_TAB *next_linear_tab(JOIN* join, JOIN_TAB* tab, bool include_bush_roots)
|
||||
@ -6418,6 +6434,24 @@ JOIN_TAB *next_linear_tab(JOIN* join, JOIN_TAB* tab, bool include_bush_roots)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Start to iterate over all join tables in bush-children-first order, excluding
|
||||
the const tables (see next_depth_first_tab() comment for details)
|
||||
*/
|
||||
|
||||
JOIN_TAB *first_depth_first_tab(JOIN* join)
|
||||
{
|
||||
JOIN_TAB* tab;
|
||||
/* This means we're starting the enumeration */
|
||||
if (join->const_tables == join->top_jtrange_tables)
|
||||
return NULL;
|
||||
|
||||
tab= join->join_tab + join->const_tables;
|
||||
|
||||
return (tab->bush_children) ? tab->bush_children->start : tab;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
A helper function to iterate over all join tables in bush-children-first order
|
||||
|
||||
@ -6425,43 +6459,28 @@ JOIN_TAB *next_linear_tab(JOIN* join, JOIN_TAB* tab, bool include_bush_roots)
|
||||
|
||||
For example, for this join plan
|
||||
|
||||
ot1 ot2 sjm ot3
|
||||
| +--------+
|
||||
| |
|
||||
it1 it2 it3
|
||||
ot1--ot2--sjm1------------ot3-...
|
||||
|
|
||||
|
|
||||
it1--it2--it3
|
||||
|
||||
|
||||
the function will return
|
||||
|
||||
ot1-ot2-it1-it2-it3-sjm-ot3 ...
|
||||
call to first_depth_first_tab() will return ot1, and subsequent calls to
|
||||
next_depth_first_tab() will return:
|
||||
|
||||
ot2 it1 it2 it3 sjm ot3 ...
|
||||
*/
|
||||
|
||||
JOIN_TAB *next_depth_first_tab(JOIN* join, JOIN_TAB* tab)
|
||||
{
|
||||
bool start= FALSE;
|
||||
if (tab == NULL)
|
||||
{
|
||||
/* This means we're starting the enumeration */
|
||||
if (join->const_tables == join->top_jtrange_tables)
|
||||
return NULL;
|
||||
|
||||
tab= join->join_tab + join->const_tables;
|
||||
start= TRUE;
|
||||
}
|
||||
|
||||
/* If we're inside SJM nest and have reached its end, get out */
|
||||
if (tab->last_leaf_in_bush)
|
||||
return tab->bush_root_tab;
|
||||
|
||||
/* Move to next tab in the array we're traversing*/
|
||||
if (!start)
|
||||
tab++;
|
||||
/* Move to next tab in the array we're traversing */
|
||||
tab++;
|
||||
|
||||
//psergey-remove: check:
|
||||
DBUG_ASSERT(join->join_tab_ranges.head()->end ==
|
||||
join->join_tab +join->top_jtrange_tables);
|
||||
if (tab == join->join_tab +join->top_jtrange_tables)
|
||||
return NULL; /* End */
|
||||
return NULL; /* Outside SJM nest and reached EOF */
|
||||
|
||||
if (tab->bush_children)
|
||||
return tab->bush_children->start;
|
||||
@ -7384,7 +7403,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
|
||||
JOIN_TAB *tab;
|
||||
table_map current_map;
|
||||
uint i= join->const_tables;
|
||||
for (tab= next_depth_first_tab(join, NULL); tab;
|
||||
for (tab= first_depth_first_tab(join); tab;
|
||||
tab= next_depth_first_tab(join, tab), i++)
|
||||
{
|
||||
bool is_hj;
|
||||
|
Reference in New Issue
Block a user