summaryrefslogtreecommitdiff
path: root/sql/sql_tvc.cc
diff options
context:
space:
mode:
authorGalina Shalygina <galashalygina@gmail.com>2017-09-01 19:01:06 +0200
committerGalina Shalygina <galashalygina@gmail.com>2017-09-01 19:01:06 +0200
commite70177074986d5ac1f9674d2869b9d69c83c377d (patch)
tree6992200fbd25e228e074b864c7478173e0fc7105 /sql/sql_tvc.cc
parent1efa9ed8cafc48950f16593ae1d3d9850d7ae1f5 (diff)
downloadmariadb-git-e70177074986d5ac1f9674d2869b9d69c83c377d.tar.gz
Memory allocation corrected. New tests added.
Diffstat (limited to 'sql/sql_tvc.cc')
-rw-r--r--sql/sql_tvc.cc156
1 files changed, 68 insertions, 88 deletions
diff --git a/sql/sql_tvc.cc b/sql/sql_tvc.cc
index 263dc24a9b0..b9fd5e2e5cd 100644
--- a/sql/sql_tvc.cc
+++ b/sql/sql_tvc.cc
@@ -374,10 +374,10 @@ void table_value_constr::print(THD *thd_arg, String *str,
/**
@brief
- Creates new SELECT defined by TVC as derived table
+ Transforms IN-predicate in IN-subselect
@param thd_arg The context of the statement
- @param values List of values that defines TVC
+ @param arg Argument is 0 in this context
@details
The method creates this SELECT statement:
@@ -386,31 +386,64 @@ void table_value_constr::print(THD *thd_arg, String *str,
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.
+ was at the beginning of the procedure.
@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)
+Item *Item_func_in::in_predicate_to_in_subs_transformer(THD *thd,
+ uchar *arg)
{
- LEX *lex= thd_arg->lex;
+ 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_arg->activate_stmt_arena_if_needed(&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)
+ list_of_lists= true;
+
+ for (uint i=1; i < arg_count; i++)
+ {
+ List<Item> *new_value= new (thd->mem_root) List<Item>();
+
+ if (list_of_lists)
+ {
+ Item_row *in_list= (Item_row *)(args[i]);
+
+ for (uint j=0; j < in_list->cols(); i++)
+ new_value->push_back(in_list->element_index(j), thd->mem_root);
+ }
+ else
+ new_value->push_back(args[i]);
+
+ values.push_back(new_value, thd->mem_root);
+ }
+
+ /*
+ Creation of TVC name
+ */
alias.length= my_snprintf(buff, sizeof(buff),
- "tvc_%u", thd_arg->lex->current_select->cur_tvc);
- alias.str= thd_arg->strmake(buff, alias.length);
+ "tvc_%u", old_select->cur_tvc);
+ alias.str= thd->strmake(buff, alias.length);
if (!alias.str)
goto err;
@@ -424,12 +457,11 @@ st_select_lex *make_new_subselect_for_tvc(THD *thd_arg,
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);
+ 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_arg, item))
+ if (add_item_to_list(thd, item))
goto err;
(lex->current_select->with_wild)++;
@@ -448,8 +480,8 @@ st_select_lex *make_new_subselect_for_tvc(THD *thd_arg,
sel->linkage= DERIVED_TABLE_TYPE;
if (!(sel->tvc=
- new (thd_arg->mem_root)
- table_value_constr(*values,
+ new (thd->mem_root)
+ table_value_constr(values,
sel,
sel->options)))
goto err;
@@ -457,11 +489,11 @@ st_select_lex *make_new_subselect_for_tvc(THD *thd_arg,
lex->check_automatic_up(UNSPECIFIED_TYPE);
lex->current_select= sel= unit->outer_select();
- ti= new (thd_arg->mem_root) Table_ident(unit);
+ ti= new (thd->mem_root) Table_ident(unit);
if (ti == NULL)
goto err;
- if (!(new_tab= sel->add_table_to_list(thd_arg,
+ if (!(new_tab= sel->add_table_to_list(thd,
ti, &alias, 0,
TL_READ, MDL_SHARED_READ)))
goto err;
@@ -478,83 +510,28 @@ st_select_lex *make_new_subselect_for_tvc(THD *thd_arg,
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
-
- @param thd_arg The context of the statement
- @param arg Argument is 0 in this context
-
- @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 procedure.
-
- @retval
- pointer to the created SELECT statement
- NULL - if creation was unsuccesfull
-*/
-
-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;
- bool list_of_lists= false;
-
- if (args[1]->type() == Item::ROW_ITEM)
- list_of_lists= true;
+ if (!sel)
+ goto err;
- for (uint i=1; i < arg_count; i++)
- {
- List<Item> *new_value= new (thd->mem_root) List<Item>();
+ sel->parsing_place= old_select->parsing_place;
+ sel->table_list.first->derived_type= 10;
- if (list_of_lists)
- {
- Item_row *in_list= (Item_row *)(args[i]);
+ 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;
- for (uint j=0; j < in_list->cols(); i++)
- new_value->push_back(in_list->element_index(j), thd->mem_root);
- }
- else
- new_value->push_back(args[i]);
+ old_select->cur_tvc++;
+ thd->lex->current_select= old_select;
- values.push_back(new_value, thd->mem_root);
- }
+ if (arena)
+ thd->restore_active_arena(arena, &backup);
- st_select_lex *new_subselect=
- make_new_subselect_for_tvc(thd, &values);
+ in_subs->fix_fields(thd, (Item **)&in_subs);
+ return in_subs;
- if (new_subselect)
- {
- 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
- (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);
-
- old_select->cur_tvc++;
- thd->lex->current_select= old_select;
- return in_subs;
- }
-
- thd->lex->current_select= old_select;
+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;