diff --git a/mysql-test/t/subselect_innodb.test b/mysql-test/t/subselect_innodb.test index 5f4badb3624..54c56e640dc 100644 --- a/mysql-test/t/subselect_innodb.test +++ b/mysql-test/t/subselect_innodb.test @@ -125,3 +125,12 @@ INSERT INTO `t2` VALUES ('yy','xx'); SELECT R.unit, R.ingredient FROM t1 R WHERE R.ingredient IN (SELECT N.ingredient FROM t2 N WHERE N.unit = R.unit); drop table t1, t2; + +# +# possible early unlock +# +CREATE TABLE t1 ( id INT NOT NULL auto_increment, date1 DATE, coworkerid INT, description VARCHAR(255), sum_used DOUBLE, sum_remaining DOUBLE, comments VARCHAR(255), PRIMARY KEY(id)) engine=innodb; +insert into t1 values (NULL, '1999-01-01', 1,'test', 22, 33, 'comment'), (NULL, '1999-01-01', 1,'test', 22, 33, 'comment'), (NULL, '1999-01-01', 1,'test', 22, 33, 'comment'), (NULL, '1998-01-01', 1,'test', 22, 33, 'comment'), (NULL, '1998-01-01', 1,'test', 22, 33, 'comment'), (NULL, '2004-01-01', 1,'test', 22, 33, 'comment'), (NULL, '2004-01-01', 1,'test', 22, 33, 'comment'); +SELECT DISTINCT (SELECT sum(sum_used) FROM t1 WHERE sum_used > 0 AND year(date1) <= '2004') as somallontvangsten, (SELECT sum(sum_used) FROM t1 WHERE sum_used < 0 AND year(date1) <= '2004') as somalluitgaven FROM t1; +select * from t1; +drop table t1; diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index b5cb8735875..1d9afcc94a4 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -135,7 +135,7 @@ void lex_start(THD *thd, uchar *buf,uint length) lex->select_lex.link_prev= (st_select_lex_node**)&(lex->all_selects_list); lex->select_lex.options= 0; lex->describe= 0; - lex->derived_tables= FALSE; + lex->subqueries= lex->derived_tables= FALSE; lex->lock_option= TL_READ; lex->found_colon= 0; lex->safe_to_cache_query= 1; diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 90c020b3e93..123e855061a 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -619,6 +619,7 @@ typedef struct st_lex bool in_comment, ignore_space, verbose, no_write_to_binlog; bool derived_tables; bool safe_to_cache_query; + bool subqueries; ALTER_INFO alter_info; /* Prepared statements SQL syntax:*/ LEX_STRING prepared_stmt_name; /* Statement name (in all queries) */ diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 078333c9552..ad68402aeab 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -3955,6 +3955,7 @@ mysql_new_select(LEX *lex, bool move_down) select_lex->init_select(); if (move_down) { + lex->subqueries= TRUE; /* first select_lex of subselect or derived table */ SELECT_LEX_UNIT *unit; if (!(unit= new(lex->thd->mem_root) SELECT_LEX_UNIT())) diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 5809bd2b7be..ec7ea9091be 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -936,7 +936,7 @@ JOIN::optimize() } } - if (select_lex->uncacheable) + if (thd->lex->subqueries) { if (!(tmp_join= (JOIN*)thd->alloc(sizeof(JOIN)))) DBUG_RETURN(-1); @@ -3834,6 +3834,7 @@ JOIN::join_free(bool full) DBUG_ENTER("JOIN::join_free"); full= full || (!select_lex->uncacheable && + !thd->lex->subqueries && !thd->lex->describe); // do not cleanup too early on EXPLAIN if (table)