Commit b2c57ced authored by Sergey Petrunya's avatar Sergey Petrunya

Code cleanup in subquery optimizations

parent 30bac798
......@@ -382,8 +382,20 @@ class Item_in_subselect :public Item_exists_subselect
};
enum_exec_method exec_method;
/* JTBM: temporary measure to tell JTBM predicates from SJ predicates */
/*
JTBM: temporary measure to tell JTBM predicates from SJ predicates
psergey-jtbm-todo: can't we do without this?
- either remove it altogether
- or put into enum_exec_method
We can't remove it altogether as it is used to classify contents in
join->sj_subselects.
*/
bool convert_to_semi_join;
/*
Cost to populate the temporary table (set on if-needed basis).
*/
double startup_cost;
bool *get_cond_guard(int i)
......
......@@ -2,7 +2,7 @@
@file
@brief
Subquery optimization code here.
Semi-join subquery optimizations code
*/
......@@ -228,15 +228,17 @@ int check_and_do_in_subquery_rewrites(JOIN *join)
if (in_subs->exec_method == Item_in_subselect::NOT_TRANSFORMED)
in_subs->exec_method= Item_in_subselect::MATERIALIZATION;
// psergey-jtbm: "if we're top-level, register for
// conversion-to-join-tab".
/*
If the subquery is an AND-part of WHERE register for being processed
with jtbm strategy
*/
if (in_subs->exec_method == Item_in_subselect::MATERIALIZATION &&
thd->thd_marker.emb_on_expr_nest == (TABLE_LIST*)0x1)
{
in_subs->emb_on_expr_nest= thd->thd_marker.emb_on_expr_nest;
in_subs->convert_to_semi_join= FALSE; //JTBM
in_subs->convert_to_semi_join= FALSE;
select_lex->outer_select()->
join->sj_subselects.append(thd->mem_root, in_subs);//JTBM
join->sj_subselects.append(thd->mem_root, in_subs);
}
}
......@@ -406,6 +408,8 @@ static bool make_in_exists_conversion(THD *thd, JOIN *join, Item_in_subselect *i
}
DBUG_RETURN(FALSE);
}
/*
Convert semi-join subquery predicates into semi-join join nests
......@@ -513,29 +517,6 @@ bool convert_join_subqueries_to_semijoins(JOIN *join)
// #tables-in-parent-query + #tables-in-subquery < MAX_TABLES
/* Replace all subqueries to be flattened with Item_int(1) */
arena= thd->activate_stmt_arena_if_needed(&backup);
#if 0
for (in_subq= join->sj_subselects.front();
in_subq != in_subq_end &&
join->tables + (*in_subq)->unit->first_select()->join->tables < MAX_TABLES;
in_subq++)
{
Item **tree= ((*in_subq)->emb_on_expr_nest == (TABLE_LIST*)1)?
&join->conds : &((*in_subq)->emb_on_expr_nest->on_expr);
Item *replace_me= *in_subq;
/*
JTBM: the subquery was already mapped with Item_in_optimizer, so we
should search for that, not for original Item_in_subselect.
TODO: what about delaying that rewrite until here?
*/
if (!(*in_subq)->convert_to_semi_join)
{
replace_me= (*in_subq)->optimizer;
}
if (replace_where_subcondition(join, tree, replace_me, new Item_int(1),
FALSE))
DBUG_RETURN(TRUE); /* purecov: inspected */
}
#endif
for (in_subq= join->sj_subselects.front();
in_subq != in_subq_end &&
......@@ -543,8 +524,6 @@ bool convert_join_subqueries_to_semijoins(JOIN *join)
in_subq++)
{
bool remove_item= TRUE;
//psergey-jtbm: todo: here: check if we should convert to semi-join or
// to JTBM nest.
if ((*in_subq)->convert_to_semi_join)
{
if (convert_subq_to_sj(join, *in_subq))
......@@ -668,6 +647,7 @@ void get_temptable_params(Item_in_subselect *item, ha_rows *out_rows,
*scan_time= data_size/IO_SIZE + 2;
}
/**
@brief Replaces an expression destructively inside the expression tree of
the WHERE clase.
......@@ -685,6 +665,7 @@ void get_temptable_params(Item_in_subselect *item, ha_rows *out_rows,
@return <code>true</code> if there was an error, <code>false</code> if
successful.
*/
static bool replace_where_subcondition(JOIN *join, Item **expr,
Item *old_cond, Item *new_cond,
bool do_fix_fields)
......@@ -920,8 +901,7 @@ static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred)
/* 3. Remove the original subquery predicate from the WHERE/ON */
// The subqueries were replaced for Item_int(1) earlier
subq_pred->exec_method=
Item_in_subselect::SEMI_JOIN; // for subsequent executions
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 */
......@@ -1046,7 +1026,7 @@ static bool convert_subq_to_jtbm(JOIN *parent_join,
SELECT_LEX *parent_lex= parent_join->select_lex;
List<TABLE_LIST> *emb_join_list= &parent_lex->top_join_list;
TABLE_LIST *emb_tbl_nest= NULL; // will change when we learn to handle outer joins
TABLE_LIST *tl;//, *last_leaf;
TABLE_LIST *tl;
DBUG_ENTER("convert_subq_to_jtbm");
if (subq_pred->setup_engine(TRUE))
......@@ -1071,7 +1051,6 @@ static bool convert_subq_to_jtbm(JOIN *parent_join,
jtbm->join_list= emb_join_list;
jtbm->embedding= emb_tbl_nest;
jtbm->alias= (char*)"(jtbm)";
jtbm->jtbm_subselect= subq_pred;
jtbm->nested_join= NULL;
......@@ -1504,6 +1483,7 @@ bool optimize_semijoin_nests(JOIN *join, table_map all_table_map)
DBUG_RETURN(FALSE);
}
/*
Get estimated record length for semi-join materialization temptable
......@@ -1627,6 +1607,7 @@ bool find_eq_ref_candidate(TABLE *table, table_map sj_inner_tables)
return FALSE;
}
/*
Do semi-join optimization step after we've added a new tab to join prefix
......@@ -3762,6 +3743,7 @@ static void remove_subq_pushed_predicates(JOIN *join, Item **where)
}
}
int do_jtbm_materialization_if_needed(JOIN_TAB *tab)
{
Item_in_subselect *in_subs;
......
/* */
/*
Semi-join subquery optimization code definitions
*/
#ifdef USE_PRAGMA_INTERFACE
#pragma interface /* gcc class implementation */
......@@ -365,4 +367,8 @@ int clear_sj_tmp_tables(JOIN *join);
int rewrite_to_index_subquery_engine(JOIN *join);
void get_temptable_params(Item_in_subselect *item, ha_rows *out_rows,
ha_rows *scan_time);
int do_jtbm_materialization_if_needed(JOIN_TAB *tab);
......@@ -243,10 +243,6 @@ join_read_record_no_init(JOIN_TAB *tab);
Item_equal *find_item_equal(COND_EQUAL *cond_equal, Field *field,
bool *inherited_fl);
void get_temptable_params(Item_in_subselect *item, ha_rows *out_rows,
ha_rows *scan_time);
int do_jtbm_materialization_if_needed(JOIN_TAB *tab);
/**
This handles SELECT with and without UNION.
*/
......@@ -2634,7 +2630,6 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables_arg, COND *conds,
no_rows_const_tables |= table->map;
}
}
//psergey-todo: inject jtbm JOIN_TABS here.
stat_vector[i]=0;
join->outer_join=outer_join;
......@@ -7723,7 +7718,7 @@ void JOIN_TAB::cleanup()
table->file->extra(HA_EXTRA_NO_KEYREAD);
}
table->file->ha_index_or_rnd_end();
//psergey-jtbm2:
if (table->pos_in_table_list &&
table->pos_in_table_list->jtbm_subselect)
{
......@@ -11570,7 +11565,6 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
{
key_part_info->null_bit=0;
key_part_info->field= *reg_field;
//psergey-jtbm:
(*reg_field)->flags |= PART_KEY_FLAG;
if (key_part_info == keyinfo->key_part)
(*reg_field)->key_start.set_bit(0);
......
......@@ -1552,18 +1552,11 @@ class JOIN :public Sql_alloc
bool optimized; ///< flag to avoid double optimization in EXPLAIN
/*
Subqueries that will need to be converted to semi-join nests (the list
is emptied when conversion is done
Subqueries that will need to be converted to semi-join nests, including
those converted to jtbm nests. The list is emptied when conversion is done.
*/
Array<Item_in_subselect> sj_subselects;
/*
Subqueries that will need to be converted to JOIN_TABs
(Note this is different from the above in the respect that it's part
of WHERE clause or something like that?)
*/
//Array<Item_in_subselect> jtbm_subselects;
/* Temporary tables used to weed-out semi-join duplicates */
List<TABLE> sj_tmp_tables;
List<SJ_MATERIALIZATION_INFO> sjm_info_list;
......@@ -1586,7 +1579,6 @@ class JOIN :public Sql_alloc
JOIN(THD *thd_arg, List<Item> &fields_arg, ulonglong select_options_arg,
select_result *result_arg)
:fields_list(fields_arg), sj_subselects(thd_arg->mem_root, 4)
//jtbm_subselects(thd_arg->mem_root, 4)
{
init(thd_arg, fields_arg, select_options_arg, result_arg);
}
......
......@@ -1131,7 +1131,7 @@ class Item_in_subselect;
1) table (TABLE_LIST::view == NULL)
- base table
(TABLE_LIST::derived == NULL)
- subquery - TABLE_LIST::table is a temp table
- FROM-clause subquery - TABLE_LIST::table is a temp table
(TABLE_LIST::derived != NULL)
- information schema table
(TABLE_LIST::schema_table != NULL)
......@@ -1150,6 +1150,8 @@ class Item_in_subselect;
(TABLE_LIST::natural_join != NULL)
- JOIN ... USING
(TABLE_LIST::join_using_fields != NULL)
- semi-join nest (sj_on_expr!= NULL && sj_subq_pred!=NULL)
4) jtbm semi-join (jtbm_subselect != NULL)
*/
class Index_hint;
......@@ -1193,8 +1195,13 @@ struct TABLE_LIST
table_map sj_inner_tables;
/* Number of IN-compared expressions */
uint sj_in_exprs;
/* If this is a non-jtbm semi-join nest: corresponding subselect predicate */
Item_in_subselect *sj_subq_pred;
/* If this is a jtbm semi-join object: corresponding subselect predicate */
Item_in_subselect *jtbm_subselect;
SJ_MATERIALIZATION_INFO *sj_mat_info;
/*
......
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