From fd0fdcdaa8257218c8487b2e83e1a0f8ce2aecd6 Mon Sep 17 00:00:00 2001 From: "ingo@mysql.com" <> Date: Wed, 19 Jan 2005 21:16:27 +0100 Subject: [PATCH] BUG#6034 - Error code 124: Wrong medium type. Version for 4.1. Committed for merge. If the result table is one of the select tables in INSERT SELECT, we must not disable the result tables indexes before selecting. mysql_execute_command() detects the match for other reasons and adds the flag OPTION_BUFFER_RESULT to the 'select_options'. In this case the result is put into a temporary table first. Hence, we can defer the preparation of the insert table until the result is to be used. --- mysql-test/r/insert_select.result | 12 ++++++++++++ mysql-test/t/insert_select.test | 15 +++++++++++++++ sql/sql_select.cc | 18 +++++++++++++++++- 3 files changed, 44 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/insert_select.result b/mysql-test/r/insert_select.result index 0a6a34f9a58..f5ad0c87881 100644 --- a/mysql-test/r/insert_select.result +++ b/mysql-test/r/insert_select.result @@ -638,3 +638,15 @@ No Field Count 0 1 100 0 2 100 drop table t1, t2; +CREATE TABLE t1 ( +ID int(11) NOT NULL auto_increment, +NO int(11) NOT NULL default '0', +SEQ int(11) NOT NULL default '0', +PRIMARY KEY (ID), +KEY t1$NO (SEQ,NO) +) ENGINE=MyISAM; +INSERT INTO t1 (SEQ, NO) SELECT "1" AS SEQ, IF(MAX(NO) IS NULL, 0, MAX(NO)) + 1 AS NO FROM t1 WHERE (SEQ = 1); +select SQL_BUFFER_RESULT * from t1 WHERE (SEQ = 1); +ID NO SEQ +1 1 1 +drop table t1; diff --git a/mysql-test/t/insert_select.test b/mysql-test/t/insert_select.test index e1459310bb9..39b8bfcaaaa 100644 --- a/mysql-test/t/insert_select.test +++ b/mysql-test/t/insert_select.test @@ -182,3 +182,18 @@ insert into t2 Select null, Field, Count From t1 Where Month=20030901 and Type=2 select * from t2; drop table t1, t2; + +# +# BUG#6034 - Error code 124: Wrong medium type +# +CREATE TABLE t1 ( + ID int(11) NOT NULL auto_increment, + NO int(11) NOT NULL default '0', + SEQ int(11) NOT NULL default '0', + PRIMARY KEY (ID), + KEY t1$NO (SEQ,NO) +) ENGINE=MyISAM; +INSERT INTO t1 (SEQ, NO) SELECT "1" AS SEQ, IF(MAX(NO) IS NULL, 0, MAX(NO)) + 1 AS NO FROM t1 WHERE (SEQ = 1); +select SQL_BUFFER_RESULT * from t1 WHERE (SEQ = 1); +drop table t1; + diff --git a/sql/sql_select.cc b/sql/sql_select.cc index aea7cb9ed6d..7e48374a8e6 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -398,7 +398,16 @@ JOIN::prepare(Item ***rref_pointer_array, goto err; } #endif - if (!procedure && result && result->prepare(fields_list, unit_arg)) + /* + We must not yet prepare the result table if it is the same as one of the + source tables (INSERT SELECT). This is checked in mysql_execute_command() + and OPTION_BUFFER_RESULT is added to the select_options. A temporary + table is then used to hold the result. The preparation may disable + indexes on the result table, which may be used during the select, if it + is the same table (Bug #6034). Do the preparation after the select phase. + */ + if (! procedure && ! test(select_options & OPTION_BUFFER_RESULT) && + result && result->prepare(fields_list, unit_arg)) goto err; /* purecov: inspected */ if (select_lex->olap == ROLLUP_TYPE && rollup_init()) @@ -1043,6 +1052,13 @@ JOIN::exec() DBUG_VOID_RETURN; } } + else if (test(select_options & OPTION_BUFFER_RESULT) && + result && result->prepare(fields_list, unit)) + { + error= 1; + thd->limit_found_rows= thd->examined_row_count= 0; + DBUG_VOID_RETURN; + } if (!tables_list) { // Only test of functions