diff options
Diffstat (limited to 'sql/sql_tvc.cc')
-rw-r--r-- | sql/sql_tvc.cc | 156 |
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; |