1
0
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:
unknown
2010-12-14 14:08:05 +02:00
parent 419d524ff9
commit 4f28dcbe32
3 changed files with 34 additions and 36 deletions

View File

@ -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)
{} {}

View File

@ -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,

View File

@ -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 "));