summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Petrunya <psergey@askmonty.org>2013-05-04 20:42:43 +0400
committerSergey Petrunya <psergey@askmonty.org>2013-05-04 20:42:43 +0400
commitddd341b71ae6b9c2dd206df64c662c0a29730ae9 (patch)
tree5ef61cfe0eb665f9bc26bc5abc9fec87d9b3c6bc
parent71422d7b143ae92a1a5802f0669d2d3d9483c2e4 (diff)
downloadmariadb-git-ddd341b71ae6b9c2dd206df64c662c0a29730ae9.tar.gz
MDEV-4071: Valgrind warnings 'Invalid read' in subselect_engine::calc_const_tables with ...
- Call tmp_having->update_used_tables() *before* we have call JOIN::cleanup(). Making the call after join::cleanup() is not allowed, because subquery predicate items walk parent join's JOIN_TAB structures. Which can be invalidated by JOIN::cleanup().
-rw-r--r--mysql-test/r/subselect_sj.result14
-rw-r--r--mysql-test/r/subselect_sj_jcl6.result14
-rw-r--r--mysql-test/t/subselect_sj.test17
-rw-r--r--sql/sql_select.cc20
4 files changed, 51 insertions, 14 deletions
diff --git a/mysql-test/r/subselect_sj.result b/mysql-test/r/subselect_sj.result
index 35c499fa8d4..56c3044c4e4 100644
--- a/mysql-test/r/subselect_sj.result
+++ b/mysql-test/r/subselect_sj.result
@@ -2870,4 +2870,18 @@ a cnt
1 1
4 1
drop table t1, t2;
+#
+# MDEV-4071: Valgrind warnings 'Invalid read' in subselect_engine::calc_const_tables with ...
+#
+CREATE TABLE t1 (b INT, c VARCHAR(1)) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (7,'v'),(0,'s');
+CREATE TABLE t2 (a INT) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (0),(8);
+SELECT c, SUM( DISTINCT b ) AS sm FROM t1
+WHERE ( 5, 108 ) IN ( SELECT MIN(a), MAX(a) FROM t2 )
+GROUP BY b
+HAVING c <> ( SELECT MAX( c ) FROM t1 )
+ORDER BY sm;
+c sm
+DROP TABLE t1,t2;
set optimizer_switch=@subselect_sj_tmp;
diff --git a/mysql-test/r/subselect_sj_jcl6.result b/mysql-test/r/subselect_sj_jcl6.result
index 5148c8e1577..7be29201c63 100644
--- a/mysql-test/r/subselect_sj_jcl6.result
+++ b/mysql-test/r/subselect_sj_jcl6.result
@@ -2884,6 +2884,20 @@ a cnt
1 1
4 1
drop table t1, t2;
+#
+# MDEV-4071: Valgrind warnings 'Invalid read' in subselect_engine::calc_const_tables with ...
+#
+CREATE TABLE t1 (b INT, c VARCHAR(1)) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (7,'v'),(0,'s');
+CREATE TABLE t2 (a INT) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (0),(8);
+SELECT c, SUM( DISTINCT b ) AS sm FROM t1
+WHERE ( 5, 108 ) IN ( SELECT MIN(a), MAX(a) FROM t2 )
+GROUP BY b
+HAVING c <> ( SELECT MAX( c ) FROM t1 )
+ORDER BY sm;
+c sm
+DROP TABLE t1,t2;
set optimizer_switch=@subselect_sj_tmp;
#
# BUG#49129: Wrong result with IN-subquery with join_cache_level=6 and firstmatch=off
diff --git a/mysql-test/t/subselect_sj.test b/mysql-test/t/subselect_sj.test
index 15ca4ce884e..bfdc6335f1d 100644
--- a/mysql-test/t/subselect_sj.test
+++ b/mysql-test/t/subselect_sj.test
@@ -2567,5 +2567,22 @@ drop table t1, t2;
connection default;
disconnect con1;
+--echo #
+--echo # MDEV-4071: Valgrind warnings 'Invalid read' in subselect_engine::calc_const_tables with ...
+--echo #
+CREATE TABLE t1 (b INT, c VARCHAR(1)) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (7,'v'),(0,'s');
+
+CREATE TABLE t2 (a INT) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (0),(8);
+
+SELECT c, SUM( DISTINCT b ) AS sm FROM t1
+WHERE ( 5, 108 ) IN ( SELECT MIN(a), MAX(a) FROM t2 )
+GROUP BY b
+HAVING c <> ( SELECT MAX( c ) FROM t1 )
+ORDER BY sm;
+
+DROP TABLE t1,t2;
+
# The following command must be the last one the file
set optimizer_switch=@subselect_sj_tmp;
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 4843d7be400..24f480bbfb9 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -2367,7 +2367,12 @@ JOIN::exec()
List<Item> *curr_all_fields= &all_fields;
List<Item> *curr_fields_list= &fields_list;
TABLE *curr_tmp_table= 0;
- bool tmp_having_used_tables_updated= FALSE;
+ /*
+ curr_join->join_free() will call JOIN::cleanup(full=TRUE). It will not
+ be safe to call update_used_tables() after that.
+ */
+ if (curr_join->tmp_having)
+ curr_join->tmp_having->update_used_tables();
/*
Initialize examined rows here because the values from all join parts
@@ -2618,16 +2623,6 @@ JOIN::exec()
curr_join->select_distinct=0; /* Each row is unique */
- /*
- curr_join->join_free() will call JOIN::cleanup(full=TRUE). It will not
- be safe to call update_used_tables() after that.
- */
- if (curr_join->tmp_having)
- {
- curr_join->tmp_having->update_used_tables();
- tmp_having_used_tables_updated= TRUE;
- }
-
curr_join->join_free(); /* Free quick selects */
if (curr_join->select_distinct && ! curr_join->group_list)
@@ -2708,9 +2703,6 @@ JOIN::exec()
if (curr_join->tmp_having && ! curr_join->group_list &&
! curr_join->sort_and_group)
{
- // Some tables may have been const
- if (!tmp_having_used_tables_updated)
- curr_join->tmp_having->update_used_tables();
JOIN_TAB *curr_table= &curr_join->join_tab[curr_join->const_tables];
table_map used_tables= (curr_join->const_table_map |
curr_table->table->map);