mirror of
https://github.com/MariaDB/server.git
synced 2025-12-24 11:21:21 +03:00
postreviews fix (SCRUM related)
reordered Item_row class variables to be sorted by memory size mysql-test/r/subselect.result: fix result of subselect test sql/item.cc: postreviews fix sql/item.h: postreviews fix sql/item_cmpfunc.h: postreviews fix sql/item_row.cc: postreviews fix sql/item_row.h: reordered class variables to be sorted by memory size postreviews fix sql/item_strfunc.cc: postreviews fix sql/item_subselect.cc: postreviews fix
This commit is contained in:
@@ -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 @@ public:
|
||||
|
||||
/*
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
{
|
||||
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;
|
||||
table_map used_tables_cache;
|
||||
bool const_item_cache;
|
||||
uint arg_count;
|
||||
Item **items;
|
||||
table_map used_tables_cache;
|
||||
uint arg_count;
|
||||
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 @@ public:
|
||||
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);
|
||||
|
||||
Reference in New Issue
Block a user