Commit 353bc070 authored by unknown's avatar unknown

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.


mysql-test/r/insert_select.result:
  BUG#6034 - Error code 124:  Wrong medium type.
  The test results.
mysql-test/t/insert_select.test:
  BUG#6034 - Error code 124:  Wrong medium type.
  The test case.
sql/sql_select.cc:
  BUG#6034 - Error code 124:  Wrong medium type.
  With OPTION_BUFFER_RESULT in the 'select_options',
  defer the preparation of the insert table until the 
  result is to be used. Unfortunately, this happens
  at several places.
parent 7f4bb64a
...@@ -632,3 +632,15 @@ No Field Count ...@@ -632,3 +632,15 @@ No Field Count
0 1 100 0 1 100
0 2 100 0 2 100
drop table t1, t2; 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;
...@@ -176,3 +176,18 @@ insert into t2 Select null, Field, Count From t1 Where Month=20030901 and Type=2 ...@@ -176,3 +176,18 @@ insert into t2 Select null, Field, Count From t1 Where Month=20030901 and Type=2
select * from t2; select * from t2;
drop table t1, 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;
...@@ -223,6 +223,8 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds, ...@@ -223,6 +223,8 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
bool no_order; bool no_order;
/* Is set if we have a GROUP BY and we have ORDER BY on a constant. */ /* Is set if we have a GROUP BY and we have ORDER BY on a constant. */
bool skip_sort_order; bool skip_sort_order;
/* We cannot always prepare the result before selecting. */
bool is_result_prepared;
ha_rows select_limit; ha_rows select_limit;
Item::cond_result cond_value; Item::cond_result cond_value;
SQL_SELECT *select; SQL_SELECT *select;
...@@ -360,7 +362,17 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds, ...@@ -360,7 +362,17 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
DBUG_RETURN(-1); DBUG_RETURN(-1);
} }
#endif #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 */ { /* purecov: inspected */
DBUG_RETURN(-1); /* purecov: inspected */ DBUG_RETURN(-1); /* purecov: inspected */
} }
...@@ -392,6 +404,8 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds, ...@@ -392,6 +404,8 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
} }
if (cond_value == Item::COND_FALSE || !thd->select_limit) if (cond_value == Item::COND_FALSE || !thd->select_limit)
{ /* Impossible cond */ { /* Impossible cond */
if (! is_result_prepared && ! procedure && result->prepare(fields))
goto err;
error=return_zero_rows(&join, result, tables, fields, error=return_zero_rows(&join, result, tables, fields,
join.tmp_table_param.sum_func_count != 0 && !group, join.tmp_table_param.sum_func_count != 0 && !group,
select_options,"Impossible WHERE",having, select_options,"Impossible WHERE",having,
...@@ -417,6 +431,8 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds, ...@@ -417,6 +431,8 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
} }
if (res < 0) if (res < 0)
{ {
if (! is_result_prepared && ! procedure && result->prepare(fields))
goto err;
error=return_zero_rows(&join, result, tables, fields, !group, error=return_zero_rows(&join, result, tables, fields, !group,
select_options,"No matching min/max row", select_options,"No matching min/max row",
having,procedure); having,procedure);
...@@ -439,6 +455,8 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds, ...@@ -439,6 +455,8 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
describe_info(&join, "No tables used"); describe_info(&join, "No tables used");
else else
{ {
if (! is_result_prepared && ! procedure && result->prepare(fields))
goto err;
result->send_fields(fields,1); result->send_fields(fields,1);
if (!having || having->val_int()) if (!having || having->val_int())
{ {
...@@ -474,6 +492,8 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds, ...@@ -474,6 +492,8 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
if (join.const_table_map != join.found_const_table_map && if (join.const_table_map != join.found_const_table_map &&
!(select_options & SELECT_DESCRIBE)) !(select_options & SELECT_DESCRIBE))
{ {
if (! is_result_prepared && ! procedure && result->prepare(fields))
goto err;
error=return_zero_rows(&join,result,tables,fields, error=return_zero_rows(&join,result,tables,fields,
join.tmp_table_param.sum_func_count != 0 && join.tmp_table_param.sum_func_count != 0 &&
!group,0,"no matching row in const table",having, !group,0,"no matching row in const table",having,
...@@ -520,6 +540,8 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds, ...@@ -520,6 +540,8 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
} }
if (make_join_select(&join,select,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, error=return_zero_rows(&join, result, tables, fields,
join.tmp_table_param.sum_func_count != 0 && !group, join.tmp_table_param.sum_func_count != 0 && !group,
select_options, select_options,
...@@ -926,6 +948,8 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds, ...@@ -926,6 +948,8 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
goto err; goto err;
count_field_types(&join.tmp_table_param,all_fields,0); 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 || if (join.group || join.tmp_table_param.sum_func_count ||
(procedure && (procedure->flags & PROC_GROUP))) (procedure && (procedure->flags & PROC_GROUP)))
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment