diff --git a/mysql-test/r/insert_select.result b/mysql-test/r/insert_select.result index ecd26f2d9fb..506f95f61bb 100644 --- a/mysql-test/r/insert_select.result +++ b/mysql-test/r/insert_select.result @@ -632,3 +632,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) +) TYPE=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 deb80dbcdbf..a54f8c4bfb5 100644 --- a/mysql-test/t/insert_select.test +++ b/mysql-test/t/insert_select.test @@ -176,3 +176,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) +) TYPE=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 eda4ce73186..0d7ee1eb125 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -223,6 +223,8 @@ mysql_select(THD *thd,TABLE_LIST *tables,List &fields,COND *conds, bool no_order; /* Is set if we have a GROUP BY and we have ORDER BY on a constant. */ bool skip_sort_order; + /* We cannot always prepare the result before selecting. */ + bool is_result_prepared; ha_rows select_limit; Item::cond_result cond_value; SQL_SELECT *select; @@ -360,7 +362,17 @@ mysql_select(THD *thd,TABLE_LIST *tables,List &fields,COND *conds, DBUG_RETURN(-1); } #endif - if (!procedure && result->prepare(fields)) + /* + 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 ((is_result_prepared= (! procedure && + ! test(select_options & OPTION_BUFFER_RESULT))) && + result->prepare(fields)) { /* purecov: inspected */ DBUG_RETURN(-1); /* purecov: inspected */ } @@ -392,6 +404,8 @@ mysql_select(THD *thd,TABLE_LIST *tables,List &fields,COND *conds, } if (cond_value == Item::COND_FALSE || !thd->select_limit) { /* Impossible cond */ + if (! is_result_prepared && ! procedure && result->prepare(fields)) + goto err; error=return_zero_rows(&join, result, tables, fields, join.tmp_table_param.sum_func_count != 0 && !group, select_options,"Impossible WHERE",having, @@ -417,6 +431,8 @@ mysql_select(THD *thd,TABLE_LIST *tables,List &fields,COND *conds, } if (res < 0) { + if (! is_result_prepared && ! procedure && result->prepare(fields)) + goto err; error=return_zero_rows(&join, result, tables, fields, !group, select_options,"No matching min/max row", having,procedure); @@ -439,6 +455,8 @@ mysql_select(THD *thd,TABLE_LIST *tables,List &fields,COND *conds, describe_info(&join, "No tables used"); else { + if (! is_result_prepared && ! procedure && result->prepare(fields)) + goto err; result->send_fields(fields,1); if (!having || having->val_int()) { @@ -474,6 +492,8 @@ mysql_select(THD *thd,TABLE_LIST *tables,List &fields,COND *conds, if (join.const_table_map != join.found_const_table_map && !(select_options & SELECT_DESCRIBE)) { + if (! is_result_prepared && ! procedure && result->prepare(fields)) + goto err; error=return_zero_rows(&join,result,tables,fields, join.tmp_table_param.sum_func_count != 0 && !group,0,"no matching row in const table",having, @@ -520,6 +540,8 @@ mysql_select(THD *thd,TABLE_LIST *tables,List &fields,COND *conds, } if (make_join_select(&join,select,conds)) { + if (! is_result_prepared && ! procedure && result->prepare(fields)) + goto err; error=return_zero_rows(&join, result, tables, fields, join.tmp_table_param.sum_func_count != 0 && !group, select_options, @@ -926,6 +948,8 @@ mysql_select(THD *thd,TABLE_LIST *tables,List &fields,COND *conds, goto err; count_field_types(&join.tmp_table_param,all_fields,0); } + else if (! is_result_prepared && result->prepare(fields)) + goto err; if (join.group || join.tmp_table_param.sum_func_count || (procedure && (procedure->flags & PROC_GROUP))) {