Skip to content

Commit

Permalink
MDEV-10050: Crash in subselect
Browse files Browse the repository at this point in the history
thd should not be taken earlier then fix_field and reset on fix_fields if it is needed.
  • Loading branch information
sanja-byelkin committed Jun 24, 2016
1 parent ef92aaf commit 79f852a
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 42 deletions.
58 changes: 35 additions & 23 deletions sql/item_subselect.cc
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,6 @@ void Item_subselect::init(st_select_lex *select_lex,
DBUG_PRINT("enter", ("select_lex: 0x%lx this: 0x%lx",
(ulong) select_lex, (ulong) this));
unit= select_lex->master_unit();
thd= unit->thd;

if (unit->item)
{
Expand All @@ -90,7 +89,7 @@ void Item_subselect::init(st_select_lex *select_lex,
engine= unit->item->engine;
own_engine= FALSE;
parsing_place= unit->item->parsing_place;
thd->change_item_tree((Item**)&unit->item, this);
unit->thd->change_item_tree((Item**)&unit->item, this);
engine->change_result(this, result, TRUE);
}
else
Expand All @@ -104,9 +103,9 @@ void Item_subselect::init(st_select_lex *select_lex,
NO_MATTER :
outer_select->parsing_place);
if (unit->is_union())
engine= new subselect_union_engine(thd, unit, result, this);
engine= new subselect_union_engine(unit, result, this);
else
engine= new subselect_single_select_engine(thd, select_lex, result, this);
engine= new subselect_single_select_engine(select_lex, result, this);
}
{
SELECT_LEX *upper= unit->outer_select();
Expand Down Expand Up @@ -220,6 +219,10 @@ bool Item_subselect::fix_fields(THD *thd_param, Item **ref)
uint8 uncacheable;
bool res;

thd= thd_param;

DBUG_ASSERT(unit->thd == thd);

status_var_increment(thd_param->status_var.feature_subquery);

DBUG_ASSERT(fixed == 0);
Expand All @@ -242,7 +245,7 @@ bool Item_subselect::fix_fields(THD *thd_param, Item **ref)
return TRUE;


if (!(res= engine->prepare()))
if (!(res= engine->prepare(thd)))
{
// all transformation is done (used by prepared statements)
changed= 1;
Expand Down Expand Up @@ -2651,7 +2654,10 @@ bool Item_in_subselect::fix_fields(THD *thd_arg, Item **ref)
{
uint outer_cols_num;
List<Item> *inner_cols;
char const *save_where= thd->where;
char const *save_where= thd_arg->where;

thd= thd_arg;
DBUG_ASSERT(unit->thd == thd);

if (test_strategy(SUBS_SEMI_JOIN))
return !( (*ref)= new Item_int(1));
Expand Down Expand Up @@ -2769,7 +2775,8 @@ bool Item_in_subselect::setup_mat_engine()
if (!(mat_engine= new subselect_hash_sj_engine(thd, this, select_engine)))
DBUG_RETURN(TRUE);

if (mat_engine->init(&select_engine->join->fields_list,
if (mat_engine->prepare(thd) ||
mat_engine->init(&select_engine->join->fields_list,
engine->get_identifier()))
DBUG_RETURN(TRUE);

Expand Down Expand Up @@ -2885,10 +2892,10 @@ void subselect_engine::set_thd(THD *thd_arg)


subselect_single_select_engine::
subselect_single_select_engine(THD *thd_arg, st_select_lex *select,
subselect_single_select_engine(st_select_lex *select,
select_result_interceptor *result_arg,
Item_subselect *item_arg)
:subselect_engine(thd_arg, item_arg, result_arg),
:subselect_engine(item_arg, result_arg),
prepared(0), executed(0),
select_lex(select), join(0)
{
Expand Down Expand Up @@ -2966,10 +2973,10 @@ void subselect_uniquesubquery_engine::cleanup()
}


subselect_union_engine::subselect_union_engine(THD *thd_arg, st_select_lex_unit *u,
subselect_union_engine::subselect_union_engine(st_select_lex_unit *u,
select_result_interceptor *result_arg,
Item_subselect *item_arg)
:subselect_engine(thd_arg, item_arg, result_arg)
:subselect_engine(item_arg, result_arg)
{
unit= u;
unit->item= item_arg;
Expand Down Expand Up @@ -3002,10 +3009,11 @@ subselect_union_engine::subselect_union_engine(THD *thd_arg, st_select_lex_unit
@retval 1 if error
*/

int subselect_single_select_engine::prepare()
int subselect_single_select_engine::prepare(THD *thd)
{
if (prepared)
return 0;
set_thd(thd);
if (select_lex->join)
{
select_lex->cleanup();
Expand Down Expand Up @@ -3034,12 +3042,13 @@ int subselect_single_select_engine::prepare()
return 0;
}

int subselect_union_engine::prepare()
int subselect_union_engine::prepare(THD *thd_arg)
{
set_thd(thd_arg);
return unit->prepare(thd, result, SELECT_NO_UNLOCK);
}

int subselect_uniquesubquery_engine::prepare()
int subselect_uniquesubquery_engine::prepare(THD *)
{
/* Should never be called. */
DBUG_ASSERT(FALSE);
Expand Down Expand Up @@ -4499,13 +4508,14 @@ subselect_hash_sj_engine::~subselect_hash_sj_engine()
}


int subselect_hash_sj_engine::prepare()
int subselect_hash_sj_engine::prepare(THD *thd_arg)
{
/*
Create and optimize the JOIN that will be used to materialize
the subquery if not yet created.
*/
return materialize_engine->prepare();
set_thd(thd_arg);
return materialize_engine->prepare(thd);
}


Expand Down Expand Up @@ -4877,7 +4887,7 @@ int subselect_hash_sj_engine::exec()
if (strategy == PARTIAL_MATCH_MERGE)
{
pm_engine=
new subselect_rowid_merge_engine(thd, (subselect_uniquesubquery_engine*)
new subselect_rowid_merge_engine((subselect_uniquesubquery_engine*)
lookup_engine, tmp_table,
count_pm_keys,
has_covering_null_row,
Expand All @@ -4886,6 +4896,7 @@ int subselect_hash_sj_engine::exec()
item, result,
semi_join_conds->argument_list());
if (!pm_engine ||
pm_engine->prepare(thd) ||
((subselect_rowid_merge_engine*) pm_engine)->
init(nn_key_parts, &partial_match_key_parts))
{
Expand All @@ -4903,13 +4914,14 @@ int subselect_hash_sj_engine::exec()
if (strategy == PARTIAL_MATCH_SCAN)
{
if (!(pm_engine=
new subselect_table_scan_engine(thd, (subselect_uniquesubquery_engine*)
new subselect_table_scan_engine((subselect_uniquesubquery_engine*)
lookup_engine, tmp_table,
item, result,
semi_join_conds->argument_list(),
has_covering_null_row,
has_covering_null_columns,
count_columns_with_nulls)))
count_columns_with_nulls)) ||
pm_engine->prepare(thd))
{
/* This is an irrecoverable error. */
res= 1;
Expand Down Expand Up @@ -5356,14 +5368,14 @@ void Ordered_key::print(String *str)


subselect_partial_match_engine::subselect_partial_match_engine(
THD *thd_arg, subselect_uniquesubquery_engine *engine_arg,
subselect_uniquesubquery_engine *engine_arg,
TABLE *tmp_table_arg, Item_subselect *item_arg,
select_result_interceptor *result_arg,
List<Item> *equi_join_conds_arg,
bool has_covering_null_row_arg,
bool has_covering_null_columns_arg,
uint count_columns_with_nulls_arg)
:subselect_engine(thd_arg, item_arg, result_arg),
:subselect_engine(item_arg, result_arg),
tmp_table(tmp_table_arg), lookup_engine(engine_arg),
equi_join_conds(equi_join_conds_arg),
has_covering_null_row(has_covering_null_row_arg),
Expand Down Expand Up @@ -5976,15 +5988,15 @@ bool subselect_rowid_merge_engine::partial_match()


subselect_table_scan_engine::subselect_table_scan_engine(
THD *thd_arg, subselect_uniquesubquery_engine *engine_arg,
subselect_uniquesubquery_engine *engine_arg,
TABLE *tmp_table_arg,
Item_subselect *item_arg,
select_result_interceptor *result_arg,
List<Item> *equi_join_conds_arg,
bool has_covering_null_row_arg,
bool has_covering_null_columns_arg,
uint count_columns_with_nulls_arg)
:subselect_partial_match_engine(thd_arg, engine_arg, tmp_table_arg, item_arg,
:subselect_partial_match_engine(engine_arg, tmp_table_arg, item_arg,
result_arg, equi_join_conds_arg,
has_covering_null_row_arg,
has_covering_null_columns_arg,
Expand Down
34 changes: 15 additions & 19 deletions sql/item_subselect.h
Original file line number Diff line number Diff line change
Expand Up @@ -715,15 +715,14 @@ class subselect_engine: public Sql_alloc
INDEXSUBQUERY_ENGINE, HASH_SJ_ENGINE,
ROWID_MERGE_ENGINE, TABLE_SCAN_ENGINE};

subselect_engine(THD *thd_arg, Item_subselect *si,
subselect_engine(Item_subselect *si,
select_result_interceptor *res)
{
result= res;
item= si;
cmp_type= res_type= STRING_RESULT;
res_field_type= MYSQL_TYPE_VAR_STRING;
maybe_null= 0;
set_thd(thd_arg);
}
virtual ~subselect_engine() {}; // to satisfy compiler
virtual void cleanup()= 0;
Expand All @@ -734,7 +733,7 @@ class subselect_engine: public Sql_alloc
*/
void set_thd(THD *thd_arg);
THD * get_thd() { return thd; }
virtual int prepare()= 0;
virtual int prepare(THD *)= 0;
virtual void fix_length_and_dec(Item_cache** row)= 0;
/*
Execute the engine
Expand Down Expand Up @@ -789,11 +788,11 @@ class subselect_single_select_engine: public subselect_engine
st_select_lex *select_lex; /* corresponding select_lex */
JOIN * join; /* corresponding JOIN structure */
public:
subselect_single_select_engine(THD *thd_arg, st_select_lex *select,
subselect_single_select_engine(st_select_lex *select,
select_result_interceptor *result,
Item_subselect *item);
void cleanup();
int prepare();
int prepare(THD *thd);
void fix_length_and_dec(Item_cache** row);
int exec();
uint cols();
Expand Down Expand Up @@ -823,11 +822,11 @@ class subselect_union_engine: public subselect_engine
{
st_select_lex_unit *unit; /* corresponding unit structure */
public:
subselect_union_engine(THD *thd_arg, st_select_lex_unit *u,
subselect_union_engine(st_select_lex_unit *u,
select_result_interceptor *result,
Item_subselect *item);
void cleanup();
int prepare();
int prepare(THD *);
void fix_length_and_dec(Item_cache** row);
int exec();
uint cols();
Expand Down Expand Up @@ -880,11 +879,11 @@ class subselect_uniquesubquery_engine: public subselect_engine
// constructor can assign THD because it will be called after JOIN::prepare
subselect_uniquesubquery_engine(THD *thd_arg, st_join_table *tab_arg,
Item_subselect *subs, Item *where)
:subselect_engine(thd_arg, subs, 0), tab(tab_arg), cond(where)
:subselect_engine(subs, 0), tab(tab_arg), cond(where)
{}
~subselect_uniquesubquery_engine();
void cleanup();
int prepare();
int prepare(THD *);
void fix_length_and_dec(Item_cache** row);
int exec();
uint cols() { return 1; }
Expand Down Expand Up @@ -1012,7 +1011,7 @@ class subselect_hash_sj_engine : public subselect_engine

subselect_hash_sj_engine(THD *thd, Item_subselect *in_predicate,
subselect_single_select_engine *old_engine)
: subselect_engine(thd, in_predicate, NULL),
: subselect_engine(in_predicate, NULL),
tmp_table(NULL), is_materialized(FALSE), materialize_engine(old_engine),
materialize_join(NULL), semi_join_conds(NULL), lookup_engine(NULL),
count_partial_match_columns(0), count_null_only_columns(0),
Expand All @@ -1022,7 +1021,7 @@ class subselect_hash_sj_engine : public subselect_engine

bool init(List<Item> *tmp_columns, uint subquery_id);
void cleanup();
int prepare();
int prepare(THD *);
int exec();
virtual void print(String *str, enum_query_type query_type);
uint cols()
Expand Down Expand Up @@ -1301,15 +1300,14 @@ class subselect_partial_match_engine : public subselect_engine
protected:
virtual bool partial_match()= 0;
public:
subselect_partial_match_engine(THD *thd_arg,
subselect_uniquesubquery_engine *engine_arg,
subselect_partial_match_engine(subselect_uniquesubquery_engine *engine_arg,
TABLE *tmp_table_arg, Item_subselect *item_arg,
select_result_interceptor *result_arg,
List<Item> *equi_join_conds_arg,
bool has_covering_null_row_arg,
bool has_covering_null_columns_arg,
uint count_columns_with_nulls_arg);
int prepare() { return 0; }
int prepare(THD *thd_arg) { set_thd(thd_arg); return 0; }
int exec();
void fix_length_and_dec(Item_cache**) {}
uint cols() { /* TODO: what is the correct value? */ return 1; }
Expand Down Expand Up @@ -1396,16 +1394,15 @@ class subselect_rowid_merge_engine: public subselect_partial_match_engine
bool exists_complementing_null_row(MY_BITMAP *keys_to_complement);
bool partial_match();
public:
subselect_rowid_merge_engine(THD *thd_arg,
subselect_uniquesubquery_engine *engine_arg,
subselect_rowid_merge_engine(subselect_uniquesubquery_engine *engine_arg,
TABLE *tmp_table_arg, uint merge_keys_count_arg,
bool has_covering_null_row_arg,
bool has_covering_null_columns_arg,
uint count_columns_with_nulls_arg,
Item_subselect *item_arg,
select_result_interceptor *result_arg,
List<Item> *equi_join_conds_arg)
:subselect_partial_match_engine(thd_arg, engine_arg, tmp_table_arg,
:subselect_partial_match_engine(engine_arg, tmp_table_arg,
item_arg, result_arg, equi_join_conds_arg,
has_covering_null_row_arg,
has_covering_null_columns_arg,
Expand All @@ -1424,8 +1421,7 @@ class subselect_table_scan_engine: public subselect_partial_match_engine
protected:
bool partial_match();
public:
subselect_table_scan_engine(THD *thd_arg,
subselect_uniquesubquery_engine *engine_arg,
subselect_table_scan_engine(subselect_uniquesubquery_engine *engine_arg,
TABLE *tmp_table_arg, Item_subselect *item_arg,
select_result_interceptor *result_arg,
List<Item> *equi_join_conds_arg,
Expand Down

0 comments on commit 79f852a

Please sign in to comment.