mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
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
This commit is contained in:
@ -366,7 +366,8 @@ public:
|
|||||||
|
|
||||||
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()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
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,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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,
|
|||||||
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,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
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()
|
|||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user