Commit 0fca9c18 authored by Sergey Petrunya's avatar Sergey Petrunya

post-merge fixes: get MWL#90 code to work with MWL#89's

way of processing prepared statements:
- conversion subquery_predicate -> TABLE_LIST is once per-statement
- However, the code must take into account that materialized temptable
  is dropped and re-created on each execution (the tricky part is that 
  at start of n-th EXECUTE we have TABLE_LIST object but not its TABLE object)
- IN-equality is injected into WHERE on every execution.
parent 621589c9
...@@ -4064,6 +4064,7 @@ bool subselect_hash_sj_engine::make_semi_join_conds() ...@@ -4064,6 +4064,7 @@ bool subselect_hash_sj_engine::make_semi_join_conds()
context->init(); context->init();
context->first_name_resolution_table= context->first_name_resolution_table=
context->last_name_resolution_table= tmp_table_ref; context->last_name_resolution_table= tmp_table_ref;
semi_join_conds_context= context;
for (uint i= 0; i < item_in->left_expr->cols(); i++) for (uint i= 0; i < item_in->left_expr->cols(); i++)
{ {
......
...@@ -839,6 +839,8 @@ class subselect_hash_sj_engine : public subselect_engine ...@@ -839,6 +839,8 @@ class subselect_hash_sj_engine : public subselect_engine
not equal to the search key in SQL terms. not equal to the search key in SQL terms.
*/ */
Item_cond_and *semi_join_conds; Item_cond_and *semi_join_conds;
Name_resolution_context *semi_join_conds_context;
subselect_hash_sj_engine(THD *thd, Item_subselect *in_predicate, subselect_hash_sj_engine(THD *thd, Item_subselect *in_predicate,
subselect_single_select_engine *old_engine) subselect_single_select_engine *old_engine)
......
...@@ -1397,6 +1397,7 @@ static bool convert_subq_to_jtbm(JOIN *parent_join, ...@@ -1397,6 +1397,7 @@ static bool convert_subq_to_jtbm(JOIN *parent_join,
jtbm->table->tablenr= parent_join->table_count; jtbm->table->tablenr= parent_join->table_count;
jtbm->table->map= table_map(1) << (parent_join->table_count); jtbm->table->map= table_map(1) << (parent_join->table_count);
jtbm->jtbm_table_no= jtbm->table->tablenr;
parent_join->table_count++; parent_join->table_count++;
DBUG_ASSERT(parent_join->table_count < MAX_TABLES); DBUG_ASSERT(parent_join->table_count < MAX_TABLES);
...@@ -1409,7 +1410,7 @@ static bool convert_subq_to_jtbm(JOIN *parent_join, ...@@ -1409,7 +1410,7 @@ static bool convert_subq_to_jtbm(JOIN *parent_join,
create_subquery_temptable_name(tbl_alias, hash_sj_engine->materialize_join-> create_subquery_temptable_name(tbl_alias, hash_sj_engine->materialize_join->
select_lex->select_number); select_lex->select_number);
jtbm->alias= tbl_alias; jtbm->alias= tbl_alias;
#if 0
/* Inject sj_on_expr into the parent's WHERE or ON */ /* Inject sj_on_expr into the parent's WHERE or ON */
if (emb_tbl_nest) if (emb_tbl_nest)
{ {
...@@ -1426,7 +1427,7 @@ static bool convert_subq_to_jtbm(JOIN *parent_join, ...@@ -1426,7 +1427,7 @@ static bool convert_subq_to_jtbm(JOIN *parent_join,
parent_join->conds->fix_fields(parent_join->thd, &parent_join->conds); parent_join->conds->fix_fields(parent_join->thd, &parent_join->conds);
parent_join->select_lex->where= parent_join->conds; parent_join->select_lex->where= parent_join->conds;
} }
#endif
/* Don't unlink the child subselect, as the subquery will be used. */ /* Don't unlink the child subselect, as the subquery will be used. */
DBUG_RETURN(FALSE); DBUG_RETURN(FALSE);
......
...@@ -7768,7 +7768,14 @@ bool setup_tables(THD *thd, Name_resolution_context *context, ...@@ -7768,7 +7768,14 @@ bool setup_tables(THD *thd, Name_resolution_context *context,
first_select_table= 0; first_select_table= 0;
tablenr= 0; tablenr= 0;
} }
setup_table_map(table, table_list, tablenr);
if (table_list->jtbm_subselect)
{
table_list->jtbm_table_no= tablenr;
}
else
setup_table_map(table, table_list, tablenr);
if (table_list->process_index_hints(table)) if (table_list->process_index_hints(table))
DBUG_RETURN(1); DBUG_RETURN(1);
} }
...@@ -7797,17 +7804,38 @@ bool setup_tables(THD *thd, Name_resolution_context *context, ...@@ -7797,17 +7804,38 @@ bool setup_tables(THD *thd, Name_resolution_context *context,
if (res) if (res)
DBUG_RETURN(1); DBUG_RETURN(1);
} }
if (table_list->jtbm_subselect) if (table_list->jtbm_subselect)
{ {
Item *item= table_list->jtbm_subselect; Item *item= table_list->jtbm_subselect->optimizer;
if (item->fix_fields(thd, &item)) if (table_list->jtbm_subselect->optimizer->fix_fields(thd, &item))
{ {
my_error(ER_TOO_MANY_TABLES,MYF(0),MAX_TABLES); /* psergey-todo: WHY ER_TOO_MANY_TABLES ???*/ my_error(ER_TOO_MANY_TABLES,MYF(0),MAX_TABLES); /* psergey-todo: WHY ER_TOO_MANY_TABLES ???*/
DBUG_RETURN(1); DBUG_RETURN(1);
} }
DBUG_ASSERT(item == table_list->jtbm_subselect); DBUG_ASSERT(item == table_list->jtbm_subselect->optimizer);
/*
{
Item_in_subselect *subq_pred= table_list->jtbm_subselect;
double rows;
double read_time;
// psergey-merge: disable IN->EXISTS for JTBM subqueries, for now.
subq_pred->in_strategy &= ~SUBS_IN_TO_EXISTS;
subq_pred->optimize(&rows, &read_time);
subq_pred->jtbm_read_time= read_time;
subq_pred->jtbm_record_count=rows;
subq_pred->is_jtbm_merged= TRUE;
}
// The following call should never ever be made on its own anymore:
if (table_list->jtbm_subselect->setup_mat_engine()) // dont_switch_arena=FALSE if (table_list->jtbm_subselect->setup_mat_engine()) // dont_switch_arena=FALSE
DBUG_RETURN(1); DBUG_RETURN(1);
*/
//psergey-merge: fix prepared statements:
//subselect_hash_sj_engine *mat_engine=
// (subselect_hash_sj_engine*)table_list->jtbm_subselect->engine;
//table= table_list->table= mat_engine->tmp_table;
} }
} }
......
...@@ -766,6 +766,57 @@ JOIN::prepare(Item ***rref_pointer_array, ...@@ -766,6 +766,57 @@ JOIN::prepare(Item ***rref_pointer_array,
} }
void
inject_jtbm_conds(JOIN *join, List<TABLE_LIST> *join_list, Item **join_where)
{
TABLE_LIST *table;
NESTED_JOIN *nested_join;
List_iterator<TABLE_LIST> li(*join_list);
DBUG_ENTER("inject_jtbm_conds");
while ((table= li++))
{
Item_in_subselect *item;
if ((item= table->jtbm_subselect))
{
Item_in_subselect *subq_pred= item;
double rows;
double read_time;
// psergey-merge: disable IN->EXISTS for JTBM subqueries, for now.
subq_pred->in_strategy &= ~SUBS_IN_TO_EXISTS;
subq_pred->optimize(&rows, &read_time);
subq_pred->jtbm_read_time= read_time;
subq_pred->jtbm_record_count=rows;
subq_pred->is_jtbm_merged= TRUE;
subselect_hash_sj_engine *hash_sj_engine=
((subselect_hash_sj_engine*)item->engine);
//repeat of convert_subq_to_jtbm:
table->table= hash_sj_engine->tmp_table;
setup_table_map(table->table, table, table->jtbm_table_no);
Item *sj_conds= hash_sj_engine->semi_join_conds;
(*join_where)= and_items(*join_where, sj_conds);
(*join_where)->fix_fields(join->thd, join_where);
//parent_join->select_lex->where= parent_join->conds;
}
if ((nested_join= table->nested_join))
{
inject_jtbm_conds(join, &nested_join->join_list, join_where);
}
}
DBUG_VOID_RETURN;
}
/** /**
global select optimisation. global select optimisation.
...@@ -856,6 +907,9 @@ JOIN::optimize() ...@@ -856,6 +907,9 @@ JOIN::optimize()
if (arena) if (arena)
thd->restore_active_arena(arena, &backup); thd->restore_active_arena(arena, &backup);
} }
//psergey-merge
inject_jtbm_conds(this, join_list, &conds);
conds= optimize_cond(this, conds, join_list, &cond_value, &cond_equal); conds= optimize_cond(this, conds, join_list, &cond_value, &cond_equal);
if (thd->is_error()) if (thd->is_error())
......
...@@ -1272,6 +1272,7 @@ struct TABLE_LIST ...@@ -1272,6 +1272,7 @@ struct TABLE_LIST
/* If this is a jtbm semi-join object: corresponding subselect predicate */ /* If this is a jtbm semi-join object: corresponding subselect predicate */
Item_in_subselect *jtbm_subselect; Item_in_subselect *jtbm_subselect;
uint jtbm_table_no;
SJ_MATERIALIZATION_INFO *sj_mat_info; 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