Commit a100c0e9 authored by unknown's avatar unknown

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
parent 15b3f3a0
...@@ -1134,3 +1134,17 @@ id select_type table type possible_keys key key_len ref rows Extra ...@@ -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 ...@@ -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) ...@@ -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) ...@@ -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() ...@@ -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 () ...@@ -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 () ...@@ -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() ...@@ -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 () ...@@ -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 () ...@@ -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) ...@@ -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 () ...@@ -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 () ...@@ -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 ...@@ -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 @@ class Item_subselect :public Item_result_field ...@@ -81,6 +83,7 @@ class Item_subselect :public Item_result_field
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;
......
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