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) ...@@ -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; 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 id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> system NULL NULL NULL NULL 1 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 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; SELECT 1 FROM (SELECT 1 as a) as b HAVING (SELECT a)=1;
1 1
1 1
......
...@@ -1289,9 +1289,10 @@ bool Item_cache_row::setup(Item * item) ...@@ -1289,9 +1289,10 @@ bool Item_cache_row::setup(Item * item)
return 1; return 1;
for (uint i= 0; i < item_count; i++) 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; return 1;
values[i]->setup(item->el(i)); values[i]->setup(el);
} }
return 0; return 0;
} }
......
...@@ -515,6 +515,10 @@ class Item_ref_null_helper: public Item_ref ...@@ -515,6 +515,10 @@ class Item_ref_null_helper: public Item_ref
/* /*
Used to find item in list of select items after '*' items processing. 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 class Item_ref_on_list_position: public Item_ref_null_helper
{ {
......
...@@ -97,6 +97,13 @@ class Item_in_optimizer: public Item_bool_func ...@@ -97,6 +97,13 @@ class Item_in_optimizer: public Item_bool_func
bool preallocate_row(); bool preallocate_row();
bool fix_fields(THD *, struct st_table_list *, Item **); bool fix_fields(THD *, struct st_table_list *, Item **);
bool is_null(); 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(); longlong val_int();
Item_cache **get_cache() { return &cache; } Item_cache **get_cache() { return &cache; }
...@@ -546,8 +553,10 @@ class cmp_item_row :public cmp_item ...@@ -546,8 +553,10 @@ class cmp_item_row :public cmp_item
{ {
if (comparators) if (comparators)
for (uint i= 0; i < n; i++) for (uint i= 0; i < n; i++)
{
if (comparators[i]) if (comparators[i])
delete comparators[i]; delete comparators[i];
}
} }
void store_value(Item *item); void store_value(Item *item);
int cmp(Item *arg); int cmp(Item *arg);
......
...@@ -54,7 +54,14 @@ bool Item_row::fix_fields(THD *thd, TABLE_LIST *tabl, Item **ref) ...@@ -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)) if (items[i]->fix_fields(thd, tabl, items+i))
return 1; return 1;
used_tables_cache |= items[i]->used_tables(); 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; maybe_null|= items[i]->maybe_null;
} }
return 0; return 0;
...@@ -82,25 +89,6 @@ bool Item_row::check_cols(uint c) ...@@ -82,25 +89,6 @@ bool Item_row::check_cols(uint c)
return 0; 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() void Item_row::bring_value()
{ {
for (uint i= 0; i < arg_count; i++) for (uint i= 0; i < arg_count; i++)
......
...@@ -16,19 +16,22 @@ ...@@ -16,19 +16,22 @@
class Item_row: public Item class Item_row: public Item
{ {
bool array_holder; Item **items;
table_map used_tables_cache; table_map used_tables_cache;
bool const_item_cache;
uint arg_count; uint arg_count;
Item **items; bool array_holder;
bool const_item_cache;
bool with_null;
public: public:
Item_row(List<Item> &); Item_row(List<Item> &);
Item_row(Item_row *item): Item_row(Item_row *item):
Item(), array_holder(0), Item(),
items(item->items),
used_tables_cache(item->used_tables_cache), used_tables_cache(item->used_tables_cache),
const_item_cache(item->const_item_cache),
arg_count(item->arg_count), arg_count(item->arg_count),
items(item->items) array_holder(0),
const_item_cache(item->const_item_cache),
with_null(0)
{} {}
~Item_row() ~Item_row()
...@@ -71,6 +74,6 @@ class Item_row: public Item ...@@ -71,6 +74,6 @@ class Item_row: public Item
Item* el(uint i) { return items[i]; } Item* el(uint i) { return items[i]; }
Item** addr(uint i) { return items + i; } Item** addr(uint i) { return items + i; }
bool check_cols(uint c); bool check_cols(uint c);
bool null_inside(); bool null_inside() { return with_null; };
void bring_value(); void bring_value();
}; };
...@@ -1961,7 +1961,8 @@ String *Item_func_conv_charset::val_str(String *str) ...@@ -1961,7 +1961,8 @@ String *Item_func_conv_charset::val_str(String *str)
d0=d=(unsigned char*)str->ptr(); d0=d=(unsigned char*)str->ptr();
de=d+dmaxlen; de=d+dmaxlen;
while (s < se && d < de){ while (s < se && d < de)
{
cnvres=from->mb_wc(from,&wc,s,se); cnvres=from->mb_wc(from,&wc,s,se);
if (cnvres>0) if (cnvres>0)
......
...@@ -157,7 +157,11 @@ void Item_singlerow_subselect::select_transformer(THD *thd, ...@@ -157,7 +157,11 @@ void Item_singlerow_subselect::select_transformer(THD *thd,
SELECT_LEX *select_lex= unit->first_select(); SELECT_LEX *select_lex= unit->first_select();
if (!select_lex->next_select() && !select_lex->table_list.elements && 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; have_to_be_excluded= 1;
...@@ -170,9 +174,6 @@ void Item_singlerow_subselect::select_transformer(THD *thd, ...@@ -170,9 +174,6 @@ void Item_singlerow_subselect::select_transformer(THD *thd,
} }
substitution= select_lex->item_list.head(); substitution= select_lex->item_list.head();
substitution->set_outer_resolving(); 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) if (select_lex->where || select_lex->having)
{ {
...@@ -444,6 +445,9 @@ void Item_in_subselect::single_value_transformer(THD *thd, ...@@ -444,6 +445,9 @@ void Item_in_subselect::single_value_transformer(THD *thd,
"LIMIT & IN/ALL/ANY/SOME subquery"); "LIMIT & IN/ALL/ANY/SOME subquery");
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
// no sense in ORDER BY without LIMIT
unit->global_parameters->order_list.empty();
Item_in_optimizer *optimizer; Item_in_optimizer *optimizer;
substitution= optimizer= new Item_in_optimizer(left_expr, this); substitution= optimizer= new Item_in_optimizer(left_expr, this);
if (!optimizer) if (!optimizer)
...@@ -476,18 +480,16 @@ void Item_in_subselect::single_value_transformer(THD *thd, ...@@ -476,18 +480,16 @@ void Item_in_subselect::single_value_transformer(THD *thd,
else else
item= (Item*) sl->item_list.pop(); item= (Item*) sl->item_list.pop();
if (sl->having || sl->with_sum_func || sl->group_list.first || sl->order_list.empty(); // no sense in ORDER BY without LIMIT
sl->order_list.first)
if (sl->having || sl->with_sum_func || sl->group_list.first)
{ {
sl->item_list.push_back(item); sl->item_list.push_back(item);
item= (*func)(expr, new Item_ref_null_helper(this, item= (*func)(expr, new Item_ref_null_helper(this,
sl->item_list.head_ref(), sl->item_list.head_ref(),
(char *)"<no matter>", (char *)"<no matter>",
(char*)"<result>")); (char*)"<result>"));
if (sl->having || sl->with_sum_func || sl->group_list.first) sl->having= and_items(sl->having, item);
sl->having= and_items(sl->having, item);
else
sl->where= and_items(sl->where, item);
} }
else else
{ {
...@@ -547,10 +549,22 @@ void Item_in_subselect::row_value_transformer(THD *thd, ...@@ -547,10 +549,22 @@ void Item_in_subselect::row_value_transformer(THD *thd,
if (unit->global_parameters->select_limit != if (unit->global_parameters->select_limit !=
HA_POS_ERROR) 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), my_error(ER_NOT_SUPPORTED_YET, MYF(0),
"LIMIT & IN/ALL/ANY/SOME subquery"); "LIMIT & IN/ALL/ANY/SOME subquery");
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
// no sense in ORDER BY without LIMIT
unit->global_parameters->order_list.empty();
Item_in_optimizer *optimizer; Item_in_optimizer *optimizer;
substitution= optimizer= new Item_in_optimizer(left_expr, this); substitution= optimizer= new Item_in_optimizer(left_expr, this);
if (!optimizer) if (!optimizer)
...@@ -568,6 +582,7 @@ void Item_in_subselect::row_value_transformer(THD *thd, ...@@ -568,6 +582,7 @@ void Item_in_subselect::row_value_transformer(THD *thd,
"LIMIT & IN/ALL/ANY/SOME subquery"); "LIMIT & IN/ALL/ANY/SOME subquery");
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
sl->order_list.empty(); // no sense in ORDER BY without LIMIT
sl->dependent= 1; sl->dependent= 1;
...@@ -589,7 +604,7 @@ void Item_in_subselect::row_value_transformer(THD *thd, ...@@ -589,7 +604,7 @@ void Item_in_subselect::row_value_transformer(THD *thd,
} }
if (sl->having || sl->with_sum_func || sl->group_list.first || 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); sl->having= and_items(sl->having, item);
else else
sl->where= and_items(sl->where, item); 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