Commit 61084a59 authored by Sergey Petrunya's avatar Sergey Petrunya

MWL#90: Address review feedback part #14

parent a585a4c5
......@@ -2316,7 +2316,7 @@ bool Item_in_subselect::init_left_expr_cache()
An IN predicate might be evaluated in a query for which all tables have
been optimzied away.
*/
if (!outer_join || !outer_join->tables || !outer_join->tables_list)
if (!outer_join || !outer_join->table_count || !outer_join->tables_list)
return TRUE;
if (!(left_expr_cache= new List<Cached_item>))
......@@ -2701,9 +2701,9 @@ int subselect_single_select_engine::exec()
pushed down into the subquery. Those optimizations are ref[_or_null]
acceses. Change them to be full table scans.
*/
for (uint i=join->const_tables ; i < join->tables ; i++)
for (JOIN_TAB *tab= first_linear_tab(join, WITHOUT_CONST_TABLES); tab;
tab= next_linear_tab(join, tab, WITH_BUSH_ROOTS))
{
JOIN_TAB *tab=join->join_tab+i;
if (tab && tab->keyuse)
{
for (uint i= 0; i < tab->ref.key_parts; i++)
......
......@@ -4319,7 +4319,7 @@ double get_sweep_read_cost(const PARAM *param, ha_rows records)
return 1;
*/
JOIN *join= param->thd->lex->select_lex.join;
if (!join || join->tables == 1)
if (!join || join->table_count == 1)
{
/* No join, assume reading is done in one 'sweep' */
result= busy_blocks*(DISK_SEEK_BASE_COST +
......@@ -11270,7 +11270,7 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree)
/* Perform few 'cheap' tests whether this access method is applicable. */
if (!join)
DBUG_RETURN(NULL); /* This is not a select statement. */
if ((join->tables != 1) || /* The query must reference one table. */
if ((join->table_count != 1) || /* The query must reference one table. */
((!join->group_list) && /* Neither GROUP BY nor a DISTINCT query. */
(!join->select_distinct)) ||
(join->select_lex->olap == ROLLUP_TYPE)) /* Check (B3) for ROLLUP */
......
......@@ -203,6 +203,9 @@ static bool sj_table_is_included(JOIN *join, JOIN_TAB *join_tab);
static Item *remove_additional_cond(Item* conds);
static void remove_subq_pushed_predicates(JOIN *join, Item **where);
enum_nested_loop_state
end_sj_materialize(JOIN *join, JOIN_TAB *join_tab, bool end_of_records);
/*
Check if we need JOIN::prepare()-phase subquery rewrites and if yes, do them
......@@ -644,7 +647,7 @@ bool convert_join_subqueries_to_semijoins(JOIN *join)
{
st_select_lex *child_select= (*in_subq)->get_select_lex();
JOIN *child_join= child_select->join;
child_join->outer_tables = child_join->tables;
child_join->outer_tables = child_join->table_count;
/*
child_select->where contains only the WHERE predicate of the
......@@ -693,15 +696,15 @@ bool convert_join_subqueries_to_semijoins(JOIN *join)
bool remove_item= TRUE;
if ((*in_subq)->is_flattenable_semijoin)
{
if (join->tables +
(*in_subq)->unit->first_select()->join->tables >= MAX_TABLES)
if (join->table_count +
(*in_subq)->unit->first_select()->join->table_count >= MAX_TABLES)
break;
if (convert_subq_to_sj(join, *in_subq))
DBUG_RETURN(TRUE);
}
else
{
if (join->tables + 1 >= MAX_TABLES)
if (join->table_count + 1 >= MAX_TABLES)
break;
if (convert_subq_to_jtbm(join, *in_subq, &remove_item))
DBUG_RETURN(TRUE);
......@@ -830,7 +833,8 @@ void get_delayed_table_estimates(TABLE *table,
double read_time;
/* Calculate #rows and cost of join execution */
get_partial_join_cost(join, join->tables - join->const_tables, &read_time, &rows);
get_partial_join_cost(join, join->table_count - join->const_tables,
&read_time, &rows);
*out_rows= (ha_rows)rows;
*startup_cost= read_time;
......@@ -1097,8 +1101,8 @@ static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred)
subq_pred->exec_method= Item_in_subselect::SEMI_JOIN; // for subsequent executions
/*TODO: also reset the 'with_subselect' there. */
/* n. Adjust the parent_join->tables counter */
uint table_no= parent_join->tables;
/* n. Adjust the parent_join->table_count counter */
uint table_no= parent_join->table_count;
/* n. Walk through child's tables and adjust table->map */
for (tl= subq_lex->leaf_tables; tl; tl= tl->next_leaf, table_no++)
{
......@@ -1111,7 +1115,7 @@ static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred)
emb= emb->embedding)
emb->select_lex= parent_join->select_lex;
}
parent_join->tables += subq_lex->join->tables;
parent_join->table_count += subq_lex->join->table_count;
/*
Put the subquery's WHERE into semi-join's sj_on_expr
......@@ -1300,11 +1304,11 @@ static bool convert_subq_to_jtbm(JOIN *parent_join,
((subselect_hash_sj_engine*)subq_pred->engine);
jtbm->table= hash_sj_engine->tmp_table;
jtbm->table->tablenr= parent_join->tables;
jtbm->table->map= table_map(1) << (parent_join->tables);
jtbm->table->tablenr= parent_join->table_count;
jtbm->table->map= table_map(1) << (parent_join->table_count);
parent_join->tables++;
DBUG_ASSERT(parent_join->tables < MAX_TABLES);
parent_join->table_count++;
DBUG_ASSERT(parent_join->table_count < MAX_TABLES);
Item *conds= hash_sj_engine->semi_join_conds;
conds->fix_after_pullout(parent_lex, &conds);
......@@ -2479,7 +2483,7 @@ at_sjmat_pos(const JOIN *join, table_map remaining_tables, const JOIN_TAB *tab,
void fix_semijoin_strategies_for_picked_join_order(JOIN *join)
{
uint table_count=join->tables;
uint table_count=join->table_count;
uint tablenr;
table_map remaining_tables= 0;
table_map handled_tabs= 0;
......@@ -2643,8 +2647,6 @@ void fix_semijoin_strategies_for_picked_join_order(JOIN *join)
}
}
enum_nested_loop_state
end_sj_materialize(JOIN *join, JOIN_TAB *join_tab, bool end_of_records);
/*
Setup semi-join materialization strategy for one semi-join nest
......@@ -3505,6 +3507,7 @@ int do_sj_dups_weedout(THD *thd, SJ_TMP_TABLE *sjtbl)
FALSE OK
TRUE Out of memory error
*/
JOIN_TAB *first_linear_tab(JOIN *join, enum enum_with_const_tables const_tbls);
int setup_semijoin_dups_elimination(JOIN *join, ulonglong options,
uint no_jbuf_after)
......@@ -3512,17 +3515,19 @@ int setup_semijoin_dups_elimination(JOIN *join, ulonglong options,
uint i;
THD *thd= join->thd;
DBUG_ENTER("setup_semijoin_dups_elimination");
for (i= join->const_tables ; i < join->tables; )
POSITION *pos= join->best_positions + join->const_tables;
for (i= join->const_tables ; i < join->top_jtrange_tables; )
{
JOIN_TAB *tab=join->join_tab + i;
POSITION *pos= join->best_positions + i;
//POSITION *pos= join->best_positions + i;
uint keylen, keyno;
switch (pos->sj_strategy) {
case SJ_OPT_MATERIALIZE:
case SJ_OPT_MATERIALIZE_SCAN:
/* Do nothing */
i+= pos->n_sj_tables;
i+= 1;// It used to be pos->n_sj_tables, but now they are embedded in a nest
pos += pos->n_sj_tables;
break;
case SJ_OPT_LOOSE_SCAN:
{
......@@ -3539,6 +3544,7 @@ int setup_semijoin_dups_elimination(JOIN *join, ulonglong options,
if (pos->n_sj_tables > 1)
tab[pos->n_sj_tables - 1].do_firstmatch= tab;
i+= pos->n_sj_tables;
pos+= pos->n_sj_tables;
break;
}
case SJ_OPT_DUPS_WEEDOUT:
......@@ -3636,6 +3642,7 @@ int setup_semijoin_dups_elimination(JOIN *join, ulonglong options,
join->join_tab[i + pos->n_sj_tables - 1].check_weed_out_table= sjtbl;
i+= pos->n_sj_tables;
pos+= pos->n_sj_tables;
break;
}
case SJ_OPT_FIRST_MATCH:
......@@ -3658,10 +3665,12 @@ int setup_semijoin_dups_elimination(JOIN *join, ulonglong options,
}
j[-1].do_firstmatch= jump_to;
i+= pos->n_sj_tables;
pos+= pos->n_sj_tables;
break;
}
case SJ_OPT_NONE:
i++;
pos++;
break;
}
}
......@@ -3848,7 +3857,7 @@ int rewrite_to_index_subquery_engine(JOIN *join)
if (!join->group_list && !join->order &&
join->unit->item &&
join->unit->item->substype() == Item_subselect::IN_SUBS &&
join->tables == 1 && join->conds &&
join->table_count == 1 && join->conds &&
!join->unit->is_union())
{
if (!join->having)
......
......@@ -381,14 +381,14 @@ Sensitive_cursor::open(JOIN *join_arg)
/* Prepare JOIN for reading rows. */
join->tmp_table= 0;
join->join_tab[join->tables-1].next_select= setup_end_select_func(join);
join->join_tab[join->top_jtrange_tables - 1].next_select= setup_end_select_func(join);
join->send_records= 0;
join->fetch_limit= join->unit->offset_limit_cnt;
/* Disable JOIN CACHE as it is not working with cursors yet */
for (JOIN_TAB *tab= join_tab;
tab != join->join_tab + join->tables - 1;
tab++)
for (JOIN_TAB *tab= first_linear_tab(join, WITHOUT_CONST_TABLES);
tab != join->join_tab + join->top_jtrange_tables - 1;
tab= next_linear_tab(join, tab, WITH_BUSH_ROOTS))
{
if (tab->next_select == sub_select_cache)
tab->next_select= sub_select;
......
......@@ -677,9 +677,10 @@ multi_delete::initialize_tables(JOIN *join)
walk= delete_tables;
for (JOIN_TAB *tab=join->join_tab, *end=join->join_tab+join->tables;
tab < end;
tab++)
for (JOIN_TAB *tab= first_linear_tab(join, WITH_CONST_TABLES);
tab;
tab= next_linear_tab(join, tab, WITH_BUSH_ROOTS))
{
if (tab->table->map & tables_to_delete_from)
{
......
This diff is collapsed.
......@@ -647,7 +647,13 @@ class JOIN :public Sql_alloc
passing 1st non-const table to filesort(). NULL means no such table exists.
*/
TABLE *sort_by_table;
uint tables; /**< Number of tables in the join */
/*
Number of tables in the join.
(In MySQL, it is named 'tables' and is also the number of elements in
join->join_tab array. In MariaDB, the latter is not true, so we've renamed
the variable)
*/
uint table_count;
uint outer_tables; /**< Number of tables that are not inside semijoin */
uint const_tables;
/*
......@@ -899,7 +905,7 @@ class JOIN :public Sql_alloc
{
join_tab= join_tab_save= 0;
table= 0;
tables= 0;
table_count= 0;
top_jtrange_tables= 0;
const_tables= 0;
eliminated_tables= 0;
......@@ -1015,7 +1021,7 @@ class JOIN :public Sql_alloc
}
inline table_map all_tables_map()
{
return (table_map(1) << tables) - 1;
return (table_map(1) << table_count) - 1;
}
/*
Return the table for which an index scan can be used to satisfy
......
......@@ -690,7 +690,7 @@ bool st_select_lex_unit::cleanup()
if ((join= fake_select_lex->join))
{
join->tables_list= 0;
join->tables= 0;
join->table_count= 0;
join->top_jtrange_tables= 0;
}
error|= fake_select_lex->cleanup();
......
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