1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-30 16:24:05 +03:00
This commit is contained in:
Sergey Petrunya
2011-12-14 04:56:54 +04:00
7 changed files with 346 additions and 124 deletions

View File

@ -798,117 +798,6 @@ err:
}
/*
Create a dummy temporary table, useful only for the sake of having a
TABLE* object with map,tablenr and maybe_null properties.
This is used by non-mergeable semi-join materilization code to handle
degenerate cases where materialized subquery produced "Impossible WHERE"
and thus wasn't materialized.
*/
TABLE *create_dummy_tmp_table(THD *thd)
{
DBUG_ENTER("create_dummy_tmp_table");
TABLE *table;
TMP_TABLE_PARAM sjm_table_param;
sjm_table_param.init();
sjm_table_param.field_count= 1;
List<Item> sjm_table_cols;
Item *column_item= new Item_int(1);
sjm_table_cols.push_back(column_item);
if (!(table= create_tmp_table(thd, &sjm_table_param,
sjm_table_cols, (ORDER*) 0,
TRUE /* distinct */,
1, /*save_sum_fields*/
thd->options | TMP_TABLE_ALL_COLUMNS,
HA_POS_ERROR /*rows_limit */,
(char*)"dummy", TRUE /* Do not open */)))
{
DBUG_RETURN(NULL);
}
DBUG_RETURN(table);
}
void
setup_jtbm_semi_joins(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("setup_jtbm_semi_joins");
while ((table= li++))
{
Item_in_subselect *item;
if ((item= table->jtbm_subselect))
{
Item_in_subselect *subq_pred= item;
double rows;
double read_time;
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;
JOIN *subq_join= subq_pred->unit->first_select()->join;
if (!subq_join->tables_list || !subq_join->table_count)
{
/*
This is an empty and constant table.
TODO: what if this is not empty but still constant?
We'll need to check the equality but there's no materializatnion
table?
A: create an IN-equality from
- left_expr
- right_expr. Q: how can right-expr exist in the context of
parent select? We don't have refs from outside to inside!
A: create/check in the context of the child select?
for injection, check how in->exists is performed.
*/
subq_pred->is_jtbm_const_tab= TRUE;
TABLE *dummy_table= create_dummy_tmp_table(join->thd);
table->table= dummy_table;
table->table->pos_in_table_list= table;
setup_table_map(table->table, table, table->jtbm_table_no);
}
else
{
DBUG_ASSERT(subq_pred->test_set_strategy(SUBS_MATERIALIZATION));
subq_pred->is_jtbm_const_tab= FALSE;
subselect_hash_sj_engine *hash_sj_engine=
((subselect_hash_sj_engine*)item->engine);
table->table= hash_sj_engine->tmp_table;
table->table->pos_in_table_list= 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);
if (!(*join_where)->fixed)
(*join_where)->fix_fields(join->thd, join_where);
}
}
if ((nested_join= table->nested_join))
{
setup_jtbm_semi_joins(join, &nested_join->join_list, join_where);
}
}
DBUG_VOID_RETURN;
}
/**
global select optimisation.
@ -1030,7 +919,8 @@ JOIN::optimize()
thd->restore_active_arena(arena, &backup);
}
setup_jtbm_semi_joins(this, join_list, &conds);
if (setup_jtbm_semi_joins(this, join_list, &conds))
DBUG_RETURN(1);
conds= optimize_cond(this, conds, join_list, &cond_value, &cond_equal);
@ -15658,7 +15548,12 @@ join_read_const_table(JOIN_TAB *tab, POSITION *pos)
tab->table->pos_in_table_list->jtbm_subselect->is_jtbm_const_tab)
{
/* Row will not be found */
DBUG_RETURN(-1);
int res;
if (tab->table->pos_in_table_list->jtbm_subselect->jtbm_const_row_found)
res= 0;
else
res= -1;
DBUG_RETURN(res);
}
else if (tab->type == JT_SYSTEM)
{
@ -21455,11 +21350,20 @@ void TABLE_LIST::print(THD *thd, table_map eliminated_tables, String *str,
}
else if (jtbm_subselect)
{
str->append(STRING_WITH_LEN(" <materialize> ("));
subselect_hash_sj_engine *hash_engine;
hash_engine= (subselect_hash_sj_engine*)jtbm_subselect->engine;
hash_engine->materialize_engine->print(str, query_type);
str->append(')');
if (jtbm_subselect->is_jtbm_const_tab)
{
str->append(STRING_WITH_LEN(" <materialize> ("));
jtbm_subselect->engine->print(str, query_type);
str->append(')');
}
else
{
str->append(STRING_WITH_LEN(" <materialize> ("));
subselect_hash_sj_engine *hash_engine;
hash_engine= (subselect_hash_sj_engine*)jtbm_subselect->engine;
hash_engine->materialize_engine->print(str, query_type);
str->append(')');
}
}
else
{