diff options
author | unknown <bell@sanja.is.com.ua> | 2004-06-09 23:32:20 +0300 |
---|---|---|
committer | unknown <bell@sanja.is.com.ua> | 2004-06-09 23:32:20 +0300 |
commit | 07b5fdbcdb656b46c83d3585dc548107b5711609 (patch) | |
tree | 245eec6a233c1233f75284cfd2d619b0afe4c28b | |
parent | 5304a03e997d520a60d98a5e27da92a0d3efb8d0 (diff) | |
download | mariadb-git-07b5fdbcdb656b46c83d3585dc548107b5711609.tar.gz |
do not unlock tables early if we have subquery in HAVING clause (BUG#3984)
mysql-test/r/subselect_innodb.result:
test of unlocking innodb tables and subquery in HAVING clause
mysql-test/t/subselect_innodb.test:
test of unlocking innodb tables and subquery in HAVING clause
sql/item_subselect.cc:
mark SELECT with subquery in HAVING clause
sql/sql_lex.cc:
mark SELECT with subquery in HAVING clause
sql/sql_lex.h:
mark SELECT with subquery in HAVING clause
sql/sql_select.cc:
do not unlock tables early if we have subquery in HAVING clause
-rw-r--r-- | mysql-test/r/subselect_innodb.result | 10 | ||||
-rw-r--r-- | mysql-test/t/subselect_innodb.test | 10 | ||||
-rw-r--r-- | sql/item_subselect.cc | 5 | ||||
-rw-r--r-- | sql/sql_lex.cc | 2 | ||||
-rw-r--r-- | sql/sql_lex.h | 5 | ||||
-rw-r--r-- | sql/sql_select.cc | 3 |
6 files changed, 33 insertions, 2 deletions
diff --git a/mysql-test/r/subselect_innodb.result b/mysql-test/r/subselect_innodb.result index 9c1816e295c..bbbc607b6f8 100644 --- a/mysql-test/r/subselect_innodb.result +++ b/mysql-test/r/subselect_innodb.result @@ -96,3 +96,13 @@ id value (select t1.value from t1 where t1.id=t2.id) 1 z a 2 x b 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; diff --git a/mysql-test/t/subselect_innodb.test b/mysql-test/t/subselect_innodb.test index 47642832158..8c13171d221 100644 --- a/mysql-test/t/subselect_innodb.test +++ b/mysql-test/t/subselect_innodb.test @@ -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; 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; diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 4503c1b63a9..6f6917b8823 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -74,6 +74,11 @@ void Item_subselect::init(st_select_lex *select_lex, else 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; } diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index f98a6b43846..ef52f4b9271 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -1022,7 +1022,7 @@ void st_select_lex::init_query() ref_pointer_array= 0; select_n_having_items= 0; prep_where= 0; - explicit_limit= 0; + subquery_in_having= explicit_limit= 0; } void st_select_lex::init_select() diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 36e05b40c7d..6ecdcda46dc 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -433,6 +433,11 @@ public: bool having_fix_field; /* explicit LIMIT clause was used */ 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 diff --git a/sql/sql_select.cc b/sql/sql_select.cc index f7a0d5259a6..77d18b8fc97 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -3902,7 +3902,8 @@ JOIN::join_free(bool full) */ if ((full || !select_lex->uncacheable) && 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 lock=0; |