From e756a511f816a8dc7509d52e684d11448663d766 Mon Sep 17 00:00:00 2001 From: "bell@sanja.is.com.ua" <> Date: Wed, 10 Dec 2003 22:46:14 +0200 Subject: [PATCH] fixed unlocking tables during subquery execution (BUG#2048) --- mysql-test/r/subselect_innodb.result | 20 ++++++++++++++++++++ mysql-test/t/subselect_innodb.test | 24 +++++++++++++++++++++++- sql/item_subselect.cc | 5 +++-- sql/sql_derived.cc | 2 +- sql/sql_lex.h | 2 +- sql/sql_union.cc | 7 ++++--- 6 files changed, 52 insertions(+), 8 deletions(-) diff --git a/mysql-test/r/subselect_innodb.result b/mysql-test/r/subselect_innodb.result index 2f5b92fd05d..83ff5209e58 100644 --- a/mysql-test/r/subselect_innodb.result +++ b/mysql-test/r/subselect_innodb.result @@ -63,3 +63,23 @@ processor_id (SELECT y.yod_id FROM t1 p2, t2 y WHERE p2.processor_id = p1.proces 2 1 3 1 drop table t1,t2,t3; +CREATE TABLE t1 ( +id int(11) NOT NULL default '0', +b int(11) default NULL, +c char(3) default NULL, +PRIMARY KEY (id), +KEY t2i1 (b) +) TYPE=innodb DEFAULT CHARSET=latin1; +INSERT INTO t1 VALUES (0,0,'GPL'),(1,0,'GPL'),(2,1,'GPL'),(3,2,'GPL'); +CREATE TABLE t2 ( +id int(11) NOT NULL default '0', +b int(11) default NULL, +c char(3) default NULL, +PRIMARY KEY (id), +KEY t2i (b) +) TYPE=innodb DEFAULT CHARSET=latin1; +INSERT INTO t2 VALUES (0,0,'GPL'),(1,0,'GPL'),(2,1,'GPL'),(3,2,'GPL'); +select (select max(id) from t2 where b=1 group by b) as x,b from t1 where b=1; +x b +2 1 +drop table t1,t2; diff --git a/mysql-test/t/subselect_innodb.test b/mysql-test/t/subselect_innodb.test index 5e274ecbd5c..360bedf8972 100644 --- a/mysql-test/t/subselect_innodb.test +++ b/mysql-test/t/subselect_innodb.test @@ -67,4 +67,26 @@ INSERT INTO t1 VALUES (1),(2),(3); INSERT INTO t3 VALUES (1,1),(2,2),(3,3); INSERT INTO t2 VALUES (1,1),(2,2),(3,3); SELECT distinct p1.processor_id, (SELECT y.yod_id FROM t1 p2, t2 y WHERE p2.processor_id = p1.processor_id and p2.processor_id = y.processor_id) FROM t1 p1; -drop table t1,t2,t3; \ No newline at end of file +drop table t1,t2,t3; + +# +# innodb locking +# +CREATE TABLE t1 ( + id int(11) NOT NULL default '0', + b int(11) default NULL, + c char(3) default NULL, + PRIMARY KEY (id), + KEY t2i1 (b) +) TYPE=innodb DEFAULT CHARSET=latin1; +INSERT INTO t1 VALUES (0,0,'GPL'),(1,0,'GPL'),(2,1,'GPL'),(3,2,'GPL'); +CREATE TABLE t2 ( + id int(11) NOT NULL default '0', + b int(11) default NULL, + c char(3) default NULL, + PRIMARY KEY (id), + KEY t2i (b) +) TYPE=innodb DEFAULT CHARSET=latin1; +INSERT INTO t2 VALUES (0,0,'GPL'),(1,0,'GPL'),(2,1,'GPL'),(3,2,'GPL'); +select (select max(id) from t2 where b=1 group by b) as x,b from t1 where b=1; +drop table t1,t2; diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 7b401b50d4c..04458a7961a 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -906,7 +906,8 @@ int subselect_single_select_engine::prepare() { if (prepared) return 0; - join= new JOIN(thd, select_lex->item_list, select_lex->options, result); + join= new JOIN(thd, select_lex->item_list, + select_lex->options | SELECT_NO_UNLOCK, result); if (!join || !result) { thd->fatal_error(); //out of memory @@ -933,7 +934,7 @@ int subselect_single_select_engine::prepare() int subselect_union_engine::prepare() { - return unit->prepare(thd, result); + return unit->prepare(thd, result, SELECT_NO_UNLOCK); } int subselect_uniquesubquery_engine::prepare() diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index e8f1c5d87de..10d2254969a 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -114,7 +114,7 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit, DBUG_RETURN(1); // out of memory // st_select_lex_unit::prepare correctly work for single select - if ((res= unit->prepare(thd, derived_result))) + if ((res= unit->prepare(thd, derived_result, 0))) goto exit; /* diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 15da6ca57a3..d8344403097 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -351,7 +351,7 @@ public: void exclude_tree(); /* UNION methods */ - int prepare(THD *thd, select_result *result); + int prepare(THD *thd, select_result *result, ulong additional_options); int exec(); int cleanup(); diff --git a/sql/sql_union.cc b/sql/sql_union.cc index f2470a59944..435354cb4ad 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -29,7 +29,7 @@ int mysql_union(THD *thd, LEX *lex, select_result *result, { DBUG_ENTER("mysql_union"); int res= 0; - if (!(res= unit->prepare(thd, result))) + if (!(res= unit->prepare(thd, result, SELECT_NO_UNLOCK))) res= unit->exec(); res|= unit->cleanup(); DBUG_RETURN(res); @@ -106,7 +106,8 @@ bool select_union::flush() } -int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result) +int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, + ulong additional_options) { SELECT_LEX *lex_select_save= thd_arg->lex.current_select; SELECT_LEX *sl, *first_select; @@ -146,7 +147,7 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result) for (;sl; sl= sl->next_select()) { JOIN *join= new JOIN(thd_arg, sl->item_list, - sl->options | thd_arg->options | SELECT_NO_UNLOCK, + sl->options | thd_arg->options | additional_options, tmp_result); thd_arg->lex.current_select= sl; offset_limit_cnt= sl->offset_limit;