Commit c7a02249 authored by bell@sanja.is.com.ua's avatar bell@sanja.is.com.ua

postreviews fix (SCRUM related)

reordered Item_row class variables to be sorted by memory size
parent 7c0a0746
......@@ -39,9 +39,8 @@ Reference 'a' not supported (forward reference in item list)
EXPLAIN SELECT 1 FROM (SELECT 1 as a) as b HAVING (SELECT a)=1;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> system NULL NULL NULL NULL 1
3 DEPENDENT SUBSELECT NULL NULL NULL NULL NULL NULL NULL No tables used
2 DERIVED NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
Note 1247 Select 3 was reduced during optimisation
SELECT 1 FROM (SELECT 1 as a) as b HAVING (SELECT a)=1;
1
1
......
......@@ -1289,9 +1289,10 @@ bool Item_cache_row::setup(Item * item)
return 1;
for (uint i= 0; i < item_count; i++)
{
if (!(values[i]= Item_cache::get_cache(item->el(i)->result_type())))
Item *el= item->el(i);
if (!(values[i]= Item_cache::get_cache(el->result_type())))
return 1;
values[i]->setup(item->el(i));
values[i]->setup(el);
}
return 0;
}
......
......@@ -515,6 +515,10 @@ class Item_ref_null_helper: public Item_ref
/*
Used to find item in list of select items after '*' items processing.
Because item '*' can be used in item list. when we create
Item_ref_on_list_position we do not know how item list will be changed, but
we know number of item position (I mean queries like "select * from t").
*/
class Item_ref_on_list_position: public Item_ref_null_helper
{
......
......@@ -97,6 +97,13 @@ class Item_in_optimizer: public Item_bool_func
bool preallocate_row();
bool fix_fields(THD *, struct st_table_list *, Item **);
bool is_null();
/*
Item_in_optimizer item is special boolean function. On value request
(one of val, val_int or val_str methods) it evaluate left expression
of IN by storing it value in cache item (one of Item_cache* items),
then it test cache is it NULL. If left expression (cache) is NULL then
Item_in_optimizer return NULL, else it evaluate Item_in_subselect.
*/
longlong val_int();
Item_cache **get_cache() { return &cache; }
......@@ -546,8 +553,10 @@ class cmp_item_row :public cmp_item
{
if (comparators)
for (uint i= 0; i < n; i++)
{
if (comparators[i])
delete comparators[i];
}
}
void store_value(Item *item);
int cmp(Item *arg);
......
......@@ -54,7 +54,14 @@ bool Item_row::fix_fields(THD *thd, TABLE_LIST *tabl, Item **ref)
if (items[i]->fix_fields(thd, tabl, items+i))
return 1;
used_tables_cache |= items[i]->used_tables();
const_item_cache&= items[i]->const_item();
if (const_item_cache&= items[i]->const_item() && !with_null)
if (items[i]->cols() > 1)
with_null|= items[i]->null_inside();
else
{
items[i]->val_int();
with_null|= items[i]->null_value;
}
maybe_null|= items[i]->maybe_null;
}
return 0;
......@@ -82,25 +89,6 @@ bool Item_row::check_cols(uint c)
return 0;
}
bool Item_row::null_inside()
{
for (uint i= 0; i < arg_count; i++)
{
if (items[i]->cols() > 1)
{
if (items[i]->null_inside())
return 1;
}
else
{
items[i]->val_int();
if (items[i]->null_value)
return 1;
}
}
return 0;
}
void Item_row::bring_value()
{
for (uint i= 0; i < arg_count; i++)
......
......@@ -16,19 +16,22 @@
class Item_row: public Item
{
bool array_holder;
Item **items;
table_map used_tables_cache;
bool const_item_cache;
uint arg_count;
Item **items;
bool array_holder;
bool const_item_cache;
bool with_null;
public:
Item_row(List<Item> &);
Item_row(Item_row *item):
Item(), array_holder(0),
Item(),
items(item->items),
used_tables_cache(item->used_tables_cache),
const_item_cache(item->const_item_cache),
arg_count(item->arg_count),
items(item->items)
array_holder(0),
const_item_cache(item->const_item_cache),
with_null(0)
{}
~Item_row()
......@@ -71,6 +74,6 @@ class Item_row: public Item
Item* el(uint i) { return items[i]; }
Item** addr(uint i) { return items + i; }
bool check_cols(uint c);
bool null_inside();
bool null_inside() { return with_null; };
void bring_value();
};
......@@ -1961,7 +1961,8 @@ String *Item_func_conv_charset::val_str(String *str)
d0=d=(unsigned char*)str->ptr();
de=d+dmaxlen;
while (s < se && d < de){
while (s < se && d < de)
{
cnvres=from->mb_wc(from,&wc,s,se);
if (cnvres>0)
......
......@@ -157,7 +157,11 @@ void Item_singlerow_subselect::select_transformer(THD *thd,
SELECT_LEX *select_lex= unit->first_select();
if (!select_lex->next_select() && !select_lex->table_list.elements &&
select_lex->item_list.elements == 1)
select_lex->item_list.elements == 1 &&
// TODO: mark subselect items from item list separately
!(select_lex->item_list.head()->type() == FIELD_ITEM ||
select_lex->item_list.head()->type() == REF_ITEM)
)
{
have_to_be_excluded= 1;
......@@ -170,9 +174,6 @@ void Item_singlerow_subselect::select_transformer(THD *thd,
}
substitution= select_lex->item_list.head();
substitution->set_outer_resolving();
if (substitution->type() == FIELD_ITEM ||
substitution->type() == REF_ITEM)
name= substitution->name; // Save name for correct resolving
if (select_lex->where || select_lex->having)
{
......@@ -444,6 +445,9 @@ void Item_in_subselect::single_value_transformer(THD *thd,
"LIMIT & IN/ALL/ANY/SOME subquery");
DBUG_VOID_RETURN;
}
// no sense in ORDER BY without LIMIT
unit->global_parameters->order_list.empty();
Item_in_optimizer *optimizer;
substitution= optimizer= new Item_in_optimizer(left_expr, this);
if (!optimizer)
......@@ -476,18 +480,16 @@ void Item_in_subselect::single_value_transformer(THD *thd,
else
item= (Item*) sl->item_list.pop();
if (sl->having || sl->with_sum_func || sl->group_list.first ||
sl->order_list.first)
sl->order_list.empty(); // no sense in ORDER BY without LIMIT
if (sl->having || sl->with_sum_func || sl->group_list.first)
{
sl->item_list.push_back(item);
item= (*func)(expr, new Item_ref_null_helper(this,
sl->item_list.head_ref(),
(char *)"<no matter>",
(char*)"<result>"));
if (sl->having || sl->with_sum_func || sl->group_list.first)
sl->having= and_items(sl->having, item);
else
sl->where= and_items(sl->where, item);
sl->having= and_items(sl->having, item);
}
else
{
......@@ -547,10 +549,22 @@ void Item_in_subselect::row_value_transformer(THD *thd,
if (unit->global_parameters->select_limit !=
HA_POS_ERROR)
{
/*
Because we do the following (not exactly, following is just explenation)
transformation
SELECT * from t1 WHERE t1.a IN (SELECT t2.a FROM t2)
->
SELECT * from t1 WHERE EXISTS(SELECT 1 FROM t2 t1.a = t2.a LIMIT 1)
it's impossible to support limit in the sub select.
*/
my_error(ER_NOT_SUPPORTED_YET, MYF(0),
"LIMIT & IN/ALL/ANY/SOME subquery");
DBUG_VOID_RETURN;
}
// no sense in ORDER BY without LIMIT
unit->global_parameters->order_list.empty();
Item_in_optimizer *optimizer;
substitution= optimizer= new Item_in_optimizer(left_expr, this);
if (!optimizer)
......@@ -568,6 +582,7 @@ void Item_in_subselect::row_value_transformer(THD *thd,
"LIMIT & IN/ALL/ANY/SOME subquery");
DBUG_VOID_RETURN;
}
sl->order_list.empty(); // no sense in ORDER BY without LIMIT
sl->dependent= 1;
......@@ -589,7 +604,7 @@ void Item_in_subselect::row_value_transformer(THD *thd,
}
if (sl->having || sl->with_sum_func || sl->group_list.first ||
!sl->table_list.elements)
!sl->table_list.elements || !sl->table_list.elements)
sl->having= and_items(sl->having, item);
else
sl->where= and_items(sl->where, item);
......
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