From a7dd24cdaa739727f06a44a5386af092f17c10e3 Mon Sep 17 00:00:00 2001 From: Sergei Petrunia Date: Tue, 6 Oct 2015 13:52:27 +0300 Subject: [PATCH] MDEV-8299: MyISAM or Aria table gets corrupted after EXPLAIN INSERT and INSERT [EXPLAIN] INSERT .. SELECT creates a select_insert object. select_insert calls handler->start_bulk_insert() during initialization. For MyISAM/Aria this requires that a matching call to handler->end_bulk_insert() call is made. Regular INSERT .. SELECT accomplishes this by calling either select_result->send_eof() or select_result->abort_result_set(). EXPLAIN INSERT ... SELECT didn't call either, which resulted in improper de-initializaiton of handler object. Make it call abort_result_set(), which invokes handler->end_bulk_insert(). --- mysql-test/r/explain_non_select.result | 15 +++++++++++++++ mysql-test/t/explain_non_select.test | 16 ++++++++++++++++ sql/sql_parse.cc | 10 ++++++++++ 3 files changed, 41 insertions(+) diff --git a/mysql-test/r/explain_non_select.result b/mysql-test/r/explain_non_select.result index 0eee7ee9b1e..8e336a0f8c0 100644 --- a/mysql-test/r/explain_non_select.result +++ b/mysql-test/r/explain_non_select.result @@ -232,3 +232,18 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE user index NULL PRIMARY 420 NULL 4 Using index DROP TABLE t1; DROP VIEW v1; +# +# MDEV-8299: MyISAM or Aria table gets corrupted after EXPLAIN INSERT and INSERT +# +CREATE TABLE t1 (pk INT NOT NULL AUTO_INCREMENT PRIMARY KEY, i INT, KEY(i)) ENGINE=MyISAM; +INSERT INTO t1 (i) VALUES (100),(200); +CREATE TABLE t2 (j INT) ENGINE=MyISAM; +INSERT INTO t2 VALUES (10),(20); +EXPLAIN INSERT INTO t1 (i) SELECT j FROM t2; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ALL NULL NULL NULL NULL 2 +INSERT INTO t1 (i) VALUES (300); +CHECK TABLE t1; +Table Op Msg_type Msg_text +test.t1 check status OK +DROP TABLE t1, t2; diff --git a/mysql-test/t/explain_non_select.test b/mysql-test/t/explain_non_select.test index e36fd518b61..52996a8c24a 100644 --- a/mysql-test/t/explain_non_select.test +++ b/mysql-test/t/explain_non_select.test @@ -208,3 +208,19 @@ INSERT INTO t1 VALUES (1),(2); EXPLAIN UPDATE v1, mysql.user SET v1.a = v1.a + 1; DROP TABLE t1; DROP VIEW v1; + +--echo # +--echo # MDEV-8299: MyISAM or Aria table gets corrupted after EXPLAIN INSERT and INSERT +--echo # +CREATE TABLE t1 (pk INT NOT NULL AUTO_INCREMENT PRIMARY KEY, i INT, KEY(i)) ENGINE=MyISAM; +INSERT INTO t1 (i) VALUES (100),(200); + +CREATE TABLE t2 (j INT) ENGINE=MyISAM; +INSERT INTO t2 VALUES (10),(20); + +EXPLAIN INSERT INTO t1 (i) SELECT j FROM t2; +INSERT INTO t1 (i) VALUES (300); +CHECK TABLE t1; + +DROP TABLE t1, t2; + diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 1374a93e6b9..93e6bdebd53 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -3549,6 +3549,16 @@ end_with_restore_list: query_cache_invalidate3(thd, first_table, 1); first_table->next_local= save_table; } + if (explain) + { + /* + sel_result needs to be cleaned up properly. + INSERT... SELECT statement will call either send_eof() or + abort_result_set(). EXPLAIN doesn't call either, so we need + to cleanup manually. + */ + sel_result->abort_result_set(); + } delete sel_result; }