summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Babaev <igor@askmonty.org>2013-10-14 13:39:18 -0700
committerIgor Babaev <igor@askmonty.org>2013-10-14 13:39:18 -0700
commiteb2c6f451392396ef2ca74f1dba761fc4459d171 (patch)
tree4b9e6c400215cd74a81c65b1fa8a0200ea7249c3
parentddc46740a56bf3885ae33dc21e281c063d189abf (diff)
parenteae0a45f4e5ed4f1e382e53be74dd8082d4d797a (diff)
downloadmariadb-git-eb2c6f451392396ef2ca74f1dba761fc4459d171.tar.gz
Merge 5.5->10.0-base
-rw-r--r--libmysqld/lib_sql.cc2
-rw-r--r--mysql-test/r/subselect_sj2.result15
-rw-r--r--mysql-test/r/subselect_sj2_jcl6.result15
-rw-r--r--mysql-test/r/subselect_sj2_mat.result15
-rw-r--r--mysql-test/t/subselect_sj2.test19
-rw-r--r--sql/sql_select.cc34
6 files changed, 94 insertions, 6 deletions
diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc
index 0809e91d134..bd36520e9f2 100644
--- a/libmysqld/lib_sql.cc
+++ b/libmysqld/lib_sql.cc
@@ -416,11 +416,13 @@ int emb_unbuffered_fetch(MYSQL *mysql, char **row)
static void emb_free_embedded_thd(MYSQL *mysql)
{
THD *thd= (THD*)mysql->thd;
+ mysql_mutex_lock(&LOCK_thread_count);
thd->clear_data_list();
thread_count--;
thd->store_globals();
thd->unlink();
delete thd;
+ mysql_mutex_unlock(&LOCK_thread_count);
my_pthread_setspecific_ptr(THR_THD, 0);
mysql->thd=0;
}
diff --git a/mysql-test/r/subselect_sj2.result b/mysql-test/r/subselect_sj2.result
index 4f94f5a704c..d87514923c4 100644
--- a/mysql-test/r/subselect_sj2.result
+++ b/mysql-test/r/subselect_sj2.result
@@ -1094,6 +1094,21 @@ COUNT(*)
3724
set optimizer_prune_level=@tmp_951283;
DROP TABLE t1,t2;
+#
+# Bug mdev-5135: crash on semijoin with nested outer joins
+#
+CREATE TABLE t1 (i1 int) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (1),(2);
+CREATE TABLE t2 (i2 int, INDEX(i2)) ENGINE=MyISAM;
+CREATE TABLE t3 (i3 int, c varchar(1), INDEX(i3), INDEX(c)) ENGINE=MyISAM;
+INSERT INTO t3 VALUES (3,'x'),(4,'y');
+SELECT * FROM t1 WHERE ( 1, 1 ) IN (
+SELECT i2, i2 FROM t2 LEFT OUTER JOIN (
+t3 AS t3a INNER JOIN t3 AS t3b ON ( t3a.i3 = t3b.i3 )
+) ON ( t3a.c = t3b.c )
+);
+i1
+DROP TABLE t1,t2,t3;
DROP TABLE IF EXISTS t1,t2,t3,t4;
#
# MDEV-4782: Valgrind warnings (Conditional jump or move depends on uninitialised value) with InnoDB, semijoin
diff --git a/mysql-test/r/subselect_sj2_jcl6.result b/mysql-test/r/subselect_sj2_jcl6.result
index e0c5864f1b3..00e393635a2 100644
--- a/mysql-test/r/subselect_sj2_jcl6.result
+++ b/mysql-test/r/subselect_sj2_jcl6.result
@@ -1109,6 +1109,21 @@ COUNT(*)
3724
set optimizer_prune_level=@tmp_951283;
DROP TABLE t1,t2;
+#
+# Bug mdev-5135: crash on semijoin with nested outer joins
+#
+CREATE TABLE t1 (i1 int) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (1),(2);
+CREATE TABLE t2 (i2 int, INDEX(i2)) ENGINE=MyISAM;
+CREATE TABLE t3 (i3 int, c varchar(1), INDEX(i3), INDEX(c)) ENGINE=MyISAM;
+INSERT INTO t3 VALUES (3,'x'),(4,'y');
+SELECT * FROM t1 WHERE ( 1, 1 ) IN (
+SELECT i2, i2 FROM t2 LEFT OUTER JOIN (
+t3 AS t3a INNER JOIN t3 AS t3b ON ( t3a.i3 = t3b.i3 )
+) ON ( t3a.c = t3b.c )
+);
+i1
+DROP TABLE t1,t2,t3;
DROP TABLE IF EXISTS t1,t2,t3,t4;
#
# MDEV-4782: Valgrind warnings (Conditional jump or move depends on uninitialised value) with InnoDB, semijoin
diff --git a/mysql-test/r/subselect_sj2_mat.result b/mysql-test/r/subselect_sj2_mat.result
index 74fea8957a9..2306f19606c 100644
--- a/mysql-test/r/subselect_sj2_mat.result
+++ b/mysql-test/r/subselect_sj2_mat.result
@@ -1096,6 +1096,21 @@ COUNT(*)
3724
set optimizer_prune_level=@tmp_951283;
DROP TABLE t1,t2;
+#
+# Bug mdev-5135: crash on semijoin with nested outer joins
+#
+CREATE TABLE t1 (i1 int) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (1),(2);
+CREATE TABLE t2 (i2 int, INDEX(i2)) ENGINE=MyISAM;
+CREATE TABLE t3 (i3 int, c varchar(1), INDEX(i3), INDEX(c)) ENGINE=MyISAM;
+INSERT INTO t3 VALUES (3,'x'),(4,'y');
+SELECT * FROM t1 WHERE ( 1, 1 ) IN (
+SELECT i2, i2 FROM t2 LEFT OUTER JOIN (
+t3 AS t3a INNER JOIN t3 AS t3b ON ( t3a.i3 = t3b.i3 )
+) ON ( t3a.c = t3b.c )
+);
+i1
+DROP TABLE t1,t2,t3;
DROP TABLE IF EXISTS t1,t2,t3,t4;
#
# MDEV-4782: Valgrind warnings (Conditional jump or move depends on uninitialised value) with InnoDB, semijoin
diff --git a/mysql-test/t/subselect_sj2.test b/mysql-test/t/subselect_sj2.test
index 0f701cf9624..18221c90bc0 100644
--- a/mysql-test/t/subselect_sj2.test
+++ b/mysql-test/t/subselect_sj2.test
@@ -1225,6 +1225,25 @@ WHERE alias3.d IN (
set optimizer_prune_level=@tmp_951283;
DROP TABLE t1,t2;
+--echo #
+--echo # Bug mdev-5135: crash on semijoin with nested outer joins
+--echo #
+
+CREATE TABLE t1 (i1 int) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (1),(2);
+
+CREATE TABLE t2 (i2 int, INDEX(i2)) ENGINE=MyISAM;
+
+CREATE TABLE t3 (i3 int, c varchar(1), INDEX(i3), INDEX(c)) ENGINE=MyISAM;
+INSERT INTO t3 VALUES (3,'x'),(4,'y');
+
+SELECT * FROM t1 WHERE ( 1, 1 ) IN (
+ SELECT i2, i2 FROM t2 LEFT OUTER JOIN (
+ t3 AS t3a INNER JOIN t3 AS t3b ON ( t3a.i3 = t3b.i3 )
+ ) ON ( t3a.c = t3b.c )
+);
+
+DROP TABLE t1,t2,t3;
--source include/have_innodb.inc
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index fdc52cb454a..a40b7b217f9 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -4980,6 +4980,33 @@ static void add_key_fields_for_nj(JOIN *join, TABLE_LIST *nested_join_table,
}
+void count_cond_for_nj(SELECT_LEX *sel, TABLE_LIST *nested_join_table)
+{
+ List_iterator<TABLE_LIST> li(nested_join_table->nested_join->join_list);
+ List_iterator<TABLE_LIST> li2(nested_join_table->nested_join->join_list);
+ bool have_another = FALSE;
+ TABLE_LIST *table;
+
+ while ((table= li++) || (have_another && (li=li2, have_another=FALSE,
+ (table= li++))))
+ if (table->nested_join)
+ {
+ if (!table->on_expr)
+ {
+ /* It's a semi-join nest. Walk into it as if it wasn't a nest */
+ have_another= TRUE;
+ li2= li;
+ li= List_iterator<TABLE_LIST>(table->nested_join->join_list);
+ }
+ else
+ count_cond_for_nj(sel, table);
+ }
+ if (nested_join_table->on_expr)
+ nested_join_table->on_expr->walk(&Item::count_sargable_conds,
+ 0, (uchar*) sel);
+
+}
+
/**
Update keyuse array with all possible keys we can use to fetch rows.
@@ -5028,12 +5055,7 @@ update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab,
while ((table= li++))
{
if (table->nested_join)
- {
- if (table->on_expr)
- table->on_expr->walk(&Item::count_sargable_conds, 0, (uchar*) sel);
- if (table->sj_on_expr)
- table->sj_on_expr->walk(&Item::count_sargable_conds, 0, (uchar*) sel);
- }
+ count_cond_for_nj(sel, table);
}
}