diff options
-rw-r--r-- | sql/sql_select.cc | 22 | ||||
-rw-r--r-- | sql/sql_select.h | 81 | ||||
-rw-r--r-- | sql/sql_union.cc | 28 |
3 files changed, 93 insertions, 38 deletions
diff --git a/sql/sql_select.cc b/sql/sql_select.cc index e8f51104bcf..a9810de97a6 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1381,12 +1381,24 @@ mysql_select(THD *thd, Item ***rref_pointer_array, JOIN *join; if (select_lex->join != 0) { - //here is EXPLAIN of subselect or derived table join= select_lex->join; - join->result= result; - if (!join->procedure && result->prepare(join->fields_list, unit)) + if (select_lex->linkage != GLOBAL_OPTIONS_TYPE) { - DBUG_RETURN(-1); + //here is EXPLAIN of subselect or derived table + join->result= result; + if (!join->procedure && result->prepare(join->fields_list, unit)) + { + DBUG_RETURN(-1); + } + } + else + { + if (join->prepare(rref_pointer_array, tables, wild_num, + conds, og_num, order, group, having, proc_param, + select_lex, unit, tables_and_fields_initied)) + { + DBUG_RETURN(-1); + } } join->select_options= select_options; free_join= 0; @@ -1396,7 +1408,6 @@ mysql_select(THD *thd, Item ***rref_pointer_array, join= new JOIN(thd, fields, select_options, result); thd->proc_info="init"; thd->used_tables=0; // Updated by setup_fields - if (join->prepare(rref_pointer_array, tables, wild_num, conds, og_num, order, group, having, proc_param, select_lex, unit, tables_and_fields_initied)) @@ -4300,6 +4311,7 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type, default: // This case should never be choosen DBUG_ASSERT(0); + new_field= 0; // to satisfy compiler (uninitialized variable) break; } if (copy_func && item->is_result_field()) diff --git a/sql/sql_select.h b/sql/sql_select.h index f29729fb5b3..a4554183312 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -190,45 +190,62 @@ class JOIN :public Sql_alloc bool optimized; // flag to avoid double optimization in EXPLAIN JOIN(THD *thd_arg, List<Item> &fields, ulong select_options_arg, - select_result *result_arg): - join_tab(0), - table(0), - tables(0), const_tables(0), - sort_and_group(0), first_record(0), - do_send_rows(1), - send_records(0), found_records(0), examined_rows(0), - exec_tmp_table1(0), exec_tmp_table2(0), - thd(thd_arg), - sum_funcs(0), - procedure(0), - having(0), tmp_having(0), - select_options(select_options_arg), - result(result_arg), - lock(thd_arg->lock), - select_lex(0), //for safety - tmp_join(0), - select_distinct(test(select_options & SELECT_DISTINCT)), - no_order(0), simple_order(0), simple_group(0), skip_sort_order(0), - need_tmp(0), - hidden_group_fields (0), /*safety*/ - buffer_result(test(select_options & OPTION_BUFFER_RESULT) && - !test(select_options & OPTION_FOUND_ROWS)), - all_fields(fields), - fields_list(fields), - error(0), - select(0), - ref_pointer_array(0), items0(0), items1(0), items2(0), items3(0), - ref_pointer_array_size(0), - zero_result_cause(0), - optimized(0) + select_result *result_arg) + :fields_list(fields) { + init(thd_arg, fields, select_options_arg, result_arg); + } + + void init(THD *thd_arg, List<Item> &fields, ulong select_options_arg, + select_result *result_arg) + { + join_tab= 0; + table= 0; + tables= 0; + const_tables= 0; + sort_and_group= 0; + first_record= 0; + do_send_rows= 1; + send_records= 0; + found_records= 0; + examined_rows= 0; + exec_tmp_table1= 0; + exec_tmp_table2= 0; + thd= thd_arg; + sum_funcs= 0; + procedure= 0; + having= 0; + tmp_having= 0; + select_options= select_options_arg; + result= result_arg; + lock= thd_arg->lock; + select_lex= 0; //for safety + tmp_join= 0; + select_distinct= test(select_options & SELECT_DISTINCT); + no_order= 0; + simple_order= 0; + simple_group= 0; + skip_sort_order= 0; + need_tmp= 0; + hidden_group_fields= 0; /*safety*/ + buffer_result= test(select_options & OPTION_BUFFER_RESULT) && + !test(select_options & OPTION_FOUND_ROWS); + all_fields= fields; + fields_list= fields; + error= 0; + select= 0; + ref_pointer_array= items0= items1= items2= items3= 0; + ref_pointer_array_size= 0; + zero_result_cause= 0; + optimized= 0; + fields_list = fields; bzero((char*) &keyuse,sizeof(keyuse)); tmp_table_param.copy_field=0; tmp_table_param.end_write_records= HA_POS_ERROR; rollup.state= ROLLUP::STATE_NONE; } - + int prepare(Item ***rref_pointer_array, TABLE_LIST *tables, uint wind_num, COND *conds, uint og_num, ORDER *order, ORDER *group, Item *having, ORDER *proc_param, SELECT_LEX *select, diff --git a/sql/sql_union.cc b/sql/sql_union.cc index 7c9e6f0a24e..0866163b3fd 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -340,6 +340,25 @@ int st_select_lex_unit::exec() fake_select_lex->table_list.link_in_list((byte *)&result_table_list, (byte **) &result_table_list.next); + JOIN *join= fake_select_lex->join; + if (!join) + { + /* + allocate JOIN for fake select only once (privent + mysql_select automatic allocation) + */ + fake_select_lex->join= new JOIN(thd, item_list, thd->options, result); + } + else + { + JOIN_TAB *tab,*end; + for (tab=join->join_tab,end=tab+join->tables ; tab != end ; tab++) + { + delete tab->select; + delete tab->quick; + } + join->init(thd, item_list, thd->options, result); + } res= mysql_select(thd, &fake_select_lex->ref_pointer_array, &result_table_list, 0, item_list, NULL, @@ -378,14 +397,21 @@ int st_select_lex_unit::cleanup() free_tmp_table(thd, table); table= 0; // Safety } + JOIN *join; for (SELECT_LEX *sl= first_select_in_union(); sl; sl= sl->next_select()) { - JOIN *join; if ((join= sl->join)) { error|= sl->join->cleanup(); delete join; } } + if (fake_select_lex && (join= fake_select_lex->join)) + { + join->tables_list= 0; + join->tables= 0; + error|= join->cleanup(); + delete join; + } DBUG_RETURN(error); } |