summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <bell@sanja.is.com.ua>2004-06-09 23:32:20 +0300
committerunknown <bell@sanja.is.com.ua>2004-06-09 23:32:20 +0300
commit07b5fdbcdb656b46c83d3585dc548107b5711609 (patch)
tree245eec6a233c1233f75284cfd2d619b0afe4c28b
parent5304a03e997d520a60d98a5e27da92a0d3efb8d0 (diff)
downloadmariadb-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.result10
-rw-r--r--mysql-test/t/subselect_innodb.test10
-rw-r--r--sql/item_subselect.cc5
-rw-r--r--sql/sql_lex.cc2
-rw-r--r--sql/sql_lex.h5
-rw-r--r--sql/sql_select.cc3
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;