From 9a914a00227519859a69b1bad7f2add2fad7c870 Mon Sep 17 00:00:00 2001 From: "ingo@mysql.com" <> Date: Wed, 19 Jan 2005 21:13:30 +0100 Subject: BUG#6034 - Error code 124: Wrong medium type. Version for 4.0. 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. --- sql/sql_select.cc | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) (limited to 'sql/sql_select.cc') 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))) { -- cgit v1.2.1