maria-developers team mailing list archive
-
maria-developers team
-
Mailing list archive
-
Message #03474
bzr commit into file:///home/tsk/mprog/src/5.3-mwl89/ branch (timour:2804)
#At file:///home/tsk/mprog/src/5.3-mwl89/ based on revid:timour@xxxxxxxxxxxx-20100718114608-wiz9ji9z80pzjw2k
2804 timour@xxxxxxxxxxxx 2010-07-18
MWL#89: Cost-based choice between Materialization and IN->EXISTS transformation
Step2 in the separation of the creation of IN->EXISTS equi-join conditions from
their injection. The goal of this separation is to make it possible that the
IN->EXISTS conditions can be used for cost estimation without actually modifying
the subquery.
This patch separates row_value_in_to_exists_transformer() into two methods:
- create_row_value_in_to_exists_cond(), and
- inject_row_value_in_to_exists_cond()
The patch performs minimal refactoring of the code so that it is easier to solve
problems resulting from the separation. There is a lot to be simplified in this
code, but this will be done separately.
modified:
sql/item_subselect.cc
sql/item_subselect.h
=== modified file 'sql/item_subselect.cc'
--- a/sql/item_subselect.cc 2010-07-18 11:46:08 +0000
+++ b/sql/item_subselect.cc 2010-07-18 12:59:24 +0000
@@ -1524,16 +1524,16 @@ Item_subselect::trans_res
Item_in_subselect::single_value_in_to_exists_transformer(JOIN * join,
Comp_creator *func)
{
- Item *where_term;
- Item *having_term;
+ Item *where_item;
+ Item *having_item;
Item_subselect::trans_res res;
res= create_single_value_in_to_exists_cond(join, func,
- &where_term, &having_term);
+ &where_item, &having_item);
if (res != RES_OK)
return res;
res= inject_single_value_in_to_exists_cond(join, func,
- where_term, having_term);
+ where_item, having_item);
return res;
}
@@ -1541,8 +1541,8 @@ Item_in_subselect::single_value_in_to_ex
Item_subselect::trans_res
Item_in_subselect::create_single_value_in_to_exists_cond(JOIN * join,
Comp_creator *func,
- Item **where_term,
- Item **having_term)
+ Item **where_item,
+ Item **having_item)
{
SELECT_LEX *select_lex= join->select_lex;
DBUG_ENTER("Item_in_subselect::create_single_value_in_to_exists_cond");
@@ -1569,8 +1569,8 @@ Item_in_subselect::create_single_value_i
if (item->fix_fields(thd, 0))
DBUG_RETURN(RES_ERROR);
- *having_term= item;
- *where_term= NULL;
+ *having_item= item;
+ *where_item= NULL;
}
else
{
@@ -1595,7 +1595,7 @@ Item_in_subselect::create_single_value_i
if (having->fix_fields(thd, 0))
DBUG_RETURN(RES_ERROR);
- *having_term= having;
+ *having_item= having;
item= new Item_cond_or(item,
new Item_func_isnull(orig_item));
@@ -1613,7 +1613,7 @@ Item_in_subselect::create_single_value_i
if (item->fix_fields(thd, 0))
DBUG_RETURN(RES_ERROR);
- *where_term= item;
+ *where_item= item;
}
else
{
@@ -1640,13 +1640,13 @@ Item_in_subselect::create_single_value_i
if (new_having->fix_fields(thd, 0))
DBUG_RETURN(RES_ERROR);
- *having_term= new_having;
- *where_term= NULL;
+ *having_item= new_having;
+ *where_item= NULL;
}
else
{
- *having_term= NULL;
- *where_term= (Item*) select_lex->item_list.head();
+ *having_item= NULL;
+ *where_item= (Item*) select_lex->item_list.head();
}
}
}
@@ -1659,8 +1659,8 @@ Item_in_subselect::create_single_value_i
Item_subselect::trans_res
Item_in_subselect::inject_single_value_in_to_exists_cond(JOIN * join,
Comp_creator *func,
- Item *where_term,
- Item *having_term)
+ Item *where_item,
+ Item *having_item)
{
SELECT_LEX *select_lex= join->select_lex;
bool fix_res;
@@ -1675,9 +1675,9 @@ Item_in_subselect::inject_single_value_i
we can assign select_lex->having here, and pass 0 as last
argument (reference) to fix_fields()
*/
- select_lex->having= join->having= and_items(join->having, having_term);
- if (join->having == having_term)
- having_term->name= (char*)in_having_cond;
+ select_lex->having= join->having= and_items(join->having, having_item);
+ if (join->having == having_item)
+ having_item->name= (char*)in_having_cond;
select_lex->having_fix_field= 1;
/*
we do not check join->having->fixed, because Item_and (from and_items)
@@ -1707,8 +1707,8 @@ Item_in_subselect::inject_single_value_i
we can assign select_lex->having here, and pass 0 as last
argument (reference) to fix_fields()
*/
- having_term->name= (char*)in_having_cond;
- select_lex->having= join->having= having_term;
+ having_item->name= (char*)in_having_cond;
+ select_lex->having= join->having= having_item;
select_lex->having_fix_field= 1;
/*
we do not check join->having->fixed, because Item_and (from
@@ -1726,14 +1726,14 @@ Item_in_subselect::inject_single_value_i
single_value_transformer but there is no corresponding action in
row_value_transformer?
*/
- where_term->name= (char *)in_additional_cond;
+ where_item->name= (char *)in_additional_cond;
/*
AND can't be changed during fix_fields()
we can assign select_lex->having here, and pass 0 as last
argument (reference) to fix_fields()
*/
- select_lex->where= join->conds= and_items(join->conds, where_term);
+ select_lex->where= join->conds= and_items(join->conds, where_item);
select_lex->where->top_level_item();
/*
we do not check join->conds->fixed, because Item_and can't be fixed
@@ -1746,8 +1746,8 @@ Item_in_subselect::inject_single_value_i
{
if (select_lex->master_unit()->is_union())
{
- having_term->name= (char*)in_having_cond;
- select_lex->having= join->having= having_term;
+ having_item->name= (char*)in_having_cond;
+ select_lex->having= join->having= having_item;
select_lex->having_fix_field= 1;
/*
@@ -1765,11 +1765,11 @@ Item_in_subselect::inject_single_value_i
// it is single select without tables => possible optimization
// remove the dependence mark since the item is moved to upper
// select and is not outer anymore.
- where_term->walk(&Item::remove_dependence_processor, 0,
+ where_item->walk(&Item::remove_dependence_processor, 0,
(uchar *) select_lex->outer_select());
- where_term= func->create(left_expr, where_term);
+ where_item= func->create(left_expr, where_item);
// fix_field of item will be done in time of substituting
- substitution= where_term;
+ substitution= where_item;
have_to_be_excluded= 1;
if (thd->lex->describe)
{
@@ -1866,20 +1866,37 @@ Item_in_subselect::row_value_transformer
add the equi-join and the "is null" to WHERE
add the is_not_null_test to HAVING
*/
-
Item_subselect::trans_res
Item_in_subselect::row_value_in_to_exists_transformer(JOIN * join)
{
+ Item *where_item;
+ Item *having_item;
+ Item_subselect::trans_res res;
+
+ res= create_row_value_in_to_exists_cond(join, &where_item, &having_item);
+ if (res != RES_OK)
+ return res;
+ res= inject_row_value_in_to_exists_cond(join, where_item, having_item);
+ return res;
+}
+
+
+Item_subselect::trans_res
+Item_in_subselect::create_row_value_in_to_exists_cond(JOIN * join,
+ Item **where_item,
+ Item **having_item)
+{
SELECT_LEX *select_lex= join->select_lex;
- Item *having_item= 0;
uint cols_num= left_expr->cols();
bool is_having_used= (join->having || select_lex->with_sum_func ||
select_lex->group_list.first ||
!select_lex->table_list.elements);
- DBUG_ENTER("Item_in_subselect::row_value_in_to_exists_transformer");
+ DBUG_ENTER("Item_in_subselect::create_row_value_in_to_exists_cond");
+
+ *where_item= NULL;
+ *having_item= NULL;
- select_lex->uncacheable|= UNCACHEABLE_DEPENDENT;
if (is_having_used)
{
/*
@@ -1899,6 +1916,7 @@ Item_in_subselect::row_value_in_to_exist
for (uint i= 0; i < cols_num; i++)
{
DBUG_ASSERT((left_expr->fixed &&
+
select_lex->ref_pointer_array[i]->fixed) ||
(select_lex->ref_pointer_array[i]->type() == REF_ITEM &&
((Item_ref*)(select_lex->ref_pointer_array[i]))->ref_type() ==
@@ -1932,8 +1950,8 @@ Item_in_subselect::row_value_in_to_exist
if (!(col_item= new Item_func_trig_cond(col_item, get_cond_guard(i))))
DBUG_RETURN(RES_ERROR);
}
- having_item= and_items(having_item, col_item);
-
+ *having_item= and_items(*having_item, col_item);
+
Item *item_nnull_test=
new Item_is_not_null_test(this,
new Item_ref(&select_lex->context,
@@ -1950,8 +1968,8 @@ Item_in_subselect::row_value_in_to_exist
item_having_part2= and_items(item_having_part2, item_nnull_test);
item_having_part2->top_level_item();
}
- having_item= and_items(having_item, item_having_part2);
- having_item->top_level_item();
+ *having_item= and_items(*having_item, item_having_part2);
+ (*having_item)->top_level_item();
}
else
{
@@ -1972,7 +1990,6 @@ Item_in_subselect::row_value_in_to_exist
(l2 = v2) and
(l3 = v3)
*/
- Item *where_item= 0;
for (uint i= 0; i < cols_num; i++)
{
Item *item, *item_isnull;
@@ -2030,10 +2047,33 @@ Item_in_subselect::row_value_in_to_exist
new Item_func_trig_cond(having_col_item, get_cond_guard(i))))
DBUG_RETURN(RES_ERROR);
}
- having_item= and_items(having_item, having_col_item);
+ *having_item= and_items(*having_item, having_col_item);
}
- where_item= and_items(where_item, item);
+ *where_item= and_items(*where_item, item);
}
+ (*where_item)->fix_fields(thd, 0);
+ }
+
+ DBUG_RETURN(RES_OK);
+}
+
+
+Item_subselect::trans_res
+Item_in_subselect::inject_row_value_in_to_exists_cond(JOIN * join,
+ Item *where_item,
+ Item *having_item)
+{
+ SELECT_LEX *select_lex= join->select_lex;
+ bool is_having_used= (join->having || select_lex->with_sum_func ||
+ select_lex->group_list.first ||
+ !select_lex->table_list.elements);
+
+ DBUG_ENTER("Item_in_subselect::inject_row_value_in_to_exists_cond");
+
+ select_lex->uncacheable|= UNCACHEABLE_DEPENDENT;
+
+ if (!is_having_used)
+ {
/*
AND can't be changed during fix_fields()
we can assign select_lex->where here, and pass 0 as last
@@ -2041,9 +2081,10 @@ Item_in_subselect::row_value_in_to_exist
*/
select_lex->where= join->conds= and_items(join->conds, where_item);
select_lex->where->top_level_item();
- if (join->conds->fix_fields(thd, 0))
+ if (!join->conds->fixed && join->conds->fix_fields(thd, 0))
DBUG_RETURN(RES_ERROR);
}
+
if (having_item)
{
bool res;
@@ -2057,12 +2098,11 @@ Item_in_subselect::row_value_in_to_exist
argument (reference) to fix_fields()
*/
select_lex->having_fix_field= 1;
- res= join->having->fix_fields(thd, 0);
+ if (!join->having->fixed)
+ res= join->having->fix_fields(thd, 0);
select_lex->having_fix_field= 0;
if (res)
- {
DBUG_RETURN(RES_ERROR);
- }
}
DBUG_RETURN(RES_OK);
=== modified file 'sql/item_subselect.h'
--- a/sql/item_subselect.h 2010-07-18 11:46:08 +0000
+++ b/sql/item_subselect.h 2010-07-18 12:59:24 +0000
@@ -438,6 +438,13 @@ public:
Item *having_term);
trans_res row_value_in_to_exists_transformer(JOIN * join);
+ trans_res create_row_value_in_to_exists_cond(JOIN * join,
+ Item **where_term,
+ Item **having_term);
+ trans_res inject_row_value_in_to_exists_cond(JOIN * join,
+ Item *where_term,
+ Item *having_term);
+
virtual bool exec();
longlong val_int();
double val_real();
# Bazaar merge directive format 2 (Bazaar 0.90)
# revision_id: timour@xxxxxxxxxxxx-20100718125924-d4209jm57rzyfjw2
# target_branch: file:///home/tsk/mprog/src/5.3-mwl89/
# testament_sha1: 256cf3972df8f535c234b950e5fa2067816ffa04
# timestamp: 2010-07-18 15:59:28 +0300
# source_branch: file:///home/tsk/mprog/src/5.3/
# base_revision_id: timour@xxxxxxxxxxxx-20100718114608-\
# wiz9ji9z80pzjw2k
#
# Begin bundle
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
dyRThQkIhNBScA==