summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergei Petrunia <psergey@askmonty.org>2018-08-15 15:21:37 +0300
committerSergei Petrunia <psergey@askmonty.org>2018-08-15 15:25:14 +0300
commitb62ac161856570e9a0e92d17de1e3dd31d54410f (patch)
tree59748a25c8e5fe772ce27e09a7087682003a81e2
parent9dfef6e29b98459a5077adb95d5b989d39e0db24 (diff)
downloadmariadb-git-b62ac161856570e9a0e92d17de1e3dd31d54410f.tar.gz
MDEV-6439: Server crashes in Explain_union::print_explain with explain in slow log, tis620 charset
Item_subselect::is_expensive() used to return FALSE (Inexpensive) whenever it saw that one of SELECTs in the Subquery's UNION is degenerate. It ignored the fact that other parts of the UNION might not be inexpensive, including the case where pther parts of the UNION have no query plan yet. For a subquery in form col >= ANY (SELECT 'foo' UNION SELECT 'bar') this would cause the query to be considered inexpensive when there is no query plan for the second part of the UNION, which in turn would cause the SELECT 'foo' to compute and free itself while still inside JOIN::optimize for that SELECT (See MDEV comment for full description).
-rw-r--r--mysql-test/r/subselect_extra_no_semijoin.result19
-rw-r--r--mysql-test/t/subselect_extra_no_semijoin.test31
-rw-r--r--sql/item_subselect.cc2
3 files changed, 50 insertions, 2 deletions
diff --git a/mysql-test/r/subselect_extra_no_semijoin.result b/mysql-test/r/subselect_extra_no_semijoin.result
index 79bca388181..200682b4065 100644
--- a/mysql-test/r/subselect_extra_no_semijoin.result
+++ b/mysql-test/r/subselect_extra_no_semijoin.result
@@ -482,3 +482,22 @@ DROP TABLE t1,t2;
set optimizer_switch= @tmp_subselect_extra_derived;
set optimizer_switch= @subselect_extra_no_sj_tmp;
set @optimizer_switch_for_subselect_extra_test=null;
+#
+# MDEV-6439: Server crashes in Explain_union::print_explain with explain in slow log, tis620 charset
+#
+SET NAMES tis620;
+set @tmp= @@global.slow_query_log;
+SET GLOBAL slow_query_log = 1;
+SET long_query_time = 0.000001;
+SET log_slow_verbosity = 'explain';
+CREATE TABLE t1 (a VARCHAR(3)) ENGINE=MyISAM;
+SELECT * FROM t1 WHERE a >= ANY ( SELECT 'foo');
+a
+SELECT * FROM t1 WHERE a >= ANY ( SELECT 'foo' UNION SELECT 'bar' );
+ERROR HY000: Illegal mix of collations (tis620_thai_ci,COERCIBLE) and (latin1_swedish_ci,IMPLICIT) for operation '<='
+create table t2 (b int);
+insert into t2 values (1),(2),(3);
+SELECT * FROM t1 WHERE a >= ANY ( SELECT 'foo' FROM t2);
+ERROR HY000: Illegal mix of collations (tis620_thai_ci,COERCIBLE) and (latin1_swedish_ci,IMPLICIT) for operation '<='
+drop table t1,t2;
+SET GLOBAL slow_query_log=@tmp;
diff --git a/mysql-test/t/subselect_extra_no_semijoin.test b/mysql-test/t/subselect_extra_no_semijoin.test
index 8aba3dde72b..d8809c7f981 100644
--- a/mysql-test/t/subselect_extra_no_semijoin.test
+++ b/mysql-test/t/subselect_extra_no_semijoin.test
@@ -6,4 +6,33 @@ set @optimizer_switch_for_subselect_extra_test='semijoin=off,firstmatch=off,loo
set optimizer_switch= @subselect_extra_no_sj_tmp;
-set @optimizer_switch_for_subselect_extra_test=null; \ No newline at end of file
+set @optimizer_switch_for_subselect_extra_test=null;
+
+--echo #
+--echo # MDEV-6439: Server crashes in Explain_union::print_explain with explain in slow log, tis620 charset
+--echo #
+
+## Using a separate client connection is easier than restoring state
+connect(con1,localhost,root,,);
+
+SET NAMES tis620;
+set @tmp= @@global.slow_query_log;
+SET GLOBAL slow_query_log = 1;
+SET long_query_time = 0.000001;
+SET log_slow_verbosity = 'explain';
+
+CREATE TABLE t1 (a VARCHAR(3)) ENGINE=MyISAM;
+SELECT * FROM t1 WHERE a >= ANY ( SELECT 'foo');
+--error ER_CANT_AGGREGATE_2COLLATIONS
+SELECT * FROM t1 WHERE a >= ANY ( SELECT 'foo' UNION SELECT 'bar' );
+
+create table t2 (b int);
+insert into t2 values (1),(2),(3);
+
+--error ER_CANT_AGGREGATE_2COLLATIONS
+SELECT * FROM t1 WHERE a >= ANY ( SELECT 'foo' FROM t2);
+
+drop table t1,t2;
+SET GLOBAL slow_query_log=@tmp;
+disconnect con1;
+connection default;
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index a8dfdff9809..14b2ccd3985 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -575,7 +575,7 @@ bool Item_subselect::is_expensive()
*/
if (cur_join->optimized &&
(cur_join->zero_result_cause || !cur_join->tables_list))
- return false;
+ continue;
/*
If a subquery is not optimized we cannot estimate its cost. A subquery is