maria-developers team mailing list archive
-
maria-developers team
-
Mailing list archive
-
Message #08665
Re: [Commits] 9f8a458: MDEV-7846: Server crashes in Item_subselect::fix_fields or fails with Thread stack overrun
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, sanja@xxxxxxxxxxx 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
> commits@xxxxxxxxxxx
> 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
Follow ups