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_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,
|
|||||||
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,
|
|||||||
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)
|
|||||||
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)
|
|||||||
|
|
||||||
|
|
||||||
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()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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()
|
|||||||
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()
|
|||||||
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)
|
|||||||
|
|
||||||
|
|
||||||
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 @@ end:
|
|||||||
|
|
||||||
|
|
||||||
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 @@ public:
|
|||||||
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
|
|||||||
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
|
|||||||
{
|
{
|
||||||
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 @@ public:
|
|||||||
// 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 @@ protected:
|
|||||||
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 @@ protected:
|
|||||||
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 @@ protected:
|
|||||||
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
|
|||||||
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,
|
|||||||
|
|
||||||
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 "));
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user