1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-07 00:04:31 +03:00

Memory allocation corrected. New tests added.

This commit is contained in:
Galina Shalygina
2017-09-01 19:01:06 +02:00
parent 1efa9ed8ca
commit e701770749
3 changed files with 130 additions and 130 deletions

View File

@@ -468,5 +468,18 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
4 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used 4 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings: Warnings:
Note 1003 /* select#1 */ select `dr_table`.`max(a)` AS `max(a)`,`dr_table`.`b` AS `b` from (/* select#2 */ select max(`test`.`t1`.`a`) AS `max(a)`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join ((values (3),(5)) `tvc_0`) where 1 group by `test`.`t1`.`b`) `dr_table` Note 1003 /* select#1 */ select `dr_table`.`max(a)` AS `max(a)`,`dr_table`.`b` AS `b` from (/* select#2 */ select max(`test`.`t1`.`a`) AS `max(a)`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join ((values (3),(5)) `tvc_0`) where 1 group by `test`.`t1`.`b`) `dr_table`
# prepare statement
prepare stmt from "select * from t1 where a in (1,2)";
execute stmt;
a b
1 2
1 1
2 5
execute stmt;
a b
1 2
1 1
2 5
deallocate prepare stmt;
drop table t1, t2; drop table t1, t2;
set @@in_subquery_conversion_threshold= default; set @@in_subquery_conversion_threshold= default;

View File

@@ -4330,9 +4330,16 @@ longlong Item_func_in::val_int()
void Item_func_in::mark_as_condition_AND_part(TABLE_LIST *embedding) void Item_func_in::mark_as_condition_AND_part(TABLE_LIST *embedding)
{ {
THD *thd= current_thd; THD *thd= current_thd;
Query_arena *arena, backup;
arena= thd->activate_stmt_arena_if_needed(&backup);
if (can_be_transformed_in_tvc(thd)) if (can_be_transformed_in_tvc(thd))
thd->lex->current_select->in_funcs.push_back(this, thd->mem_root); thd->lex->current_select->in_funcs.push_back(this, thd->mem_root);
if (arena)
thd->restore_active_arena(arena, &backup);
emb_on_expr_nest= embedding; emb_on_expr_nest= embedding;
} }

View File

