From: Roy Lyseng Date: October 27 2011 11:41am Subject: bzr push into mysql-trunk branch (roy.lyseng:3470 to 3471) Bug#13106350 List-Archive: http://lists.mysql.com/commits/141608 X-Bug: 13106350 Message-Id: <20111027114158.2B5ED203@tyr67.norway.sun.com> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit 3471 Roy Lyseng 2011-10-27 Bug#13106350: MRR initialization on a derived table caused crash Followup patch to make test behave in trunk. mysql-test/r/derived.result Updated result file for bug#13106350. mysql-test/t/derived.test Deleted setting of semi-join related optimizer switches. Added explain to notify of plan changes. modified: mysql-test/r/derived.result mysql-test/t/derived.test 3470 Roy Lyseng 2011-10-26 Bug#113106350: crash in memcpy from join_cache::write_record_data This problem may happen if we combine the Duplicate Weedout semi-join strategy with join buffering, and the outer table is a derived table. The problem is that Duplicate Weedout needs the row id of all involved tables, hence the table is instructed to save the row id. Join buffering needs to save and restore the rowid into a buffer, for that purpose an st_cache_field object is allocated. This object contains a pointer to the row id buffer, but at the time of object creation, the table (being a derived table) has not yet been opened and the buffer pointer is NULL. The fix is to save a reference to the st_cache_field object in the corresponding JOIN_TAB and bind it with the buffer after the derived table has been materialized. mysql-test/t/derived.test Added test case for bug#113106350. mysql-test/r/derived.result Added test case results for bug#113106350. sql/sql_join_cache.cc Save reference to rowid copy object when setting up fields to copy. sql/sql_select.cc Bind the rowid buffer of a TABLE object to a copy object that is used to copy a rowid. Needed when temporary tables are opened as part of execution. sql/sql_select.h Added reference to copy object used to copy rowid in JOIN_TAB. Added a bind_buffer() access function for st_cache_field. modified: mysql-test/r/derived.result mysql-test/t/derived.test sql/sql_join_cache.cc sql/sql_select.cc sql/sql_select.h === modified file 'mysql-test/r/derived.result' --- a/mysql-test/r/derived.result 2011-10-26 13:23:01 +0000 +++ b/mysql-test/r/derived.result 2011-10-27 11:39:49 +0000 @@ -1617,14 +1617,22 @@ DROP TABLE t1, t2; # # Bug#13106350: MRR initialization on a derived table caused crash. # -SET @save_switch= @@optimizer_switch; -SET @@optimizer_switch="firstmatch=off,loosescan=off,materialization=off"; CREATE TABLE t1 (pk INTEGER PRIMARY KEY, vc VARCHAR(20)); INSERT INTO t1 VALUES(7, 'seven'), (13, 'thirteen'); CREATE TABLE t2 (pk INTEGER PRIMARY KEY, vc1 VARCHAR(20), vc2 VARCHAR(20)); INSERT INTO t2 VALUES(7, 'seven', 's'), (14, 'fourteen', 'f'); CREATE TABLE t3 (pk INTEGER PRIMARY KEY, vc VARCHAR(20)); INSERT INTO t3 VALUES(5, 'f'), (6, 's'), (7, 's'); +explain SELECT derived.vc +FROM (SELECT * FROM t1) AS derived +WHERE derived.vc IN ( +SELECT t2.vc1 +FROM t2 JOIN t3 ON t2.vc2=t3.vc); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; Start temporary +1 PRIMARY ref auto_key0 auto_key0 23 test.t2.vc1 2 +1 PRIMARY t3 ALL NULL NULL NULL NULL 3 Using where; End temporary; Using join buffer (Block Nested Loop) +2 DERIVED t1 ALL NULL NULL NULL NULL 2 SELECT derived.vc FROM (SELECT * FROM t1) AS derived WHERE derived.vc IN ( @@ -1632,6 +1640,5 @@ SELECT t2.vc1 FROM t2 JOIN t3 ON t2.vc2=t3.vc); vc seven -SET @@optimizer_switch= @save_switch; DROP TABLE t1, t2, t3; # === modified file 'mysql-test/t/derived.test' --- a/mysql-test/t/derived.test 2011-10-26 13:23:01 +0000 +++ b/mysql-test/t/derived.test 2011-10-27 11:39:49 +0000 @@ -979,8 +979,6 @@ DROP TABLE t1, t2; --echo # --echo # Bug#13106350: MRR initialization on a derived table caused crash. --echo # -SET @save_switch= @@optimizer_switch; -SET @@optimizer_switch="firstmatch=off,loosescan=off,materialization=off"; CREATE TABLE t1 (pk INTEGER PRIMARY KEY, vc VARCHAR(20)); @@ -994,13 +992,15 @@ CREATE TABLE t3 (pk INTEGER PRIMARY KEY, INSERT INTO t3 VALUES(5, 'f'), (6, 's'), (7, 's'); +let $query= SELECT derived.vc FROM (SELECT * FROM t1) AS derived WHERE derived.vc IN ( SELECT t2.vc1 FROM t2 JOIN t3 ON t2.vc2=t3.vc); +eval explain $query; +eval $query; -SET @@optimizer_switch= @save_switch; DROP TABLE t1, t2, t3; --echo # No bundle (reason: useless for push emails).