1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-01 03:47:19 +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

@ -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
Transforms IN-predicate in IN-subselect
@ -512,7 +397,25 @@ Item *Item_func_in::in_predicate_to_in_subs_transformer(THD *thd,
uchar *arg)
{
SELECT_LEX *old_select= thd->lex->current_select;
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;
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);
}
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)
{
new_subselect->parsing_place= old_select->parsing_place;
new_subselect->table_list.first->derived_type= 10;
/*
Creation of SELECT statement: SELECT * FROM ...
*/
Item_in_subselect *in_subs= new (thd->mem_root) Item_in_subselect
(thd, args[0], new_subselect);
thd->lex->derived_tables |= DERIVED_SUBQUERY;
in_subs->emb_on_expr_nest= emb_on_expr_nest;
in_subs->fix_fields(thd, (Item **)&in_subs);
if (mysql_new_select(lex, 1, NULL))
goto err;
old_select->cur_tvc++;
thd->lex->current_select= old_select;
return in_subs;
}
mysql_init_select(lex);
lex->current_select->parsing_place= SELECT_LIST;
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;
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;
}
@ -633,9 +610,12 @@ bool JOIN::transform_in_predicate_into_tvc(THD *thd_arg)
table->on_expr->transform(thd_arg,
&Item::in_predicate_to_in_subs_transformer,
(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;
thd_arg->lex->current_select= old_select;
return false;