mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
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.
This commit is contained in:
@ -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 @@ end:
|
||||
|
||||
|
||||
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 @@ public:
|
||||
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 @@ 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(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 @@ protected:
|
||||
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 @@ protected:
|
||||
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 @@ protected:
|
||||
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 "));
|
||||
|
||||
|
Reference in New Issue
Block a user