Skip to content

Commit 79f852a

Browse files
committed
MDEV-10050: Crash in subselect
thd should not be taken earlier then fix_field and reset on fix_fields if it is needed.
1 parent ef92aaf commit 79f852a

File tree

2 files changed

+50
-42
lines changed

2 files changed

+50
-42
lines changed

sql/item_subselect.cc

Lines changed: 35 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,6 @@ void Item_subselect::init(st_select_lex *select_lex,
7979
DBUG_PRINT("enter", ("select_lex: 0x%lx this: 0x%lx",
8080
(ulong) select_lex, (ulong) this));
8181
unit= select_lex->master_unit();
82-
thd= unit->thd;
8382

8483
if (unit->item)
8584
{
@@ -90,7 +89,7 @@ void Item_subselect::init(st_select_lex *select_lex,
9089
engine= unit->item->engine;
9190
own_engine= FALSE;
9291
parsing_place= unit->item->parsing_place;
93-
thd->change_item_tree((Item**)&unit->item, this);
92+
unit->thd->change_item_tree((Item**)&unit->item, this);
9493
engine->change_result(this, result, TRUE);
9594
}
9695
else
@@ -104,9 +103,9 @@ void Item_subselect::init(st_select_lex *select_lex,
104103
NO_MATTER :
105104
outer_select->parsing_place);
106105
if (unit->is_union())
107-
engine= new subselect_union_engine(thd, unit, result, this);
106+
engine= new subselect_union_engine(unit, result, this);
108107
else
109-
engine= new subselect_single_select_engine(thd, select_lex, result, this);
108+
engine= new subselect_single_select_engine(select_lex, result, this);
110109
}
111110
{
112111
SELECT_LEX *upper= unit->outer_select();
@@ -220,6 +219,10 @@ bool Item_subselect::fix_fields(THD *thd_param, Item **ref)
220219
uint8 uncacheable;
221220
bool res;
222221

222+
thd= thd_param;
223+
224+
DBUG_ASSERT(unit->thd == thd);
225+
223226
status_var_increment(thd_param->status_var.feature_subquery);
224227

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

244247

245-
if (!(res= engine->prepare()))
248+
if (!(res= engine->prepare(thd)))
246249
{
247250
// all transformation is done (used by prepared statements)
248251
changed= 1;
@@ -2651,7 +2654,10 @@ bool Item_in_subselect::fix_fields(THD *thd_arg, Item **ref)
26512654
{
26522655
uint outer_cols_num;
26532656
List<Item> *inner_cols;
2654-
char const *save_where= thd->where;
2657+
char const *save_where= thd_arg->where;
2658+
2659+
thd= thd_arg;
2660+
DBUG_ASSERT(unit->thd == thd);
26552661

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

2772-
if (mat_engine->init(&select_engine->join->fields_list,
2778+
if (mat_engine->prepare(thd) ||
2779+
mat_engine->init(&select_engine->join->fields_list,
27732780
engine->get_identifier()))
27742781
DBUG_RETURN(TRUE);
27752782

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

28862893

28872894
subselect_single_select_engine::
2888-
subselect_single_select_engine(THD *thd_arg, st_select_lex *select,
2895+
subselect_single_select_engine(st_select_lex *select,
28892896
select_result_interceptor *result_arg,
28902897
Item_subselect *item_arg)
2891-
:subselect_engine(thd_arg, item_arg, result_arg),
2898+
:subselect_engine(item_arg, result_arg),
28922899
prepared(0), executed(0),
28932900
select_lex(select), join(0)
28942901
{
@@ -2966,10 +2973,10 @@ void subselect_uniquesubquery_engine::cleanup()
29662973
}
29672974

29682975

2969-
subselect_union_engine::subselect_union_engine(THD *thd_arg, st_select_lex_unit *u,
2976+
subselect_union_engine::subselect_union_engine(st_select_lex_unit *u,
29702977
select_result_interceptor *result_arg,
29712978
Item_subselect *item_arg)
2972-
:subselect_engine(thd_arg, item_arg, result_arg)
2979+
:subselect_engine(item_arg, result_arg)
29732980
{
29742981
unit= u;
29752982
unit->item= item_arg;
@@ -3002,10 +3009,11 @@ subselect_union_engine::subselect_union_engine(THD *thd_arg, st_select_lex_unit
30023009
@retval 1 if error
30033010
*/
30043011

3005-
int subselect_single_select_engine::prepare()
3012+
int subselect_single_select_engine::prepare(THD *thd)
30063013
{
30073014
if (prepared)
30083015
return 0;
3016+
set_thd(thd);
30093017
if (select_lex->join)
30103018
{
30113019
select_lex->cleanup();
@@ -3034,12 +3042,13 @@ int subselect_single_select_engine::prepare()
30343042
return 0;
30353043
}
30363044

3037-
int subselect_union_engine::prepare()
3045+
int subselect_union_engine::prepare(THD *thd_arg)
30383046
{
3047+
set_thd(thd_arg);
30393048
return unit->prepare(thd, result, SELECT_NO_UNLOCK);
30403049
}
30413050

3042-
int subselect_uniquesubquery_engine::prepare()
3051+
int subselect_uniquesubquery_engine::prepare(THD *)
30433052
{
30443053
/* Should never be called. */
30453054
DBUG_ASSERT(FALSE);
@@ -4499,13 +4508,14 @@ subselect_hash_sj_engine::~subselect_hash_sj_engine()
44994508
}
45004509

45014510

4502-
int subselect_hash_sj_engine::prepare()
4511+
int subselect_hash_sj_engine::prepare(THD *thd_arg)
45034512
{
45044513
/*
45054514
Create and optimize the JOIN that will be used to materialize
45064515
the subquery if not yet created.
45074516
*/
4508-
return materialize_engine->prepare();
4517+
set_thd(thd_arg);
4518+
return materialize_engine->prepare(thd);
45094519
}
45104520

45114521

@@ -4877,7 +4887,7 @@ int subselect_hash_sj_engine::exec()
48774887
if (strategy == PARTIAL_MATCH_MERGE)
48784888
{
48794889
pm_engine=
4880-
new subselect_rowid_merge_engine(thd, (subselect_uniquesubquery_engine*)
4890+
new subselect_rowid_merge_engine((subselect_uniquesubquery_engine*)
48814891
lookup_engine, tmp_table,
48824892
count_pm_keys,
48834893
has_covering_null_row,
@@ -4886,6 +4896,7 @@ int subselect_hash_sj_engine::exec()
48864896
item, result,
48874897
semi_join_conds->argument_list());
48884898
if (!pm_engine ||
4899+
pm_engine->prepare(thd) ||
48894900
((subselect_rowid_merge_engine*) pm_engine)->
48904901
init(nn_key_parts, &partial_match_key_parts))
48914902
{
@@ -4903,13 +4914,14 @@ int subselect_hash_sj_engine::exec()
49034914
if (strategy == PARTIAL_MATCH_SCAN)
49044915
{
49054916
if (!(pm_engine=
4906-
new subselect_table_scan_engine(thd, (subselect_uniquesubquery_engine*)
4917+
new subselect_table_scan_engine((subselect_uniquesubquery_engine*)
49074918
lookup_engine, tmp_table,
49084919
item, result,
49094920
semi_join_conds->argument_list(),
49104921
has_covering_null_row,
49114922
has_covering_null_columns,
4912-
count_columns_with_nulls)))
4923+
count_columns_with_nulls)) ||
4924+
pm_engine->prepare(thd))
49134925
{
49144926
/* This is an irrecoverable error. */
49154927
res= 1;
@@ -5356,14 +5368,14 @@ void Ordered_key::print(String *str)
53565368

53575369

53585370
subselect_partial_match_engine::subselect_partial_match_engine(
5359-
THD *thd_arg, subselect_uniquesubquery_engine *engine_arg,
5371+
subselect_uniquesubquery_engine *engine_arg,
53605372
TABLE *tmp_table_arg, Item_subselect *item_arg,
53615373
select_result_interceptor *result_arg,
53625374
List<Item> *equi_join_conds_arg,
53635375
bool has_covering_null_row_arg,
53645376
bool has_covering_null_columns_arg,
53655377
uint count_columns_with_nulls_arg)
5366-
:subselect_engine(thd_arg, item_arg, result_arg),
5378+
:subselect_engine(item_arg, result_arg),
53675379
tmp_table(tmp_table_arg), lookup_engine(engine_arg),
53685380
equi_join_conds(equi_join_conds_arg),
53695381
has_covering_null_row(has_covering_null_row_arg),
@@ -5976,15 +5988,15 @@ bool subselect_rowid_merge_engine::partial_match()
59765988

59775989

59785990
subselect_table_scan_engine::subselect_table_scan_engine(
5979-
THD *thd_arg, subselect_uniquesubquery_engine *engine_arg,
5991+
subselect_uniquesubquery_engine *engine_arg,
59805992
TABLE *tmp_table_arg,
59815993
Item_subselect *item_arg,
59825994
select_result_interceptor *result_arg,
59835995
List<Item> *equi_join_conds_arg,
59845996
bool has_covering_null_row_arg,
59855997
bool has_covering_null_columns_arg,
59865998
uint count_columns_with_nulls_arg)
5987-
:subselect_partial_match_engine(thd_arg, engine_arg, tmp_table_arg, item_arg,
5999+
:subselect_partial_match_engine(engine_arg, tmp_table_arg, item_arg,
59886000
result_arg, equi_join_conds_arg,
59896001
has_covering_null_row_arg,
59906002
has_covering_null_columns_arg,

sql/item_subselect.h

Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -715,15 +715,14 @@ class subselect_engine: public Sql_alloc
715715
INDEXSUBQUERY_ENGINE, HASH_SJ_ENGINE,
716716
ROWID_MERGE_ENGINE, TABLE_SCAN_ENGINE};
717717

718-
subselect_engine(THD *thd_arg, Item_subselect *si,
718+
subselect_engine(Item_subselect *si,
719719
select_result_interceptor *res)
720720
{
721721
result= res;
722722
item= si;
723723
cmp_type= res_type= STRING_RESULT;
724724
res_field_type= MYSQL_TYPE_VAR_STRING;
725725
maybe_null= 0;
726-
set_thd(thd_arg);
727726
}
728727
virtual ~subselect_engine() {}; // to satisfy compiler
729728
virtual void cleanup()= 0;
@@ -734,7 +733,7 @@ class subselect_engine: public Sql_alloc
734733
*/
735734
void set_thd(THD *thd_arg);
736735
THD * get_thd() { return thd; }
737-
virtual int prepare()= 0;
736+
virtual int prepare(THD *)= 0;
738737
virtual void fix_length_and_dec(Item_cache** row)= 0;
739738
/*
740739
Execute the engine
@@ -789,11 +788,11 @@ class subselect_single_select_engine: public subselect_engine
789788
st_select_lex *select_lex; /* corresponding select_lex */
790789
JOIN * join; /* corresponding JOIN structure */
791790
public:
792-
subselect_single_select_engine(THD *thd_arg, st_select_lex *select,
791+
subselect_single_select_engine(st_select_lex *select,
793792
select_result_interceptor *result,
794793
Item_subselect *item);
795794
void cleanup();
796-
int prepare();
795+
int prepare(THD *thd);
797796
void fix_length_and_dec(Item_cache** row);
798797
int exec();
799798
uint cols();
@@ -823,11 +822,11 @@ class subselect_union_engine: public subselect_engine
823822
{
824823
st_select_lex_unit *unit; /* corresponding unit structure */
825824
public:
826-
subselect_union_engine(THD *thd_arg, st_select_lex_unit *u,
825+
subselect_union_engine(st_select_lex_unit *u,
827826
select_result_interceptor *result,
828827
Item_subselect *item);
829828
void cleanup();
830-
int prepare();
829+
int prepare(THD *);
831830
void fix_length_and_dec(Item_cache** row);
832831
int exec();
833832
uint cols();
@@ -880,11 +879,11 @@ class subselect_uniquesubquery_engine: public subselect_engine
880879
// constructor can assign THD because it will be called after JOIN::prepare
881880
subselect_uniquesubquery_engine(THD *thd_arg, st_join_table *tab_arg,
882881
Item_subselect *subs, Item *where)
883-
:subselect_engine(thd_arg, subs, 0), tab(tab_arg), cond(where)
882+
:subselect_engine(subs, 0), tab(tab_arg), cond(where)
884883
{}
885884
~subselect_uniquesubquery_engine();
886885
void cleanup();
887-
int prepare();
886+
int prepare(THD *);
888887
void fix_length_and_dec(Item_cache** row);
889888
int exec();
890889
uint cols() { return 1; }
@@ -1012,7 +1011,7 @@ class subselect_hash_sj_engine : public subselect_engine
10121011

10131012
subselect_hash_sj_engine(THD *thd, Item_subselect *in_predicate,
10141013
subselect_single_select_engine *old_engine)
1015-
: subselect_engine(thd, in_predicate, NULL),
1014+
: subselect_engine(in_predicate, NULL),
10161015
tmp_table(NULL), is_materialized(FALSE), materialize_engine(old_engine),
10171016
materialize_join(NULL), semi_join_conds(NULL), lookup_engine(NULL),
10181017
count_partial_match_columns(0), count_null_only_columns(0),
@@ -1022,7 +1021,7 @@ class subselect_hash_sj_engine : public subselect_engine
10221021

10231022
bool init(List<Item> *tmp_columns, uint subquery_id);
10241023
void cleanup();
1025-
int prepare();
1024+
int prepare(THD *);
10261025
int exec();
10271026
virtual void print(String *str, enum_query_type query_type);
10281027
uint cols()
@@ -1301,15 +1300,14 @@ class subselect_partial_match_engine : public subselect_engine
13011300
protected:
13021301
virtual bool partial_match()= 0;
13031302
public:
1304-
subselect_partial_match_engine(THD *thd_arg,
1305-
subselect_uniquesubquery_engine *engine_arg,
1303+
subselect_partial_match_engine(subselect_uniquesubquery_engine *engine_arg,
13061304
TABLE *tmp_table_arg, Item_subselect *item_arg,
13071305
select_result_interceptor *result_arg,
13081306
List<Item> *equi_join_conds_arg,
13091307
bool has_covering_null_row_arg,
13101308
bool has_covering_null_columns_arg,
13111309
uint count_columns_with_nulls_arg);
1312-
int prepare() { return 0; }
1310+
int prepare(THD *thd_arg) { set_thd(thd_arg); return 0; }
13131311
int exec();
13141312
void fix_length_and_dec(Item_cache**) {}
13151313
uint cols() { /* TODO: what is the correct value? */ return 1; }
@@ -1396,16 +1394,15 @@ class subselect_rowid_merge_engine: public subselect_partial_match_engine
13961394
bool exists_complementing_null_row(MY_BITMAP *keys_to_complement);
13971395
bool partial_match();
13981396
public:
1399-
subselect_rowid_merge_engine(THD *thd_arg,
1400-
subselect_uniquesubquery_engine *engine_arg,
1397+
subselect_rowid_merge_engine(subselect_uniquesubquery_engine *engine_arg,
14011398
TABLE *tmp_table_arg, uint merge_keys_count_arg,
14021399
bool has_covering_null_row_arg,
14031400
bool has_covering_null_columns_arg,
14041401
uint count_columns_with_nulls_arg,
14051402
Item_subselect *item_arg,
14061403
select_result_interceptor *result_arg,
14071404
List<Item> *equi_join_conds_arg)
1408-
:subselect_partial_match_engine(thd_arg, engine_arg, tmp_table_arg,
1405+
:subselect_partial_match_engine(engine_arg, tmp_table_arg,
14091406
item_arg, result_arg, equi_join_conds_arg,
14101407
has_covering_null_row_arg,
14111408
has_covering_null_columns_arg,
@@ -1424,8 +1421,7 @@ class subselect_table_scan_engine: public subselect_partial_match_engine
14241421
protected:
14251422
bool partial_match();
14261423
public:
1427-
subselect_table_scan_engine(THD *thd_arg,
1428-
subselect_uniquesubquery_engine *engine_arg,
1424+
subselect_table_scan_engine(subselect_uniquesubquery_engine *engine_arg,
14291425
TABLE *tmp_table_arg, Item_subselect *item_arg,
14301426
select_result_interceptor *result_arg,
14311427
List<Item> *equi_join_conds_arg,

0 commit comments

Comments
 (0)