Commit 98a7b49d authored by bell@sanja.is.com.ua's avatar bell@sanja.is.com.ua

do not unlock tables early if we have subquery in HAVING clause (BUG#3984)

parent 1b76aa07
...@@ -96,3 +96,13 @@ id value (select t1.value from t1 where t1.id=t2.id) ...@@ -96,3 +96,13 @@ id value (select t1.value from t1 where t1.id=t2.id)
1 z a 1 z a
2 x b 2 x b
drop table t1,t2; drop table t1,t2;
create table t1 (a int, b int) engine=innodb;
insert into t1 values (1,2), (1,3), (2,3), (2,4), (2,5), (3,4), (4,5), (4,100);
create table t2 (a int) engine=innodb;
insert into t2 values (1),(2),(3),(4);
select a, sum(b) as b from t1 group by a having b > (select max(a) from t2);
a b
1 5
2 12
4 105
drop table t1, t2;
...@@ -101,3 +101,13 @@ insert into t2 values (1,'z'),(2,'x'); ...@@ -101,3 +101,13 @@ insert into t2 values (1,'z'),(2,'x');
select t2.id,t2.value,(select t1.value from t1 where t1.id=t2.id) from t2; select t2.id,t2.value,(select t1.value from t1 where t1.id=t2.id) from t2;
select t2.id,t2.value,(select t1.value from t1 where t1.id=t2.id) from t2; select t2.id,t2.value,(select t1.value from t1 where t1.id=t2.id) from t2;
drop table t1,t2; drop table t1,t2;
#
# unlocking tables with subqueries in HAVING
#
create table t1 (a int, b int) engine=innodb;
insert into t1 values (1,2), (1,3), (2,3), (2,4), (2,5), (3,4), (4,5), (4,100);
create table t2 (a int) engine=innodb;
insert into t2 values (1),(2),(3),(4);
select a, sum(b) as b from t1 group by a having b > (select max(a) from t2);
drop table t1, t2;
...@@ -74,6 +74,11 @@ void Item_subselect::init(st_select_lex *select_lex, ...@@ -74,6 +74,11 @@ void Item_subselect::init(st_select_lex *select_lex,
else else
engine= new subselect_single_select_engine(select_lex, result, this); engine= new subselect_single_select_engine(select_lex, result, this);
} }
{
SELECT_LEX *upper= unit->outer_select();
if (upper->parsing_place == SELECT_LEX_NODE::IN_HAVING)
upper->subquery_in_having= 1;
}
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
......
...@@ -1022,7 +1022,7 @@ void st_select_lex::init_query() ...@@ -1022,7 +1022,7 @@ void st_select_lex::init_query()
ref_pointer_array= 0; ref_pointer_array= 0;
select_n_having_items= 0; select_n_having_items= 0;
prep_where= 0; prep_where= 0;
explicit_limit= 0; subquery_in_having= explicit_limit= 0;
} }
void st_select_lex::init_select() void st_select_lex::init_select()
......
...@@ -433,6 +433,11 @@ public: ...@@ -433,6 +433,11 @@ public:
bool having_fix_field; bool having_fix_field;
/* explicit LIMIT clause was used */ /* explicit LIMIT clause was used */
bool explicit_limit; bool explicit_limit;
/*
there are subquery in HAVING clause => we can't close tables before
query processing end even if we use temporary table
*/
bool subquery_in_having;
/* /*
SELECT for SELECT command st_select_lex. Used to privent scaning SELECT for SELECT command st_select_lex. Used to privent scaning
......
...@@ -3902,7 +3902,8 @@ JOIN::join_free(bool full) ...@@ -3902,7 +3902,8 @@ JOIN::join_free(bool full)
*/ */
if ((full || !select_lex->uncacheable) && if ((full || !select_lex->uncacheable) &&
lock && thd->lock && lock && thd->lock &&
!(select_options & SELECT_NO_UNLOCK)) !(select_options & SELECT_NO_UNLOCK) &&
!select_lex->subquery_in_having)
{ {
mysql_unlock_read_tables(thd, lock);// Don't free join->lock mysql_unlock_read_tables(thd, lock);// Don't free join->lock
lock=0; lock=0;
......
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