summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/sql_select.cc22
-rw-r--r--sql/sql_select.h81
-rw-r--r--sql/sql_union.cc28
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);
}