MDEV-10050: Crash in subselect
thd should not be taken earlier then fix_field and reset on fix_fields if it is needed.
This commit is contained in:
parent
ef92aaf9ec
commit
79f852a069
@ -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)
|
||||
{
|
||||
@ -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
|
||||
@ -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();
|
||||
@ -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);
|
||||
@ -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;
|
||||
@ -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));
|
||||
@ -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);
|
||||
|
||||
@ -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)
|
||||
{
|
||||
@ -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;
|
||||
@ -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();
|
||||
@ -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);
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
@ -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,
|
||||
@ -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))
|
||||
{
|
||||
@ -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;
|
||||
@ -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),
|
||||
@ -5976,7 +5988,7 @@ end:
|
||||
|
||||
|
||||
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,
|
||||
@ -5984,7 +5996,7 @@ subselect_table_scan_engine::subselect_table_scan_engine(
|
||||
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,
|
||||
|
@ -715,7 +715,7 @@ public:
|
||||
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;
|
||||
@ -723,7 +723,6 @@ public:
|
||||
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;
|
||||
@ -734,7 +733,7 @@ public:
|
||||
*/
|
||||
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
|
||||
@ -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();
|
||||
@ -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();
|
||||
@ -880,11 +879,11 @@ public:
|
||||
// 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; }
|
||||
@ -1012,7 +1011,7 @@ public:
|
||||
|
||||
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),
|
||||
@ -1022,7 +1021,7 @@ public:
|
||||
|
||||
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()
|
||||
@ -1301,15 +1300,14 @@ protected:
|
||||
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; }
|
||||
@ -1396,8 +1394,7 @@ protected:
|
||||
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,
|
||||
@ -1405,7 +1402,7 @@ public:
|
||||
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,
|
||||
@ -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,
|
||||
|
Loading…
x
Reference in New Issue
Block a user