Commit ea8882be authored by ingo@mysql.com's avatar ingo@mysql.com

BUG#6034 - Error code 124: Wrong medium type.

Version for 5.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.
Now the preparation is split into two prepare methods.
The first detects the situation and defers some preparations
until the second phase.
parent e906e861
...@@ -638,3 +638,15 @@ No Field Count ...@@ -638,3 +638,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)
) 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;
...@@ -180,3 +180,18 @@ insert into t2 Select null, Field, Count From t1 Where Month=20030901 and Type=2 ...@@ -180,3 +180,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)
) 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;
...@@ -1280,6 +1280,7 @@ class select_result :public Sql_alloc { ...@@ -1280,6 +1280,7 @@ class select_result :public Sql_alloc {
unit= u; unit= u;
return 0; return 0;
} }
virtual int prepare2(void) { return 0; }
/* /*
Because of peculiarities of prepared statements protocol Because of peculiarities of prepared statements protocol
we need to know number of columns in the result set (if we need to know number of columns in the result set (if
...@@ -1379,6 +1380,7 @@ class select_insert :public select_result_interceptor { ...@@ -1379,6 +1380,7 @@ class select_insert :public select_result_interceptor {
enum_duplicates duplic, bool ignore); enum_duplicates duplic, bool ignore);
~select_insert(); ~select_insert();
int prepare(List<Item> &list, SELECT_LEX_UNIT *u); int prepare(List<Item> &list, SELECT_LEX_UNIT *u);
int prepare2(void);
bool send_data(List<Item> &items); bool send_data(List<Item> &items);
virtual void store_values(List<Item> &values); virtual void store_values(List<Item> &values);
void send_error(uint errcode,const char *err); void send_error(uint errcode,const char *err);
......
...@@ -1802,13 +1802,22 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u) ...@@ -1802,13 +1802,22 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
thd->lex->current_select->options|= OPTION_BUFFER_RESULT; thd->lex->current_select->options|= OPTION_BUFFER_RESULT;
thd->lex->current_select->join->select_options|= OPTION_BUFFER_RESULT; thd->lex->current_select->join->select_options|= OPTION_BUFFER_RESULT;
} }
else
restore_record(table,s->default_values); // Get empty record {
table->next_number_field=table->found_next_number_field; /*
thd->cuted_fields=0; We must not yet prepare the result table if it is the same as one of the
source tables (INSERT SELECT). 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
in select_insert::prepare2().
*/
if (info.ignore || info.handle_duplicates != DUP_ERROR) if (info.ignore || info.handle_duplicates != DUP_ERROR)
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY); table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
table->file->start_bulk_insert((ha_rows) 0); table->file->start_bulk_insert((ha_rows) 0);
}
restore_record(table,s->default_values); // Get empty record
table->next_number_field=table->found_next_number_field;
thd->cuted_fields=0;
thd->no_trans_update= 0; thd->no_trans_update= 0;
thd->abort_on_warning= (!info.ignore && thd->abort_on_warning= (!info.ignore &&
(thd->variables.sql_mode & (thd->variables.sql_mode &
...@@ -1819,6 +1828,36 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u) ...@@ -1819,6 +1828,36 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
} }
/*
Finish the preparation of the result table.
SYNOPSIS
select_insert::prepare2()
void
DESCRIPTION
If the result table is the same as one of the source tables (INSERT SELECT),
the result table is not finally prepared at the join prepair phase.
Do the final preparation now.
RETURN
0 OK
*/
int select_insert::prepare2(void)
{
DBUG_ENTER("select_insert::prepare2");
if (thd->lex->current_select->options & OPTION_BUFFER_RESULT)
{
if (info.ignore || info.handle_duplicates != DUP_ERROR)
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
table->file->start_bulk_insert((ha_rows) 0);
}
return 0;
}
void select_insert::cleanup() void select_insert::cleanup()
{ {
/* select_insert/select_create are never re-used in prepared statement */ /* select_insert/select_create are never re-used in prepared statement */
......
...@@ -1164,6 +1164,7 @@ JOIN::exec() ...@@ -1164,6 +1164,7 @@ JOIN::exec()
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
} }
(void) result->prepare2(); // Currently, this cannot fail.
if (!tables_list) if (!tables_list)
{ // Only test of functions { // Only test of functions
...@@ -13149,7 +13150,8 @@ bool JOIN::change_result(select_result *res) ...@@ -13149,7 +13150,8 @@ bool JOIN::change_result(select_result *res)
{ {
DBUG_ENTER("JOIN::change_result"); DBUG_ENTER("JOIN::change_result");
result= res; result= res;
if (!procedure && result->prepare(fields_list, select_lex->master_unit())) if (!procedure && (result->prepare(fields_list, select_lex->master_unit()) ||
result->prepare2()))
{ {
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
} }
......
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