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,
DBUG_ENTER("Item_subselect::init");
DBUG_PRINT("enter", ("select_lex: 0x%lx", (long) select_lex));
unit= select_lex->master_unit();
thd= unit->thd;
if (unit->item)
{
......@@ -76,6 +77,7 @@ void Item_subselect::init(st_select_lex *select_lex,
else
{
SELECT_LEX *outer_select= unit->outer_select();
DBUG_ASSERT(thd);
/*
do not take into account expression inside aggregate functions because
they can access original table fields
......@@ -84,9 +86,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(unit, result, this);
engine= new subselect_union_engine(thd, unit, result, this);
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();
......@@ -183,7 +185,8 @@ bool Item_subselect::fix_fields(THD *thd_param, Item **ref)
bool res;
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)
{
done_first_fix_fields= TRUE;
......@@ -2384,10 +2387,10 @@ void subselect_engine::set_thd(THD *thd_arg)
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,
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)
{
select_lex->master_unit()->item= item_arg;
......@@ -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,
Item_subselect *item_arg)
:subselect_engine(item_arg, result_arg)
:subselect_engine(thd_arg, item_arg, result_arg)
{
unit= u;
if (!result_arg) //out of memory
......@@ -4164,7 +4167,7 @@ int subselect_hash_sj_engine::exec()
if (strategy == PARTIAL_MATCH_MERGE)
{
pm_engine=
new subselect_rowid_merge_engine((subselect_uniquesubquery_engine*)
new subselect_rowid_merge_engine(thd, (subselect_uniquesubquery_engine*)
lookup_engine, tmp_table,
count_pm_keys,
covering_null_row_width,
......@@ -4188,7 +4191,7 @@ int subselect_hash_sj_engine::exec()
if (strategy == PARTIAL_MATCH_SCAN)
{
if (!(pm_engine=
new subselect_table_scan_engine((subselect_uniquesubquery_engine*)
new subselect_table_scan_engine(thd, (subselect_uniquesubquery_engine*)
lookup_engine, tmp_table,
item, result,
semi_join_conds->argument_list(),
......@@ -4623,12 +4626,12 @@ void Ordered_key::print(String *str)
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,
select_result_interceptor *result_arg,
List<Item> *equi_join_conds_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),
equi_join_conds(equi_join_conds_arg),
covering_null_row_width(covering_null_row_width_arg)
......@@ -5144,13 +5147,13 @@ bool subselect_rowid_merge_engine::partial_match()
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,
Item_subselect *item_arg,
select_result_interceptor *result_arg,
List<Item> *equi_join_conds_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,
covering_null_row_width_arg)
{}
......
......@@ -501,14 +501,15 @@ class subselect_engine: public Sql_alloc
INDEXSUBQUERY_ENGINE, HASH_SJ_ENGINE,
ROWID_MERGE_ENGINE, TABLE_SCAN_ENGINE};
subselect_engine(Item_subselect *si, select_result_interceptor *res)
:thd(0)
subselect_engine(THD *thd_arg, Item_subselect *si,
select_result_interceptor *res)
{
result= res;
item= si;
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;
......@@ -572,7 +573,7 @@ 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(st_select_lex *select,
subselect_single_select_engine(THD *thd_arg, st_select_lex *select,
select_result_interceptor *result,
Item_subselect *item);
void cleanup();
......@@ -601,7 +602,7 @@ class subselect_union_engine: public subselect_engine
{
st_select_lex_unit *unit; /* corresponding unit structure */
public:
subselect_union_engine(st_select_lex_unit *u,
subselect_union_engine(THD *thd_arg, st_select_lex_unit *u,
select_result_interceptor *result,
Item_subselect *item);
void cleanup();
......@@ -657,10 +658,8 @@ 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(subs, 0), tab(tab_arg), cond(where)
{
set_thd(thd_arg);
}
:subselect_engine(thd_arg, subs, 0), tab(tab_arg), cond(where)
{}
~subselect_uniquesubquery_engine();
void cleanup();
int prepare();
......@@ -812,13 +811,11 @@ class subselect_hash_sj_engine : public subselect_engine
public:
subselect_hash_sj_engine(THD *thd, Item_subselect *in_predicate,
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),
materialize_join(NULL), count_partial_match_columns(0),
count_null_only_columns(0), semi_join_conds(NULL), strategy(UNDEFINED)
{
set_thd(thd);
}
{}
~subselect_hash_sj_engine();
bool init_permanent(List<Item> *tmp_columns);
......@@ -1056,7 +1053,8 @@ class subselect_partial_match_engine : public subselect_engine
protected:
virtual bool partial_match()= 0;
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,
select_result_interceptor *result_arg,
List<Item> *equi_join_conds_arg,
......@@ -1148,19 +1146,18 @@ class subselect_rowid_merge_engine: public subselect_partial_match_engine
bool test_null_row(rownum_t row_num);
bool partial_match();
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,
uint covering_null_row_width_arg,
Item_subselect *item_arg,
select_result_interceptor *result_arg,
List<Item> *equi_join_conds_arg)
:subselect_partial_match_engine(engine_arg, tmp_table_arg, item_arg,
result_arg, equi_join_conds_arg,
:subselect_partial_match_engine(thd_arg, engine_arg, tmp_table_arg,
item_arg, result_arg, equi_join_conds_arg,
covering_null_row_width_arg),
keys_count(keys_count_arg), non_null_key(NULL)
{
thd= lookup_engine->get_thd();
}
{}
~subselect_rowid_merge_engine();
bool init(MY_BITMAP *non_null_key_parts, MY_BITMAP *partial_match_key_parts);
void cleanup();
......@@ -1173,7 +1170,8 @@ class subselect_table_scan_engine: public subselect_partial_match_engine
protected:
bool partial_match();
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,
select_result_interceptor *result_arg,
List<Item> *equi_join_conds_arg,
......
......@@ -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)
{
/* TODO: thd may not be set for sub queries, but this should be fixed */
DBUG_ASSERT(thd);
if (!thd)
thd= current_thd;
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