summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Babaev <igor@askmonty.org>2016-11-11 20:55:03 -0800
committerIgor Babaev <igor@askmonty.org>2016-11-11 20:55:25 -0800
commit96b62b55149a9297f32c3aad99ece613cc3f788f (patch)
tree9915cccc75b02ab985fe2ed5d559376c85a2b03a
parent10aee66896a127da599a91f389820937cb4ba832 (diff)
downloadmariadb-git-96b62b55149a9297f32c3aad99ece613cc3f788f.tar.gz
Fixed bug mdev-11161.
The flag TABLE_LIST::fill_me must be reset to false at the prepare phase for any materialized derived table used in the executed query. Otherwise if the optimizer decides to generate a key for such a table it is generated only for the first execution of the query.
-rw-r--r--mysql-test/r/derived_view.result83
-rw-r--r--mysql-test/t/derived_view.test54
-rw-r--r--sql/sql_derived.cc2
3 files changed, 139 insertions, 0 deletions
diff --git a/mysql-test/r/derived_view.result b/mysql-test/r/derived_view.result
index 230660f2fcf..d993086299e 100644
--- a/mysql-test/r/derived_view.result
+++ b/mysql-test/r/derived_view.result
@@ -2496,5 +2496,88 @@ DROP TABLE t1,t2;
#
# end of 5.3 tests
#
+#
+# Bug mdev-11161: The second execution of prepared statement
+# does not use generated key for materialized
+# derived table / view
+# (actually this is a 5.3 bug.)
+#
+create table t1 (
+mat_id MEDIUMINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
+matintnum CHAR(6) NOT NULL,
+test MEDIUMINT UNSIGNED NULL
+);
+create table t2 (
+mat_id MEDIUMINT UNSIGNED NOT NULL,
+pla_id MEDIUMINT UNSIGNED NOT NULL
+);
+insert into t1 values
+(NULL, 'a', 1), (NULL, 'b', 2), (NULL, 'c', 3), (NULL, 'd', 4),
+(NULL, 'e', 5), (NULL, 'f', 6), (NULL, 'g', 7), (NULL, 'h', 8),
+(NULL, 'i', 9);
+insert into t2 values
+(1, 100), (1, 101), (1, 102), (2, 100), (2, 103), (2, 104),
+(3, 101), (3, 102), (3, 105);
+explain
+SELECT STRAIGHT_JOIN d.pla_id, m2.mat_id
+FROM t1 m2
+INNER JOIN
+(SELECT mp.pla_id, MIN(m1.matintnum) AS matintnum
+FROM t2 mp INNER JOIN t1 m1 ON mp.mat_id=m1.mat_id
+GROUP BY mp.pla_id) d
+ON d.matintnum=m2.matintnum;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY m2 ALL NULL NULL NULL NULL 9
+1 PRIMARY <derived2> ref key0 key0 7 test.m2.matintnum 2
+2 DERIVED mp ALL NULL NULL NULL NULL 9 Using temporary; Using filesort
+2 DERIVED m1 eq_ref PRIMARY PRIMARY 3 test.mp.mat_id 1
+prepare stmt1 from
+"SELECT STRAIGHT_JOIN d.pla_id, m2.mat_id
+ FROM t1 m2
+ INNER JOIN
+ (SELECT mp.pla_id, MIN(m1.matintnum) AS matintnum
+ FROM t2 mp INNER JOIN t1 m1 ON mp.mat_id=m1.mat_id
+ GROUP BY mp.pla_id) d
+ ON d.matintnum=m2.matintnum";
+flush status;
+execute stmt1;
+pla_id mat_id
+102 1
+101 1
+100 1
+104 2
+103 2
+105 3
+show status like '%Handler_read%';
+Variable_name Value
+Handler_read_first 0
+Handler_read_key 21
+Handler_read_last 0
+Handler_read_next 6
+Handler_read_prev 0
+Handler_read_rnd 6
+Handler_read_rnd_deleted 0
+Handler_read_rnd_next 27
+flush status;
+execute stmt1;
+pla_id mat_id
+102 1
+101 1
+100 1
+104 2
+103 2
+105 3
+show status like '%Handler_read%';
+Variable_name Value
+Handler_read_first 0
+Handler_read_key 21
+Handler_read_last 0
+Handler_read_next 6
+Handler_read_prev 0
+Handler_read_rnd 6
+Handler_read_rnd_deleted 0
+Handler_read_rnd_next 27
+deallocate prepare stmt1;
+drop table t1,t2;
set optimizer_switch=@exit_optimizer_switch;
set join_cache_level=@exit_join_cache_level;
diff --git a/mysql-test/t/derived_view.test b/mysql-test/t/derived_view.test
index 67899837bb2..d017f847af9 100644
--- a/mysql-test/t/derived_view.test
+++ b/mysql-test/t/derived_view.test
@@ -1827,6 +1827,60 @@ DROP TABLE t1,t2;
--echo # end of 5.3 tests
--echo #
+--echo #
+--echo # Bug mdev-11161: The second execution of prepared statement
+--echo # does not use generated key for materialized
+--echo # derived table / view
+--echo # (actually this is a 5.3 bug.)
+--echo #
+
+create table t1 (
+ mat_id MEDIUMINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
+ matintnum CHAR(6) NOT NULL,
+ test MEDIUMINT UNSIGNED NULL
+);
+create table t2 (
+ mat_id MEDIUMINT UNSIGNED NOT NULL,
+ pla_id MEDIUMINT UNSIGNED NOT NULL
+);
+insert into t1 values
+ (NULL, 'a', 1), (NULL, 'b', 2), (NULL, 'c', 3), (NULL, 'd', 4),
+ (NULL, 'e', 5), (NULL, 'f', 6), (NULL, 'g', 7), (NULL, 'h', 8),
+ (NULL, 'i', 9);
+insert into t2 values
+ (1, 100), (1, 101), (1, 102), (2, 100), (2, 103), (2, 104),
+ (3, 101), (3, 102), (3, 105);
+
+explain
+ SELECT STRAIGHT_JOIN d.pla_id, m2.mat_id
+ FROM t1 m2
+ INNER JOIN
+ (SELECT mp.pla_id, MIN(m1.matintnum) AS matintnum
+ FROM t2 mp INNER JOIN t1 m1 ON mp.mat_id=m1.mat_id
+ GROUP BY mp.pla_id) d
+ ON d.matintnum=m2.matintnum;
+
+prepare stmt1 from
+"SELECT STRAIGHT_JOIN d.pla_id, m2.mat_id
+ FROM t1 m2
+ INNER JOIN
+ (SELECT mp.pla_id, MIN(m1.matintnum) AS matintnum
+ FROM t2 mp INNER JOIN t1 m1 ON mp.mat_id=m1.mat_id
+ GROUP BY mp.pla_id) d
+ ON d.matintnum=m2.matintnum";
+
+flush status;
+execute stmt1;
+show status like '%Handler_read%';
+
+flush status;
+execute stmt1;
+show status like '%Handler_read%';
+
+deallocate prepare stmt1;
+
+drop table t1,t2;
+
# The following command must be the last one the file
set optimizer_switch=@exit_optimizer_switch;
set join_cache_level=@exit_join_cache_level;
diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc
index c6865a7116e..44395599961 100644
--- a/sql/sql_derived.cc
+++ b/sql/sql_derived.cc
@@ -651,6 +651,8 @@ bool mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *derived)
unit->derived= derived;
+ derived->fill_me= FALSE;
+
if (!(derived->derived_result= new select_union))
DBUG_RETURN(TRUE); // out of memory