Commit 56568288 authored by unknown's avatar unknown

fake_select_lex should be prepared during PS preparation to work correctly

item_list for fake_select will be created only once
(problem reported by valgrind in test_union2 fixed)


sql/sql_lex.h:
  new function to keep code in one place
sql/sql_union.cc:
  fake_select_lex should be prepared during PS preparation to work correctly
  item_list for fake_select will be created only once
parent 151495ba
...@@ -366,7 +366,8 @@ class st_select_lex_unit: public st_select_lex_node { ...@@ -366,7 +366,8 @@ class st_select_lex_unit: public st_select_lex_node {
bool check_updateable(char *db, char *table); bool check_updateable(char *db, char *table);
void print(String *str); void print(String *str);
ulong init_prepare_fake_select_lex(THD *thd);
friend void mysql_init_query(THD *thd); friend void mysql_init_query(THD *thd);
friend int subselect_union_engine::exec(); friend int subselect_union_engine::exec();
......
...@@ -106,6 +106,41 @@ bool select_union::flush() ...@@ -106,6 +106,41 @@ bool select_union::flush()
} }
/*
initialization procedures before fake_select_lex preparation()
SYNOPSIS
st_select_lex_unit::init_prepare_fake_select_lex()
thd - thread handler
RETURN
options of SELECT
*/
ulong
st_select_lex_unit::init_prepare_fake_select_lex(THD *thd)
{
ulong options_tmp= thd->options;
thd->lex->current_select= fake_select_lex;
offset_limit_cnt= global_parameters->offset_limit;
select_limit_cnt= global_parameters->select_limit +
global_parameters->offset_limit;
if (select_limit_cnt < global_parameters->select_limit)
select_limit_cnt= HA_POS_ERROR; // no limit
if (select_limit_cnt == HA_POS_ERROR)
options_tmp&= ~OPTION_FOUND_ROWS;
else if (found_rows_for_union && !thd->lex->describe)
options_tmp|= OPTION_FOUND_ROWS;
fake_select_lex->ftfunc_list_alloc.empty();
fake_select_lex->ftfunc_list= &fake_select_lex->ftfunc_list_alloc;
fake_select_lex->table_list.link_in_list((byte *)&result_table_list,
(byte **)
&result_table_list.next);
return options_tmp;
}
int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
ulong additional_options) ulong additional_options)
{ {
...@@ -207,7 +242,6 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, ...@@ -207,7 +242,6 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
} }
} }
item_list.empty();
// it is not single select // it is not single select
if (first_select->next_select()) if (first_select->next_select())
{ {
...@@ -229,7 +263,7 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, ...@@ -229,7 +263,7 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
union_result->set_table(table); union_result->set_table(table);
thd_arg->lex->current_select= lex_select_save; thd_arg->lex->current_select= lex_select_save;
{ if (!item_list.elements){
Statement *stmt= thd->current_statement; Statement *stmt= thd->current_statement;
Statement backup; Statement backup;
if (stmt) if (stmt)
...@@ -246,7 +280,30 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, ...@@ -246,7 +280,30 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
} }
} }
if (stmt) if (stmt)
{
thd->restore_backup_item_arena(stmt, &backup); thd->restore_backup_item_arena(stmt, &backup);
/* prepare fake select to initialize it correctly */
ulong options_tmp= init_prepare_fake_select_lex(thd);
if (!(fake_select_lex->join= new JOIN(thd, item_list, thd->options,
result)))
{
fake_select_lex->table_list.empty();
DBUG_RETURN(-1);
}
fake_select_lex->item_list= item_list;
thd_arg->lex->current_select= fake_select_lex;
res= fake_select_lex->join->
prepare(&fake_select_lex->ref_pointer_array,
(TABLE_LIST*) fake_select_lex->table_list.first,
0, 0,
fake_select_lex->order_list.elements,
(ORDER*) fake_select_lex->order_list.first,
(ORDER*) NULL, NULL, (ORDER*) NULL,
fake_select_lex, this);
fake_select_lex->table_list.empty();
}
} }
} }
else else
...@@ -373,22 +430,7 @@ int st_select_lex_unit::exec() ...@@ -373,22 +430,7 @@ int st_select_lex_unit::exec()
if (!thd->is_fatal_error) // Check if EOM if (!thd->is_fatal_error) // Check if EOM
{ {
ulong options_tmp= thd->options; ulong options_tmp= init_prepare_fake_select_lex(thd);
thd->lex->current_select= fake_select_lex;
offset_limit_cnt= global_parameters->offset_limit;
select_limit_cnt= global_parameters->select_limit +
global_parameters->offset_limit;
if (select_limit_cnt < global_parameters->select_limit)
select_limit_cnt= HA_POS_ERROR; // no limit
if (select_limit_cnt == HA_POS_ERROR)
options_tmp&= ~OPTION_FOUND_ROWS;
else if (found_rows_for_union && !thd->lex->describe)
options_tmp|= OPTION_FOUND_ROWS;
fake_select_lex->ftfunc_list= &empty_list;
fake_select_lex->table_list.link_in_list((byte *)&result_table_list,
(byte **)
&result_table_list.next);
JOIN *join= fake_select_lex->join; JOIN *join= fake_select_lex->join;
if (!join) if (!join)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment