Hi Sanja, O the patch fixes the crash. However when I am debugging it, I see the execution to go like this: (gdb) wher #0 JOIN::optimize_inner (this=0x7fff900087d0) at /home/psergey/dev-git/10.1-dbg6/sql/sql_select.cc:1095 #1 0x0000555555a8e5f8 in JOIN::optimize (this=0x7fff900087d0) at /home/psergey/dev-git/10.1-dbg6/sql/sql_select.cc:1036 #2 0x0000555555b277ce in st_select_lex_unit::optimize (this=0x7fff900068a8) at /home/psergey/dev-git/10.1-dbg6/sql/sql_union.cc:747 #3 0x0000555555b279cb in st_select_lex_unit::exec (this=0x7fff900068a8) at /home/psergey/dev-git/10.1-dbg6/sql/sql_union.cc:780 #4 0x0000555555d3855f in subselect_union_engine::exec (this=0x7fff90007970) at /home/psergey/dev-git/10.1-dbg6/sql/item_subselect.cc:3785 #5 0x0000555555d2eb12 in Item_subselect::exec (this=0x7fff9000b028) at /home/psergey/dev-git/10.1-dbg6/sql/item_subselect.cc:684 #6 0x0000555555d3057e in Item_singlerow_subselect::val_str (this=0x7fff9000b028, str=0x7ffff43b3a40) at /home/psergey/dev-git/10.1-dbg6/sql/item_subselect.cc:1295 #7 0x0000555555cbca5e in Item_func_conv_charset::Item_func_conv_charset (this=0x7fff90021aa0, thd=0x555557ffda80, a=0x7fff9000b028, cs=0x555556c18b80, cache_if_const=true) at /home/psergey/dev-git/10.1-dbg6/sql/item_strfunc.h:975 #8 0x0000555555ca1a7b in Item::safe_charset_converter (this=0x7fff9000b028, thd=0x555557ffda80, tocs=0x555556c18b80) at /home/psergey/dev-git/10.1-dbg6/sql/item.cc:1084 #9 0x0000555555ca4452 in Item_func_or_sum::agg_item_set_converter (this=0x7fff90021828, coll=..., fname=0x555556460377 "<", args=0x7fff900218b0, nargs=2, flags=7, item_sep=1) at /home/psergey/dev-git/10.1-dbg6/sql/item.cc:2141 #10 0x0000555555cd4106 in Item_func_or_sum::agg_arg_charsets (this=0x7fff90021828, c=..., items=0x7fff900218b0, nitems=2, flags=7, item_sep=1) at /home/psergey/dev-git/10.1-dbg6/sql/item.h:3714 #11 0x0000555555cd414e in Item_func_or_sum::agg_arg_charsets_for_comparison (this=0x7fff90021828, c=..., items=0x7fff900218b0, nitems=2, item_sep=1) at /home/psergey/dev-git/10.1-dbg6/sql/item.h:3760 #12 0x0000555555cc10ac in Item_func::setup_args_and_comparator (this=0x7fff90021828, thd=0x555557ffda80, cmp=0x7fff900218e0) at /home/psergey/dev-git/10.1-dbg6/sql/item_cmpfunc.cc:509 #13 0x0000555555cc11b5 in Item_bool_rowready_func2::fix_length_and_dec (this=0x7fff90021828) at /home/psergey/dev-git/10.1-dbg6/sql/item_cmpfunc.cc:531 #14 0x0000555555cf022b in Item_func::fix_fields (this=0x7fff90021828, thd=0x555557ffda80, ref=0x7ffff43b3eb0) at /home/psergey/dev-git/10.1-dbg6/sql/item_func.cc:234 #15 0x0000555555d322fb in Item_allany_subselect::transform_into_max_min (this=0x7fff900077a8, join=0x7fff900087d0) at /home/psergey/dev-git/10.1-dbg6/sql/item_subselect.cc:1969 #16 0x0000555555bd557d in JOIN::transform_max_min_subquery (this=0x7fff900087d0) at /home/psergey/dev-git/10.1-dbg6/sql/opt_subselect.cc:901 #17 0x0000555555a8e9c6 in JOIN::optimize_inner (this=0x7fff900087d0) at /home/psergey/dev-git/10.1-dbg6/sql/sql_select.cc:1131 #18 0x0000555555a8e5f8 in JOIN::optimize (this=0x7fff900087d0) at /home/psergey/dev-git/10.1-dbg6/sql/sql_select.cc:1036 #19 0x0000555555a44f98 in st_select_lex::optimize_unflattened_subqueries (this=0x555558001b98, const_only=false) at /home/psergey/dev-git/10.1-dbg6/sql/sql_lex.cc:3760 #20 0x0000555555bdeaee in JOIN::optimize_unflattened_subqueries (this=0x7fff90007ca8) at /home/psergey/dev-git/10.1-dbg6/sql/opt_subselect.cc:5051 #21 0x0000555555a91dd7 in JOIN::optimize_inner (this=0x7fff90007ca8) at /home/psergey/dev-git/10.1-dbg6/sql/sql_select.cc:2043 #22 0x0000555555a8e5f8 in JOIN::optimize (this=0x7fff90007ca8) at /home/psergey/dev-git/10.1-dbg6/sql/sql_select.cc:1036 #23 0x0000555555a96bf2 in mysql_select (thd=0x555557ffda80, rref_pointer_array=0x555558001e10, tables=0x7fff900054b0, wild_num=1, fields=..., conds=0x7fff90007a80, og_num=0, order=0x0, group=0x0, having=0x0, proc_param=0x0, select_options=2147748608, result=0x7fff90007c88, unit=0x555558001498, select_lex=0x555558001b98) at /home/psergey/dev-git/10.1-dbg6/sql/sql_select.cc:3437 #24 0x0000555555a8c7fd in handle_select (thd=0x555557ffda80, lex=0x5555580013d0, result=0x7fff90007c88, setup_tables_done_option=0) at /home/psergey/dev-git/10.1-dbg6/sql/sql_select.cc:384 #25 0x0000555555a5cd61 in execute_sqlcom_select (thd=0x555557ffda80, all_tables=0x7fff900054b0) at /home/psergey/dev-git/10.1-dbg6/sql/sql_parse.cc:5894 #26 0x0000555555a52a21 in mysql_execute_command (thd=0x555557ffda80) at /home/psergey/dev-git/10.1-dbg6/sql/sql_parse.cc:2960 #27 0x0000555555a604b1 in mysql_parse (thd=0x555557ffda80, rawbuf=0x7fff90005258 "SELECT * FROM t1, t2 WHERE f3 = f2 AND f1 > ANY ( SELECT 'foo' UNION SELECT 'bar' )", length=83, parser_state=0x7ffff43b54f0) at /home/psergey/dev-git/10.1-dbg6/sql/sql_parse.cc:7314 #28 0x0000555555a4ec23 in dispatch_command (command=COM_QUERY, thd=0x555557ffda80, packet=0x555558004031 "SELECT * FROM t1, t2 WHERE f3 = f2 AND f1 > ANY ( SELECT 'foo' UNION SELECT 'bar' )", packet_length=83) at /home/psergey/dev-git/10.1-dbg6/sql/sql_parse.cc:1486 #29 0x0000555555a4d944 in do_command (thd=0x555557ffda80) at /home/psergey/dev-git/10.1-dbg6/sql/sql_parse.cc:1107 Note frame #0 and frame #17: JOIN::optimize_inner() has invoked a few functions which in turn invoked JOIN::optimize (and JOIN::optimize_inner()) for the same join. Before your patch this didn't happen, as the inner call to JOIN::optimize would find join->optimized= true and return immediately. In this particular example, the double-optimized join a degenerate "SELECT 'foo'", double-optimization has no effect. I tried to create an example with a non-degenerate join but didn't succeed. Looking at the code, I have no certainity that it's impossible to have two JOIN::optimize calls nest for a non-degenerate join. If you can explain why this is not possible, please do. If you can't prove this, I would suggest adding JOIN::inside_optimize_call and have "if (inside_optimize_call) return 0;" as the first line of JOIN::optimize. On Wed, Jun 22, 2016 at 11:17:44AM +0200, Oleksandr Byelkin wrote:
revision-id: 773ce408762b5f8256d4053b6d0d418d15657b92 (mariadb-10.1.14-24-g773ce40) parent(s): 63120090f994cc78876944e9f7a76f53337fa46e committer: Oleksandr Byelkin timestamp: 2016-06-22 11:17:44 +0200 message:
MDEV-10045: Server crashes in Time_and_counter_tracker::incr_loops
Do not set 'optimized' flag until whole optimization procedure is finished.
--- mysql-test/r/subselect.result | 11 +++++++++++ mysql-test/r/subselect_no_exists_to_in.result | 11 +++++++++++ mysql-test/r/subselect_no_mat.result | 11 +++++++++++ mysql-test/r/subselect_no_opts.result | 11 +++++++++++ mysql-test/r/subselect_no_scache.result | 11 +++++++++++ mysql-test/r/subselect_no_semijoin.result | 11 +++++++++++ mysql-test/t/subselect.test | 15 +++++++++++++++ sql/sql_select.cc | 6 +++--- 8 files changed, 84 insertions(+), 3 deletions(-)
diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index 6a53199..1ea7000 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -7159,3 +7159,14 @@ f foo drop table t1; SET NAMES default; +# +# MDEV-10045: Server crashes in Time_and_counter_tracker::incr_loops +# +SET NAMES utf8; +CREATE TABLE t1 (f1 VARCHAR(3), f2 INT UNSIGNED) ENGINE=MyISAM; +CREATE TABLE t2 (f3 INT) ENGINE=MyISAM; +SELECT * FROM t1, t2 WHERE f3 = f2 AND f1 > ANY ( SELECT 'foo' UNION SELECT 'bar' ); +f1 f2 f3 +DROP TABLE t1, t2; +SET NAMES default; +End of 10.1 tests diff --git a/mysql-test/r/subselect_no_exists_to_in.result b/mysql-test/r/subselect_no_exists_to_in.result index aa68434..be5e5b6 100644 --- a/mysql-test/r/subselect_no_exists_to_in.result +++ b/mysql-test/r/subselect_no_exists_to_in.result @@ -7159,6 +7159,17 @@ f foo drop table t1; SET NAMES default; +# +# MDEV-10045: Server crashes in Time_and_counter_tracker::incr_loops +# +SET NAMES utf8; +CREATE TABLE t1 (f1 VARCHAR(3), f2 INT UNSIGNED) ENGINE=MyISAM; +CREATE TABLE t2 (f3 INT) ENGINE=MyISAM; +SELECT * FROM t1, t2 WHERE f3 = f2 AND f1 > ANY ( SELECT 'foo' UNION SELECT 'bar' ); +f1 f2 f3 +DROP TABLE t1, t2; +SET NAMES default; +End of 10.1 tests set optimizer_switch=default; select @@optimizer_switch like '%exists_to_in=off%'; @@optimizer_switch like '%exists_to_in=off%' diff --git a/mysql-test/r/subselect_no_mat.result b/mysql-test/r/subselect_no_mat.result index 754aec1..6dd227c 100644 --- a/mysql-test/r/subselect_no_mat.result +++ b/mysql-test/r/subselect_no_mat.result @@ -7152,6 +7152,17 @@ f foo drop table t1; SET NAMES default; +# +# MDEV-10045: Server crashes in Time_and_counter_tracker::incr_loops +# +SET NAMES utf8; +CREATE TABLE t1 (f1 VARCHAR(3), f2 INT UNSIGNED) ENGINE=MyISAM; +CREATE TABLE t2 (f3 INT) ENGINE=MyISAM; +SELECT * FROM t1, t2 WHERE f3 = f2 AND f1 > ANY ( SELECT 'foo' UNION SELECT 'bar' ); +f1 f2 f3 +DROP TABLE t1, t2; +SET NAMES default; +End of 10.1 tests 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 e05dd4d..389c0f5 100644 --- a/mysql-test/r/subselect_no_opts.result +++ b/mysql-test/r/subselect_no_opts.result @@ -7150,4 +7150,15 @@ f foo drop table t1; SET NAMES default; +# +# MDEV-10045: Server crashes in Time_and_counter_tracker::incr_loops +# +SET NAMES utf8; +CREATE TABLE t1 (f1 VARCHAR(3), f2 INT UNSIGNED) ENGINE=MyISAM; +CREATE TABLE t2 (f3 INT) ENGINE=MyISAM; +SELECT * FROM t1, t2 WHERE f3 = f2 AND f1 > ANY ( SELECT 'foo' UNION SELECT 'bar' ); +f1 f2 f3 +DROP TABLE t1, t2; +SET NAMES default; +End of 10.1 tests 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 71ade62..a90278c 100644 --- a/mysql-test/r/subselect_no_scache.result +++ b/mysql-test/r/subselect_no_scache.result @@ -7165,6 +7165,17 @@ f foo drop table t1; SET NAMES default; +# +# MDEV-10045: Server crashes in Time_and_counter_tracker::incr_loops +# +SET NAMES utf8; +CREATE TABLE t1 (f1 VARCHAR(3), f2 INT UNSIGNED) ENGINE=MyISAM; +CREATE TABLE t2 (f3 INT) ENGINE=MyISAM; +SELECT * FROM t1, t2 WHERE f3 = f2 AND f1 > ANY ( SELECT 'foo' UNION SELECT 'bar' ); +f1 f2 f3 +DROP TABLE t1, t2; +SET NAMES default; +End of 10.1 tests 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 43d191b..16aa7b8 100644 --- a/mysql-test/r/subselect_no_semijoin.result +++ b/mysql-test/r/subselect_no_semijoin.result @@ -7150,5 +7150,16 @@ f foo drop table t1; SET NAMES default; +# +# MDEV-10045: Server crashes in Time_and_counter_tracker::incr_loops +# +SET NAMES utf8; +CREATE TABLE t1 (f1 VARCHAR(3), f2 INT UNSIGNED) ENGINE=MyISAM; +CREATE TABLE t2 (f3 INT) ENGINE=MyISAM; +SELECT * FROM t1, t2 WHERE f3 = f2 AND f1 > ANY ( SELECT 'foo' UNION SELECT 'bar' ); +f1 f2 f3 +DROP TABLE t1, t2; +SET NAMES default; +End of 10.1 tests 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 3599b52..c9c89a2 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -6011,3 +6011,18 @@ INSERT INTO t1 VALUES ('foo'); SELECT f FROM t1 WHERE f > ALL ( SELECT 'bar' UNION SELECT 'baz' ); drop table t1; SET NAMES default; + +--echo # +--echo # MDEV-10045: Server crashes in Time_and_counter_tracker::incr_loops +--echo # +SET NAMES utf8; + +CREATE TABLE t1 (f1 VARCHAR(3), f2 INT UNSIGNED) ENGINE=MyISAM; +CREATE TABLE t2 (f3 INT) ENGINE=MyISAM; + +SELECT * FROM t1, t2 WHERE f3 = f2 AND f1 > ANY ( SELECT 'foo' UNION SELECT 'bar' ); + +DROP TABLE t1, t2; +SET NAMES default; + +--echo End of 10.1 tests diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 4825726..ded59eb 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1040,7 +1040,7 @@ int JOIN::optimize() and deleted. The second call will not produce a valid query plan, it will short-circuit because optimized==TRUE.
- "was_optimized != optimized" is here to handle this case: + "!was_optimized" is here to handle this case: - first optimization starts, gets an error (from a const. cheap subquery), returns 1 - another JOIN::optimize() call made, and now join->optimize() will @@ -1049,7 +1049,7 @@ int JOIN::optimize() Can have QEP_NOT_PRESENT_YET for degenerate queries (for example, SELECT * FROM tbl LIMIT 0) */ - if (was_optimized != optimized && !res && have_query_plan != QEP_DELETED) + if (!was_optimized && !res && have_query_plan != QEP_DELETED) { create_explain_query_if_not_exists(thd->lex, thd->mem_root); have_query_plan= QEP_AVAILABLE; @@ -1058,6 +1058,7 @@ int JOIN::optimize() !skip_sort_order && !no_order && (order || group_list), select_distinct); } + optimized= 1; return res; }
@@ -1086,7 +1087,6 @@ JOIN::optimize_inner() // to prevent double initialization on EXPLAIN if (optimized) DBUG_RETURN(0); - optimized= 1; DEBUG_SYNC(thd, "before_join_optimize");
THD_STAGE_INFO(thd, stage_optimizing); _______________________________________________ commits mailing list commits@mariadb.org 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