mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
added mem_root switching for subselect if it is necessary
(bug #518 fixed) mysql-test/r/subselect.result: test of bug #518 mysql-test/t/subselect.test: test of bug #518 sql/item_subselect.cc: test and switch mem_root if it is necessary exec() - wrapper around engine->exec() to test and switch mem_root if necessary sql/item_subselect.h: added storing THD for mem_root testinmg & switching exec() - wrapper around engine->exec() to test and switch mem_root if necessary
This commit is contained in:
@ -1134,3 +1134,17 @@ id select_type table type possible_keys key key_len ref rows Extra
|
|||||||
1 PRIMARY t1 ref salary salary 5 const 1 Using where
|
1 PRIMARY t1 ref salary salary 5 const 1 Using where
|
||||||
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
|
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
CREATE TABLE t1 (
|
||||||
|
ID int(10) unsigned NOT NULL auto_increment,
|
||||||
|
SUB_ID int(3) unsigned NOT NULL default '0',
|
||||||
|
REF_ID int(10) unsigned default NULL,
|
||||||
|
REF_SUB int(3) unsigned default '0',
|
||||||
|
PRIMARY KEY (ID,SUB_ID),
|
||||||
|
UNIQUE KEY t1_PK (ID,SUB_ID),
|
||||||
|
KEY t1_FK (REF_ID,REF_SUB),
|
||||||
|
KEY t1_REFID (REF_ID)
|
||||||
|
) TYPE=MyISAM CHARSET=cp1251;
|
||||||
|
INSERT INTO t1 VALUES (1,0,NULL,NULL),(2,0,NULL,NULL);
|
||||||
|
SELECT DISTINCT REF_ID FROM t1 WHERE ID= (SELECT DISTINCT REF_ID FROM t1 WHERE ID=2);
|
||||||
|
REF_ID
|
||||||
|
DROP TABLE t1;
|
||||||
|
@ -716,3 +716,17 @@ create table t1 (id int not null auto_increment primary key, salary int, key(sal
|
|||||||
insert into t1 (salary) values (100),(1000),(10000),(10),(500),(5000),(50000);
|
insert into t1 (salary) values (100),(1000),(10000),(10),(500),(5000),(50000);
|
||||||
explain SELECT id FROM t1 where salary = (SELECT MAX(salary) FROM t1);
|
explain SELECT id FROM t1 where salary = (SELECT MAX(salary) FROM t1);
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1 (
|
||||||
|
ID int(10) unsigned NOT NULL auto_increment,
|
||||||
|
SUB_ID int(3) unsigned NOT NULL default '0',
|
||||||
|
REF_ID int(10) unsigned default NULL,
|
||||||
|
REF_SUB int(3) unsigned default '0',
|
||||||
|
PRIMARY KEY (ID,SUB_ID),
|
||||||
|
UNIQUE KEY t1_PK (ID,SUB_ID),
|
||||||
|
KEY t1_FK (REF_ID,REF_SUB),
|
||||||
|
KEY t1_REFID (REF_ID)
|
||||||
|
) TYPE=MyISAM CHARSET=cp1251;
|
||||||
|
INSERT INTO t1 VALUES (1,0,NULL,NULL),(2,0,NULL,NULL);
|
||||||
|
SELECT DISTINCT REF_ID FROM t1 WHERE ID= (SELECT DISTINCT REF_ID FROM t1 WHERE ID=2);
|
||||||
|
DROP TABLE t1;
|
||||||
|
@ -79,8 +79,10 @@ void Item_subselect::select_transformer(THD *thd, st_select_lex_unit *unit)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Item_subselect::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
|
bool Item_subselect::fix_fields(THD *thd_param, TABLE_LIST *tables, Item **ref)
|
||||||
{
|
{
|
||||||
|
thd= thd_param;
|
||||||
|
|
||||||
if (substitution)
|
if (substitution)
|
||||||
{
|
{
|
||||||
(*ref)= substitution;
|
(*ref)= substitution;
|
||||||
@ -115,6 +117,20 @@ bool Item_subselect::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Item_subselect::exec()
|
||||||
|
{
|
||||||
|
MEM_ROOT *old_root= my_pthread_getspecific_ptr(MEM_ROOT*, THR_MALLOC);
|
||||||
|
if (&thd->mem_root != old_root)
|
||||||
|
{
|
||||||
|
my_pthread_setspecific_ptr(THR_MALLOC, &thd->mem_root);
|
||||||
|
int res= engine->exec();
|
||||||
|
my_pthread_setspecific_ptr(THR_MALLOC, old_root);
|
||||||
|
return (res);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return engine->exec();
|
||||||
|
}
|
||||||
|
|
||||||
Item::Type Item_subselect::type() const
|
Item::Type Item_subselect::type() const
|
||||||
{
|
{
|
||||||
return SUBSELECT_ITEM;
|
return SUBSELECT_ITEM;
|
||||||
@ -253,12 +269,12 @@ bool Item_singlerow_subselect::null_inside()
|
|||||||
|
|
||||||
void Item_singlerow_subselect::bring_value()
|
void Item_singlerow_subselect::bring_value()
|
||||||
{
|
{
|
||||||
engine->exec();
|
exec();
|
||||||
}
|
}
|
||||||
|
|
||||||
double Item_singlerow_subselect::val ()
|
double Item_singlerow_subselect::val ()
|
||||||
{
|
{
|
||||||
if (!engine->exec() && !value->null_value)
|
if (!exec() && !value->null_value)
|
||||||
{
|
{
|
||||||
null_value= 0;
|
null_value= 0;
|
||||||
return value->val();
|
return value->val();
|
||||||
@ -272,7 +288,7 @@ double Item_singlerow_subselect::val ()
|
|||||||
|
|
||||||
longlong Item_singlerow_subselect::val_int ()
|
longlong Item_singlerow_subselect::val_int ()
|
||||||
{
|
{
|
||||||
if (!engine->exec() && !value->null_value)
|
if (!exec() && !value->null_value)
|
||||||
{
|
{
|
||||||
null_value= 0;
|
null_value= 0;
|
||||||
return value->val_int();
|
return value->val_int();
|
||||||
@ -286,7 +302,7 @@ longlong Item_singlerow_subselect::val_int ()
|
|||||||
|
|
||||||
String *Item_singlerow_subselect::val_str (String *str)
|
String *Item_singlerow_subselect::val_str (String *str)
|
||||||
{
|
{
|
||||||
if (!engine->exec() && !value->null_value)
|
if (!exec() && !value->null_value)
|
||||||
{
|
{
|
||||||
null_value= 0;
|
null_value= 0;
|
||||||
return value->val_str(str);
|
return value->val_str(str);
|
||||||
@ -354,7 +370,7 @@ void Item_exists_subselect::fix_length_and_dec()
|
|||||||
|
|
||||||
double Item_exists_subselect::val ()
|
double Item_exists_subselect::val ()
|
||||||
{
|
{
|
||||||
if (engine->exec())
|
if (exec())
|
||||||
{
|
{
|
||||||
reset();
|
reset();
|
||||||
return 0;
|
return 0;
|
||||||
@ -364,7 +380,7 @@ double Item_exists_subselect::val ()
|
|||||||
|
|
||||||
longlong Item_exists_subselect::val_int ()
|
longlong Item_exists_subselect::val_int ()
|
||||||
{
|
{
|
||||||
if (engine->exec())
|
if (exec())
|
||||||
{
|
{
|
||||||
reset();
|
reset();
|
||||||
return 0;
|
return 0;
|
||||||
@ -374,7 +390,7 @@ longlong Item_exists_subselect::val_int ()
|
|||||||
|
|
||||||
String *Item_exists_subselect::val_str(String *str)
|
String *Item_exists_subselect::val_str(String *str)
|
||||||
{
|
{
|
||||||
if (engine->exec())
|
if (exec())
|
||||||
{
|
{
|
||||||
reset();
|
reset();
|
||||||
return 0;
|
return 0;
|
||||||
@ -385,7 +401,7 @@ String *Item_exists_subselect::val_str(String *str)
|
|||||||
|
|
||||||
double Item_in_subselect::val ()
|
double Item_in_subselect::val ()
|
||||||
{
|
{
|
||||||
if (engine->exec())
|
if (exec())
|
||||||
{
|
{
|
||||||
reset();
|
reset();
|
||||||
null_value= 1;
|
null_value= 1;
|
||||||
@ -398,7 +414,7 @@ double Item_in_subselect::val ()
|
|||||||
|
|
||||||
longlong Item_in_subselect::val_int ()
|
longlong Item_in_subselect::val_int ()
|
||||||
{
|
{
|
||||||
if (engine->exec())
|
if (exec())
|
||||||
{
|
{
|
||||||
reset();
|
reset();
|
||||||
null_value= 1;
|
null_value= 1;
|
||||||
@ -411,7 +427,7 @@ longlong Item_in_subselect::val_int ()
|
|||||||
|
|
||||||
String *Item_in_subselect::val_str(String *str)
|
String *Item_in_subselect::val_str(String *str)
|
||||||
{
|
{
|
||||||
if (engine->exec())
|
if (exec())
|
||||||
{
|
{
|
||||||
reset();
|
reset();
|
||||||
null_value= 1;
|
null_value= 1;
|
||||||
|
@ -36,6 +36,8 @@ class Item_subselect :public Item_result_field
|
|||||||
my_bool engine_owner; /* Is this item owner of engine */
|
my_bool engine_owner; /* Is this item owner of engine */
|
||||||
my_bool value_assigned; /* value already assigned to subselect */
|
my_bool value_assigned; /* value already assigned to subselect */
|
||||||
protected:
|
protected:
|
||||||
|
/* thread handler, will be assigned in fix_fields only */
|
||||||
|
THD *thd;
|
||||||
/* substitution instead of subselect in case of optimization */
|
/* substitution instead of subselect in case of optimization */
|
||||||
Item *substitution;
|
Item *substitution;
|
||||||
/* engine that perform execution of subselect (single select or union) */
|
/* engine that perform execution of subselect (single select or union) */
|
||||||
@ -81,6 +83,7 @@ public:
|
|||||||
return null_value;
|
return null_value;
|
||||||
}
|
}
|
||||||
bool fix_fields(THD *thd, TABLE_LIST *tables, Item **ref);
|
bool fix_fields(THD *thd, TABLE_LIST *tables, Item **ref);
|
||||||
|
bool exec();
|
||||||
virtual void fix_length_and_dec();
|
virtual void fix_length_and_dec();
|
||||||
table_map used_tables() const;
|
table_map used_tables() const;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user