Hi Sanja, It is very difficult to understand this patch. What is the exact meaning of left_expr_orig? It is declared but has no comments.
It is interesting that convert_subq_to_sj has got new code to handle scalar comparison case ( foo IN (SELECT bar ...)), while there is no handling for tuple comparison ( (foo1,foo2) IN (SELECT bar1,bar2 ..)). Is this intentional? On Thu, Apr 23, 2015 at 08:09:00PM +0200, [email protected] wrote: > revision-id: 9f8a458fb2d07298810bb5d9824ce728017bfb32 > parent(s): e540d023e2ec6f37efc9ab695ccdfd4a6744ad64 > committer: Oleksandr Byelkin > branch nick: server > timestamp: 2015-04-23 20:08:57 +0200 > message: > > MDEV-7846: Server crashes in Item_subselect::fix_fields or fails with Thread > stack overrun > > Substitute into transformed subselects original left expression and than > register its change in case it was substituted. > > --- > mysql-test/r/subselect.result | 28 +++++++++++++++++++++++++ > mysql-test/r/subselect_no_mat.result | 28 +++++++++++++++++++++++++ > mysql-test/r/subselect_no_opts.result | 28 +++++++++++++++++++++++++ > mysql-test/r/subselect_no_scache.result | 28 +++++++++++++++++++++++++ > mysql-test/r/subselect_no_semijoin.result | 28 +++++++++++++++++++++++++ > mysql-test/t/subselect.test | 34 > +++++++++++++++++++++++++++++++ > sql/item_cmpfunc.cc | 8 ++++---- > sql/item_subselect.cc | 8 +++----- > sql/item_subselect.h | 1 + > sql/opt_subselect.cc | 4 +++- > 10 files changed, 185 insertions(+), 10 deletions(-) > > diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result > index 0ab2d48..cf52ba2 100644 > --- a/mysql-test/r/subselect.result > +++ b/mysql-test/r/subselect.result > @@ -7053,3 +7053,31 @@ WHERE h.host in (SELECT host FROM mysql.user) > ) AS sq > FROM mysql.host h GROUP BY h.host; > sq > +# > +# MDEV-7846:Server crashes in Item_subselect::fix > +#_fields or fails with Thread stack overrun > +# > +CREATE TABLE t1 (column1 INT) ENGINE=MyISAM; > +INSERT INTO t1 VALUES (3),(9); > +CREATE TABLE t2 (column2 INT) ENGINE=MyISAM; > +INSERT INTO t2 VALUES (1),(4); > +CREATE TABLE t3 (column3 INT) ENGINE=MyISAM; > +INSERT INTO t3 VALUES (6),(8); > +CREATE TABLE t4 (column4 INT) ENGINE=MyISAM; > +INSERT INTO t4 VALUES (2),(5); > +PREPARE stmt FROM " > +SELECT ( > + SELECT MAX( table1.column1 ) AS field1 > + FROM t1 AS table1 > + WHERE table3.column3 IN ( SELECT table2.column2 AS field2 FROM t2 AS > table2 ) > +) AS sq > +FROM t3 AS table3, t4 AS table4 GROUP BY sq > +"; > +EXECUTE stmt; > +sq > +NULL > +EXECUTE stmt; > +sq > +NULL > +deallocate prepare stmt; > +drop table t1,t2,t3,t4; > diff --git a/mysql-test/r/subselect_no_mat.result > b/mysql-test/r/subselect_no_mat.result > index 5780351..73a69e9 100644 > --- a/mysql-test/r/subselect_no_mat.result > +++ b/mysql-test/r/subselect_no_mat.result > @@ -7050,6 +7050,34 @@ WHERE h.host in (SELECT host FROM mysql.user) > ) AS sq > FROM mysql.host h GROUP BY h.host; > sq > +# > +# MDEV-7846:Server crashes in Item_subselect::fix > +#_fields or fails with Thread stack overrun > +# > +CREATE TABLE t1 (column1 INT) ENGINE=MyISAM; > +INSERT INTO t1 VALUES (3),(9); > +CREATE TABLE t2 (column2 INT) ENGINE=MyISAM; > +INSERT INTO t2 VALUES (1),(4); > +CREATE TABLE t3 (column3 INT) ENGINE=MyISAM; > +INSERT INTO t3 VALUES (6),(8); > +CREATE TABLE t4 (column4 INT) ENGINE=MyISAM; > +INSERT INTO t4 VALUES (2),(5); > +PREPARE stmt FROM " > +SELECT ( > + SELECT MAX( table1.column1 ) AS field1 > + FROM t1 AS table1 > + WHERE table3.column3 IN ( SELECT table2.column2 AS field2 FROM t2 AS > table2 ) > +) AS sq > +FROM t3 AS table3, t4 AS table4 GROUP BY sq > +"; > +EXECUTE stmt; > +sq > +NULL > +EXECUTE stmt; > +sq > +NULL > +deallocate prepare stmt; > +drop table t1,t2,t3,t4; > set optimizer_switch=default; > select @@optimizer_switch like '%materialization=on%'; > @@optimizer_switch like '%materialization=on%' > diff --git a/mysql-test/r/subselect_no_opts.result > b/mysql-test/r/subselect_no_opts.result > index 4bea029..1512e39 100644 > --- a/mysql-test/r/subselect_no_opts.result > +++ b/mysql-test/r/subselect_no_opts.result > @@ -7048,4 +7048,32 @@ WHERE h.host in (SELECT host FROM mysql.user) > ) AS sq > FROM mysql.host h GROUP BY h.host; > sq > +# > +# MDEV-7846:Server crashes in Item_subselect::fix > +#_fields or fails with Thread stack overrun > +# > +CREATE TABLE t1 (column1 INT) ENGINE=MyISAM; > +INSERT INTO t1 VALUES (3),(9); > +CREATE TABLE t2 (column2 INT) ENGINE=MyISAM; > +INSERT INTO t2 VALUES (1),(4); > +CREATE TABLE t3 (column3 INT) ENGINE=MyISAM; > +INSERT INTO t3 VALUES (6),(8); > +CREATE TABLE t4 (column4 INT) ENGINE=MyISAM; > +INSERT INTO t4 VALUES (2),(5); > +PREPARE stmt FROM " > +SELECT ( > + SELECT MAX( table1.column1 ) AS field1 > + FROM t1 AS table1 > + WHERE table3.column3 IN ( SELECT table2.column2 AS field2 FROM t2 AS > table2 ) > +) AS sq > +FROM t3 AS table3, t4 AS table4 GROUP BY sq > +"; > +EXECUTE stmt; > +sq > +NULL > +EXECUTE stmt; > +sq > +NULL > +deallocate prepare stmt; > +drop table t1,t2,t3,t4; > set @optimizer_switch_for_subselect_test=null; > diff --git a/mysql-test/r/subselect_no_scache.result > b/mysql-test/r/subselect_no_scache.result > index fdb3b12..26cea1f 100644 > --- a/mysql-test/r/subselect_no_scache.result > +++ b/mysql-test/r/subselect_no_scache.result > @@ -7059,6 +7059,34 @@ WHERE h.host in (SELECT host FROM mysql.user) > ) AS sq > FROM mysql.host h GROUP BY h.host; > sq > +# > +# MDEV-7846:Server crashes in Item_subselect::fix > +#_fields or fails with Thread stack overrun > +# > +CREATE TABLE t1 (column1 INT) ENGINE=MyISAM; > +INSERT INTO t1 VALUES (3),(9); > +CREATE TABLE t2 (column2 INT) ENGINE=MyISAM; > +INSERT INTO t2 VALUES (1),(4); > +CREATE TABLE t3 (column3 INT) ENGINE=MyISAM; > +INSERT INTO t3 VALUES (6),(8); > +CREATE TABLE t4 (column4 INT) ENGINE=MyISAM; > +INSERT INTO t4 VALUES (2),(5); > +PREPARE stmt FROM " > +SELECT ( > + SELECT MAX( table1.column1 ) AS field1 > + FROM t1 AS table1 > + WHERE table3.column3 IN ( SELECT table2.column2 AS field2 FROM t2 AS > table2 ) > +) AS sq > +FROM t3 AS table3, t4 AS table4 GROUP BY sq > +"; > +EXECUTE stmt; > +sq > +NULL > +EXECUTE stmt; > +sq > +NULL > +deallocate prepare stmt; > +drop table t1,t2,t3,t4; > set optimizer_switch=default; > select @@optimizer_switch like '%subquery_cache=on%'; > @@optimizer_switch like '%subquery_cache=on%' > diff --git a/mysql-test/r/subselect_no_semijoin.result > b/mysql-test/r/subselect_no_semijoin.result > index cb6d35d..4c6f037 100644 > --- a/mysql-test/r/subselect_no_semijoin.result > +++ b/mysql-test/r/subselect_no_semijoin.result > @@ -7048,5 +7048,33 @@ WHERE h.host in (SELECT host FROM mysql.user) > ) AS sq > FROM mysql.host h GROUP BY h.host; > sq > +# > +# MDEV-7846:Server crashes in Item_subselect::fix > +#_fields or fails with Thread stack overrun > +# > +CREATE TABLE t1 (column1 INT) ENGINE=MyISAM; > +INSERT INTO t1 VALUES (3),(9); > +CREATE TABLE t2 (column2 INT) ENGINE=MyISAM; > +INSERT INTO t2 VALUES (1),(4); > +CREATE TABLE t3 (column3 INT) ENGINE=MyISAM; > +INSERT INTO t3 VALUES (6),(8); > +CREATE TABLE t4 (column4 INT) ENGINE=MyISAM; > +INSERT INTO t4 VALUES (2),(5); > +PREPARE stmt FROM " > +SELECT ( > + SELECT MAX( table1.column1 ) AS field1 > + FROM t1 AS table1 > + WHERE table3.column3 IN ( SELECT table2.column2 AS field2 FROM t2 AS > table2 ) > +) AS sq > +FROM t3 AS table3, t4 AS table4 GROUP BY sq > +"; > +EXECUTE stmt; > +sq > +NULL > +EXECUTE stmt; > +sq > +NULL > +deallocate prepare stmt; > +drop table t1,t2,t3,t4; > set @optimizer_switch_for_subselect_test=null; > set @join_cache_level_for_subselect_test=NULL; > diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test > index 3eb056d..00ab48b 100644 > --- a/mysql-test/t/subselect.test > +++ b/mysql-test/t/subselect.test > @@ -5930,3 +5930,37 @@ SELECT > WHERE h.host in (SELECT host FROM mysql.user) > ) AS sq > FROM mysql.host h GROUP BY h.host; > + > + > +--echo # > +--echo # MDEV-7846:Server crashes in Item_subselect::fix > +--echo #_fields or fails with Thread stack overrun > +--echo # > +CREATE TABLE t1 (column1 INT) ENGINE=MyISAM; > +INSERT INTO t1 VALUES (3),(9); > + > +CREATE TABLE t2 (column2 INT) ENGINE=MyISAM; > + > +INSERT INTO t2 VALUES (1),(4); > + > +CREATE TABLE t3 (column3 INT) ENGINE=MyISAM; > +INSERT INTO t3 VALUES (6),(8); > + > +CREATE TABLE t4 (column4 INT) ENGINE=MyISAM; > +INSERT INTO t4 VALUES (2),(5); > + > + > +PREPARE stmt FROM " > +SELECT ( > + SELECT MAX( table1.column1 ) AS field1 > + FROM t1 AS table1 > + WHERE table3.column3 IN ( SELECT table2.column2 AS field2 FROM t2 AS > table2 ) > +) AS sq > +FROM t3 AS table3, t4 AS table4 GROUP BY sq > +"; > + > +EXECUTE stmt; > +EXECUTE stmt; > + > +deallocate prepare stmt; > +drop table t1,t2,t3,t4; > diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc > index 51a38f0..29fff8e 100644 > --- a/sql/item_cmpfunc.cc > +++ b/sql/item_cmpfunc.cc > @@ -1455,12 +1455,12 @@ bool Item_in_optimizer::fix_left(THD *thd, Item **ref) > next execution we need to copy args[1]->left_expr again. > */ > ref0= &(((Item_in_subselect *)args[1])->left_expr); > - args[0]= ref0[0]; > } > - if ((!args[0]->fixed && args[0]->fix_fields(thd, ref0)) || > - (!cache && !(cache= Item_cache::get_cache(ref0[0])))) > + if ((!(*ref0)->fixed && (*ref0)->fix_fields(thd, ref0)) || > + (!cache && !(cache= Item_cache::get_cache(*ref0)))) > DBUG_RETURN(1); > - args[0]= ref0[0]; > + if (args[0] != (*ref0)) > + current_thd->change_item_tree(args, (*ref0)); > DBUG_PRINT("info", ("actual fix fields")); > > cache->setup(args[0]); > diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc > index 4c11808..e04f5ff 100644 > --- a/sql/item_subselect.cc > +++ b/sql/item_subselect.cc > @@ -1360,7 +1360,7 @@ Item_in_subselect::Item_in_subselect(Item * left_exp, > upper_item(0) > { > DBUG_ENTER("Item_in_subselect::Item_in_subselect"); > - left_expr= left_exp; > + left_expr_orig= left_expr= left_exp; > func= &eq_creator; > init(select_lex, new select_exists_subselect(this)); > max_columns= UINT_MAX; > @@ -1384,7 +1384,7 @@ Item_allany_subselect::Item_allany_subselect(Item * > left_exp, > :Item_in_subselect(), func_creator(fc), all(all_arg) > { > DBUG_ENTER("Item_allany_subselect::Item_allany_subselect"); > - left_expr= left_exp; > + left_expr_orig= left_expr= left_exp; > func= func_creator(all_arg); > init(select_lex, new select_exists_subselect(this)); > max_columns= 1; > @@ -2584,15 +2584,13 @@ Item_in_subselect::select_in_like_transformer(JOIN > *join) > arena= thd->activate_stmt_arena_if_needed(&backup); > if (!optimizer) > { > - result= (!(optimizer= new Item_in_optimizer(left_expr, this))); > + result= (!(optimizer= new Item_in_optimizer(left_expr_orig, this))); > if (result) > goto out; > } > > thd->lex->current_select= current->return_after_parsing(); > result= optimizer->fix_left(thd, optimizer->arguments()); > - /* fix_fields can change reference to left_expr, we need reassign it */ > - left_expr= optimizer->arguments()[0]; > thd->lex->current_select= current; > > if (changed) > diff --git a/sql/item_subselect.h b/sql/item_subselect.h > index 592e771..930bd66 100644 > --- a/sql/item_subselect.h > +++ b/sql/item_subselect.h > @@ -449,6 +449,7 @@ class Item_in_subselect :public Item_exists_subselect > Item **having_item); > public: > Item *left_expr; > + Item *left_expr_orig; > /* Priority of this predicate in the convert-to-semi-join-nest process. */ > int sj_convert_priority; > /* > diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc > index 5b1a7f2..1363be0 100644 > --- a/sql/opt_subselect.cc > +++ b/sql/opt_subselect.cc > @@ -1593,7 +1593,9 @@ static bool convert_subq_to_sj(JOIN *parent_join, > Item_in_subselect *subq_pred) > { > nested_join->sj_outer_expr_list.push_back(subq_pred->left_expr); > Item_func_eq *item_eq= > - new Item_func_eq(subq_pred->left_expr, subq_lex->ref_pointer_array[0]); > + new Item_func_eq(subq_pred->left_expr_orig, > subq_lex->ref_pointer_array[0]); > + if (subq_pred->left_expr_orig != subq_pred->left_expr) > + thd->change_item_tree(item_eq->arguments(), subq_pred->left_expr); > item_eq->in_equality_no= 0; > sj_nest->sj_on_expr= and_items(sj_nest->sj_on_expr, item_eq); > } > _______________________________________________ > commits mailing list > [email protected] > https://lists.askmonty.org/cgi-bin/mailman/listinfo/commits -- BR Sergei -- Sergei Petrunia, Software Developer MariaDB Corporation | Skype: sergefp | Blog: http://s.petrunia.net/blog _______________________________________________ Mailing list: https://launchpad.net/~maria-developers Post to : [email protected] Unsubscribe : https://launchpad.net/~maria-developers More help : https://help.launchpad.net/ListHelp

