Commit 4f28dcbe authored by unknown's avatar unknown

Fix LP BUG#685411

Analysis:
The assert failed because st_select_lex::print() was called for subqueries
as follows:

Item_subselect::print() ->
  subselect_single_select_engine::print() -> st_select_lex::print()

It was Item_subselect::fix_fields() that set the thd by calling set_thd(),
so when this print() was called before fix_fields(), subselect_engine::thd
was NULL.

Solution:
The patch makes all constructors of all subselect_engine classes to take
a THD parameter. The default subselect_single_select_engine engine is created
early during parse time, in the Item_subselect::init call, so we pass the
correct THD object already at this point.
parent 419d524f
...@@ -60,6 +60,7 @@ void Item_subselect::init(st_select_lex *select_lex, ...@@ -60,6 +60,7 @@ void Item_subselect::init(st_select_lex *select_lex,
DBUG_ENTER("Item_subselect::init"); DBUG_ENTER("Item_subselect::init");
DBUG_PRINT("enter", ("select_lex: 0x%lx", (long) select_lex)); DBUG_PRINT("enter", ("select_lex: 0x%lx", (long) select_lex));
unit= select_lex->master_unit(); unit= select_lex->master_unit();
thd= unit->thd;
if (unit->item) if (unit->item)
{ {
...@@ -76,6 +77,7 @@ void Item_subselect::init(st_select_lex *select_lex, ...@@ -76,6 +77,7 @@ void Item_subselect::init(st_select_lex *select_lex,
else else
{ {
SELECT_LEX *outer_select= unit->outer_select(); SELECT_LEX *outer_select= unit->outer_select();
DBUG_ASSERT(thd);
/* /*
do not take into account expression inside aggregate functions because do not take into account expression inside aggregate functions because
they can access original table fields they can access original table fields
...@@ -84,9 +86,9 @@ void Item_subselect::init(st_select_lex *select_lex, ...@@ -84,9 +86,9 @@ void Item_subselect::init(st_select_lex *select_lex,
NO_MATTER : NO_MATTER :
outer_select->parsing_place); outer_select->parsing_place);
if (unit->is_union()) if (unit->is_union())
engine= new subselect_union_engine(unit, result, this); engine= new subselect_union_engine(thd, unit, result, this);
else else
engine= new subselect_single_select_engine(select_lex, result, this); engine= new subselect_single_select_engine(thd, select_lex, result, this);
} }
{ {
SELECT_LEX *upper= unit->outer_select(); SELECT_LEX *upper= unit->outer_select();
...@@ -183,7 +185,8 @@ bool Item_subselect::fix_fields(THD *thd_param, Item **ref) ...@@ -183,7 +185,8 @@ bool Item_subselect::fix_fields(THD *thd_param, Item **ref)
bool res; bool res;
DBUG_ASSERT(fixed == 0); DBUG_ASSERT(fixed == 0);
engine->set_thd((thd= thd_param)); /* There is no reason to get a different THD. */
DBUG_ASSERT(thd == thd_param);
if (!done_first_fix_fields) if (!done_first_fix_fields)
{ {
done_first_fix_fields= TRUE; done_first_fix_fields= TRUE;
...@@ -2384,10 +2387,10 @@ void subselect_engine::set_thd(THD *thd_arg) ...@@ -2384,10 +2387,10 @@ void subselect_engine::set_thd(THD *thd_arg)
subselect_single_select_engine:: subselect_single_select_engine::
subselect_single_select_engine(st_select_lex *select, subselect_single_select_engine(THD *thd_arg, st_select_lex *select,
select_result_interceptor *result_arg, select_result_interceptor *result_arg,
Item_subselect *item_arg) Item_subselect *item_arg)
:subselect_engine(item_arg, result_arg), :subselect_engine(thd_arg, item_arg, result_arg),
prepared(0), executed(0), select_lex(select), join(0) prepared(0), executed(0), select_lex(select), join(0)
{ {
select_lex->master_unit()->item= item_arg; select_lex->master_unit()->item= item_arg;
...@@ -2455,10 +2458,10 @@ void subselect_uniquesubquery_engine::cleanup() ...@@ -2455,10 +2458,10 @@ void subselect_uniquesubquery_engine::cleanup()
} }
subselect_union_engine::subselect_union_engine(st_select_lex_unit *u, subselect_union_engine::subselect_union_engine(THD *thd_arg, st_select_lex_unit *u,
select_result_interceptor *result_arg, select_result_interceptor *result_arg,
Item_subselect *item_arg) Item_subselect *item_arg)
:subselect_engine(item_arg, result_arg) :subselect_engine(thd_arg, item_arg, result_arg)
{ {
unit= u; unit= u;
if (!result_arg) //out of memory if (!result_arg) //out of memory
...@@ -4164,7 +4167,7 @@ int subselect_hash_sj_engine::exec() ...@@ -4164,7 +4167,7 @@ int subselect_hash_sj_engine::exec()
if (strategy == PARTIAL_MATCH_MERGE) if (strategy == PARTIAL_MATCH_MERGE)
{ {
pm_engine= pm_engine=
new subselect_rowid_merge_engine((subselect_uniquesubquery_engine*) new subselect_rowid_merge_engine(thd, (subselect_uniquesubquery_engine*)
lookup_engine, tmp_table, lookup_engine, tmp_table,
count_pm_keys, count_pm_keys,
covering_null_row_width, covering_null_row_width,
...@@ -4188,7 +4191,7 @@ int subselect_hash_sj_engine::exec() ...@@ -4188,7 +4191,7 @@ int subselect_hash_sj_engine::exec()
if (strategy == PARTIAL_MATCH_SCAN) if (strategy == PARTIAL_MATCH_SCAN)
{ {
if (!(pm_engine= if (!(pm_engine=
new subselect_table_scan_engine((subselect_uniquesubquery_engine*) new subselect_table_scan_engine(thd, (subselect_uniquesubquery_engine*)
lookup_engine, tmp_table, lookup_engine, tmp_table,
item, result, item, result,
semi_join_conds->argument_list(), semi_join_conds->argument_list(),
...@@ -4623,12 +4626,12 @@ void Ordered_key::print(String *str) ...@@ -4623,12 +4626,12 @@ void Ordered_key::print(String *str)
subselect_partial_match_engine::subselect_partial_match_engine( subselect_partial_match_engine::subselect_partial_match_engine(
subselect_uniquesubquery_engine *engine_arg, THD *thd_arg, subselect_uniquesubquery_engine *engine_arg,
TABLE *tmp_table_arg, Item_subselect *item_arg, TABLE *tmp_table_arg, Item_subselect *item_arg,
select_result_interceptor *result_arg, select_result_interceptor *result_arg,
List<Item> *equi_join_conds_arg, List<Item> *equi_join_conds_arg,
uint covering_null_row_width_arg) uint covering_null_row_width_arg)
:subselect_engine(item_arg, result_arg), :subselect_engine(thd_arg, item_arg, result_arg),
tmp_table(tmp_table_arg), lookup_engine(engine_arg), tmp_table(tmp_table_arg), lookup_engine(engine_arg),
equi_join_conds(equi_join_conds_arg), equi_join_conds(equi_join_conds_arg),
covering_null_row_width(covering_null_row_width_arg) covering_null_row_width(covering_null_row_width_arg)
...@@ -5144,13 +5147,13 @@ bool subselect_rowid_merge_engine::partial_match() ...@@ -5144,13 +5147,13 @@ bool subselect_rowid_merge_engine::partial_match()
subselect_table_scan_engine::subselect_table_scan_engine( subselect_table_scan_engine::subselect_table_scan_engine(
subselect_uniquesubquery_engine *engine_arg, THD *thd_arg, subselect_uniquesubquery_engine *engine_arg,
TABLE *tmp_table_arg, TABLE *tmp_table_arg,
Item_subselect *item_arg, Item_subselect *item_arg,
select_result_interceptor *result_arg, select_result_interceptor *result_arg,
List<Item> *equi_join_conds_arg, List<Item> *equi_join_conds_arg,
uint covering_null_row_width_arg) uint covering_null_row_width_arg)
:subselect_partial_match_engine(engine_arg, tmp_table_arg, item_arg, :subselect_partial_match_engine(thd_arg, engine_arg, tmp_table_arg, item_arg,
result_arg, equi_join_conds_arg, result_arg, equi_join_conds_arg,
covering_null_row_width_arg) covering_null_row_width_arg)
{} {}
......
...@@ -501,14 +501,15 @@ class subselect_engine: public Sql_alloc ...@@ -501,14 +501,15 @@ class subselect_engine: public Sql_alloc
INDEXSUBQUERY_ENGINE, HASH_SJ_ENGINE, INDEXSUBQUERY_ENGINE, HASH_SJ_ENGINE,
ROWID_MERGE_ENGINE, TABLE_SCAN_ENGINE}; ROWID_MERGE_ENGINE, TABLE_SCAN_ENGINE};
subselect_engine(Item_subselect *si, select_result_interceptor *res) subselect_engine(THD *thd_arg, Item_subselect *si,
:thd(0) select_result_interceptor *res)
{ {
result= res; result= res;
item= si; item= si;
res_type= STRING_RESULT; res_type= STRING_RESULT;
res_field_type= MYSQL_TYPE_VAR_STRING; res_field_type= MYSQL_TYPE_VAR_STRING;
maybe_null= 0; maybe_null= 0;
set_thd(thd_arg);
} }
virtual ~subselect_engine() {}; // to satisfy compiler virtual ~subselect_engine() {}; // to satisfy compiler
virtual void cleanup()= 0; virtual void cleanup()= 0;
...@@ -572,7 +573,7 @@ class subselect_single_select_engine: public subselect_engine ...@@ -572,7 +573,7 @@ class subselect_single_select_engine: public subselect_engine
st_select_lex *select_lex; /* corresponding select_lex */ st_select_lex *select_lex; /* corresponding select_lex */
JOIN * join; /* corresponding JOIN structure */ JOIN * join; /* corresponding JOIN structure */
public: public:
subselect_single_select_engine(st_select_lex *select, subselect_single_select_engine(THD *thd_arg, st_select_lex *select,
select_result_interceptor *result, select_result_interceptor *result,
Item_subselect *item); Item_subselect *item);
void cleanup(); void cleanup();
...@@ -601,7 +602,7 @@ class subselect_union_engine: public subselect_engine ...@@ -601,7 +602,7 @@ class subselect_union_engine: public subselect_engine
{ {
st_select_lex_unit *unit; /* corresponding unit structure */ st_select_lex_unit *unit; /* corresponding unit structure */
public: public:
subselect_union_engine(st_select_lex_unit *u, subselect_union_engine(THD *thd_arg, st_select_lex_unit *u,
select_result_interceptor *result, select_result_interceptor *result,
Item_subselect *item); Item_subselect *item);
void cleanup(); void cleanup();
...@@ -657,10 +658,8 @@ class subselect_uniquesubquery_engine: public subselect_engine ...@@ -657,10 +658,8 @@ class subselect_uniquesubquery_engine: public subselect_engine
// constructor can assign THD because it will be called after JOIN::prepare // constructor can assign THD because it will be called after JOIN::prepare
subselect_uniquesubquery_engine(THD *thd_arg, st_join_table *tab_arg, subselect_uniquesubquery_engine(THD *thd_arg, st_join_table *tab_arg,
Item_subselect *subs, Item *where) Item_subselect *subs, Item *where)
:subselect_engine(subs, 0), tab(tab_arg), cond(where) :subselect_engine(thd_arg, subs, 0), tab(tab_arg), cond(where)
{ {}
set_thd(thd_arg);
}
~subselect_uniquesubquery_engine(); ~subselect_uniquesubquery_engine();
void cleanup(); void cleanup();
int prepare(); int prepare();
...@@ -812,13 +811,11 @@ class subselect_hash_sj_engine : public subselect_engine ...@@ -812,13 +811,11 @@ class subselect_hash_sj_engine : public subselect_engine
public: public:
subselect_hash_sj_engine(THD *thd, Item_subselect *in_predicate, subselect_hash_sj_engine(THD *thd, Item_subselect *in_predicate,
subselect_single_select_engine *old_engine) subselect_single_select_engine *old_engine)
:subselect_engine(in_predicate, NULL), tmp_table(NULL), :subselect_engine(thd, in_predicate, NULL), tmp_table(NULL),
is_materialized(FALSE), materialize_engine(old_engine), lookup_engine(NULL), is_materialized(FALSE), materialize_engine(old_engine), lookup_engine(NULL),
materialize_join(NULL), count_partial_match_columns(0), materialize_join(NULL), count_partial_match_columns(0),
count_null_only_columns(0), semi_join_conds(NULL), strategy(UNDEFINED) count_null_only_columns(0), semi_join_conds(NULL), strategy(UNDEFINED)
{ {}
set_thd(thd);
}
~subselect_hash_sj_engine(); ~subselect_hash_sj_engine();
bool init_permanent(List<Item> *tmp_columns); bool init_permanent(List<Item> *tmp_columns);
...@@ -1056,7 +1053,8 @@ class subselect_partial_match_engine : public subselect_engine ...@@ -1056,7 +1053,8 @@ class subselect_partial_match_engine : public subselect_engine
protected: protected:
virtual bool partial_match()= 0; virtual bool partial_match()= 0;
public: public:
subselect_partial_match_engine(subselect_uniquesubquery_engine *engine_arg, subselect_partial_match_engine(THD *thd_arg,
subselect_uniquesubquery_engine *engine_arg,
TABLE *tmp_table_arg, Item_subselect *item_arg, TABLE *tmp_table_arg, Item_subselect *item_arg,
select_result_interceptor *result_arg, select_result_interceptor *result_arg,
List<Item> *equi_join_conds_arg, List<Item> *equi_join_conds_arg,
...@@ -1148,19 +1146,18 @@ class subselect_rowid_merge_engine: public subselect_partial_match_engine ...@@ -1148,19 +1146,18 @@ class subselect_rowid_merge_engine: public subselect_partial_match_engine
bool test_null_row(rownum_t row_num); bool test_null_row(rownum_t row_num);
bool partial_match(); bool partial_match();
public: public:
subselect_rowid_merge_engine(subselect_uniquesubquery_engine *engine_arg, subselect_rowid_merge_engine(THD *thd_arg,
subselect_uniquesubquery_engine *engine_arg,
TABLE *tmp_table_arg, uint keys_count_arg, TABLE *tmp_table_arg, uint keys_count_arg,
uint covering_null_row_width_arg, uint covering_null_row_width_arg,
Item_subselect *item_arg, Item_subselect *item_arg,
select_result_interceptor *result_arg, select_result_interceptor *result_arg,
List<Item> *equi_join_conds_arg) List<Item> *equi_join_conds_arg)
:subselect_partial_match_engine(engine_arg, tmp_table_arg, item_arg, :subselect_partial_match_engine(thd_arg, engine_arg, tmp_table_arg,
result_arg, equi_join_conds_arg, item_arg, result_arg, equi_join_conds_arg,
covering_null_row_width_arg), covering_null_row_width_arg),
keys_count(keys_count_arg), non_null_key(NULL) keys_count(keys_count_arg), non_null_key(NULL)
{ {}
thd= lookup_engine->get_thd();
}
~subselect_rowid_merge_engine(); ~subselect_rowid_merge_engine();
bool init(MY_BITMAP *non_null_key_parts, MY_BITMAP *partial_match_key_parts); bool init(MY_BITMAP *non_null_key_parts, MY_BITMAP *partial_match_key_parts);
void cleanup(); void cleanup();
...@@ -1173,7 +1170,8 @@ class subselect_table_scan_engine: public subselect_partial_match_engine ...@@ -1173,7 +1170,8 @@ class subselect_table_scan_engine: public subselect_partial_match_engine
protected: protected:
bool partial_match(); bool partial_match();
public: public:
subselect_table_scan_engine(subselect_uniquesubquery_engine *engine_arg, subselect_table_scan_engine(THD *thd_arg,
subselect_uniquesubquery_engine *engine_arg,
TABLE *tmp_table_arg, Item_subselect *item_arg, TABLE *tmp_table_arg, Item_subselect *item_arg,
select_result_interceptor *result_arg, select_result_interceptor *result_arg,
List<Item> *equi_join_conds_arg, List<Item> *equi_join_conds_arg,
......
...@@ -19518,10 +19518,7 @@ void TABLE_LIST::print(THD *thd, table_map eliminated_tables, String *str, ...@@ -19518,10 +19518,7 @@ void TABLE_LIST::print(THD *thd, table_map eliminated_tables, String *str,
void st_select_lex::print(THD *thd, String *str, enum_query_type query_type) void st_select_lex::print(THD *thd, String *str, enum_query_type query_type)
{ {
/* TODO: thd may not be set for sub queries, but this should be fixed */
DBUG_ASSERT(thd); DBUG_ASSERT(thd);
if (!thd)
thd= current_thd;
str->append(STRING_WITH_LEN("select ")); str->append(STRING_WITH_LEN("select "));
......
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