@@ -372,121 +372,6 @@ void table_value_constr::print(THD *thd_arg, String *str,
} }
/**
@brief
Creates new SELECT defined by TVC as derived table
@param thd_arg The context of the statement
@param values List of values that defines TVC
@details
The method creates this SELECT statement:
SELECT * FROM (VALUES values) AS new_tvc
If during creation of SELECT statement some action is
unsuccesfull backup is made to the state in which system
was at the beginning of the method.
@retval
pointer to the created SELECT statement
NULL - if creation was unsuccesfull
*/
st_select_lex *make_new_subselect_for_tvc(THD *thd_arg,
List<List_item> *values)
{
LEX *lex= thd_arg->lex;
Item *item;
SELECT_LEX *sel;
SELECT_LEX_UNIT *unit;
TABLE_LIST *new_tab;
Table_ident *ti;
Query_arena backup;
Query_arena *arena= thd_arg->activate_stmt_arena_if_needed(&backup);
char buff[6];
LEX_CSTRING alias;
alias.length= my_snprintf(buff, sizeof(buff),
"tvc_%u", thd_arg->lex->current_select->cur_tvc);
alias.str= thd_arg->strmake(buff, alias.length);
if (!alias.str)
goto err;
/*
Creation of SELECT statement: SELECT * FROM ...
*/
if (mysql_new_select(lex, 1, NULL))
goto err;
mysql_init_select(lex);
lex->current_select->parsing_place= SELECT_LIST;
item= new (thd_arg->mem_root)
Item_field(thd_arg, &lex->current_select->context,
NULL, NULL, &star_clex_str);
if (item == NULL)
goto err;
if (add_item_to_list(thd_arg, item))
goto err;
(lex->current_select->with_wild)++;
/*
Creation of TVC as derived table
*/
lex->derived_tables|= DERIVED_SUBQUERY;
if (mysql_new_select(lex, 1, NULL))
goto err;
mysql_init_select(lex);
sel= lex->current_select;
unit= sel->master_unit();
sel->linkage= DERIVED_TABLE_TYPE;
if (!(sel->tvc=
new (thd_arg->mem_root)
table_value_constr(*values,
sel,
sel->options)))
goto err;
lex->check_automatic_up(UNSPECIFIED_TYPE);
lex->current_select= sel= unit->outer_select();
ti= new (thd_arg->mem_root) Table_ident(unit);
if (ti == NULL)
goto err;
if (!(new_tab= sel->add_table_to_list(thd_arg,
ti, &alias, 0,
TL_READ, MDL_SHARED_READ)))
goto err;
sel->add_joined_table(new_tab);
new_tab->select_lex->add_where_field(new_tab->derived->first_select());
sel->context.table_list=
sel->context.first_name_resolution_table=
sel->table_list.first;
sel->where= 0;
sel->set_braces(false);
unit->with_clause= 0;
return sel;
err:
if (arena)
thd_arg->restore_active_arena(arena, &backup);
return NULL;
}
/** /**
@brief @brief
Transforms IN-predicate in IN-subselect Transforms IN-predicate in IN-subselect
@@ -512,7 +397,25 @@ Item *Item_func_in::in_predicate_to_in_subs_transformer(THD *thd,
uchar *arg) uchar *arg)
{ {
SELECT_LEX *old_select= thd->lex->current_select; SELECT_LEX *old_select= thd->lex->current_select;
List<List_item> values; List<List_item> values;
Item *item;
SELECT_LEX *sel;
SELECT_LEX_UNIT *unit;
TABLE_LIST *new_tab;
Table_ident *ti;
Item_in_subselect *in_subs;
Query_arena backup;
Query_arena *arena= thd->activate_stmt_arena_if_needed(&backup);
LEX *lex= thd->lex;
char buff[6];
LEX_CSTRING alias;
/*
Creation of values list of lists
*/
bool list_of_lists= false; bool list_of_lists= false;
if (args[1]->type() == Item::ROW_ITEM) if (args[1]->type() == Item::ROW_ITEM)
@@ -535,26 +438,100 @@ Item *Item_func_in::in_predicate_to_in_subs_transformer(THD *thd,
values.push_back(new_value, thd->mem_root); values.push_back(new_value, thd->mem_root);
} }
st_select_lex *new_subselect= /*
make_new_subselect_for_tvc(thd, &values); Creation of TVC name
*/
alias.length= my_snprintf(buff, sizeof(buff),
"tvc_%u", old_select->cur_tvc);
alias.str= thd->strmake(buff, alias.length);
if (!alias.str)
goto err;
if (new_subselect) /*
{ Creation of SELECT statement: SELECT * FROM ...
new_subselect->parsing_place= old_select->parsing_place; */
new_subselect->table_list.first->derived_type= 10;
Item_in_subselect *in_subs= new (thd->mem_root) Item_in_subselect if (mysql_new_select(lex, 1, NULL))
(thd, args[0], new_subselect); goto err;
thd->lex->derived_tables |= DERIVED_SUBQUERY;
in_subs->emb_on_expr_nest= emb_on_expr_nest;
in_subs->fix_fields(thd, (Item **)&in_subs);
old_select->cur_tvc++; mysql_init_select(lex);
thd->lex->current_select= old_select; lex->current_select->parsing_place= SELECT_LIST;
return in_subs;
}
item= new (thd->mem_root) Item_field(thd, &lex->current_select->context,
NULL, NULL, &star_clex_str);
if (item == NULL)
goto err;
if (add_item_to_list(thd, item))
goto err;
(lex->current_select->with_wild)++;
/*
Creation of TVC as derived table
*/
lex->derived_tables|= DERIVED_SUBQUERY;
if (mysql_new_select(lex, 1, NULL))
goto err;
mysql_init_select(lex);
sel= lex->current_select;
unit= sel->master_unit();
sel->linkage= DERIVED_TABLE_TYPE;
if (!(sel->tvc=
new (thd->mem_root)
table_value_constr(values,
sel,
sel->options)))
goto err;
lex->check_automatic_up(UNSPECIFIED_TYPE);
lex->current_select= sel= unit->outer_select();
ti= new (thd->mem_root) Table_ident(unit);
if (ti == NULL)
goto err;
if (!(new_tab= sel->add_table_to_list(thd,
ti, &alias, 0,
TL_READ, MDL_SHARED_READ)))
goto err;
sel->add_joined_table(new_tab);
new_tab->select_lex->add_where_field(new_tab->derived->first_select());
sel->context.table_list=
sel->context.first_name_resolution_table=
sel->table_list.first;
sel->where= 0;
sel->set_braces(false);
unit->with_clause= 0;
if (!sel)
goto err;
sel->parsing_place= old_select->parsing_place;
sel->table_list.first->derived_type= 10;
in_subs= new (thd->mem_root) Item_in_subselect(thd, args[0], sel);
thd->lex->derived_tables |= DERIVED_SUBQUERY;
in_subs->emb_on_expr_nest= emb_on_expr_nest;
old_select->cur_tvc++;
thd->lex->current_select= old_select; thd->lex->current_select= old_select;
if (arena)
thd->restore_active_arena(arena, &backup);
in_subs->fix_fields(thd, (Item **)&in_subs);
return in_subs;
err:
if (arena)
thd->restore_active_arena(arena, &backup);
return this; return this;
} }
@@ -633,9 +610,12 @@ bool JOIN::transform_in_predicate_into_tvc(THD *thd_arg)
table->on_expr->transform(thd_arg, table->on_expr->transform(thd_arg,
&Item::in_predicate_to_in_subs_transformer, &Item::in_predicate_to_in_subs_transformer,
(uchar*) 0); (uchar*) 0);
table->prep_on_expr= table->on_expr ?
table->on_expr->copy_andor_structure(thd) : 0;
} }
} }
} }
select_lex->in_funcs.empty();
select_lex->parsing_place= old_parsing_place; select_lex->parsing_place= old_parsing_place;
thd_arg->lex->current_select= old_select; thd_arg->lex->current_select= old_select;
return false; return false;