A bug fix for multi-table updates with InnoDB storage engine

parent 31248b1a
...@@ -1074,3 +1074,20 @@ id ...@@ -1074,3 +1074,20 @@ id
select * from t2; select * from t2;
id t1_id id t1_id
drop table t1,t2; drop table t1,t2;
DROP TABLE IF EXISTS t1,t2;
CREATE TABLE t1(id INT NOT NULL, PRIMARY KEY (id)) TYPE=INNODB;
CREATE TABLE t2(id INT PRIMARY KEY, t1_id INT, INDEX par_ind (t1_id) ) TYPE=INNODB;
INSERT INTO t1 VALUES(1);
INSERT INTO t2 VALUES(1, 1);
SELECT * from t1;
id
1
UPDATE t1,t2 SET t1.id=t1.id+1, t2.t1_id=t1.id+1;
SELECT * from t1;
id
2
UPDATE t1,t2 SET t1.id=t1.id+1;
SELECT * from t1;
id
3
DROP TABLE IF EXISTS t1,t2;
...@@ -715,3 +715,14 @@ delete t1,t2 from t1,t2 where t1.id=t2.t1_id; ...@@ -715,3 +715,14 @@ delete t1,t2 from t1,t2 where t1.id=t2.t1_id;
select * from t1; select * from t1;
select * from t2; select * from t2;
drop table t1,t2; drop table t1,t2;
DROP TABLE IF EXISTS t1,t2;
CREATE TABLE t1(id INT NOT NULL, PRIMARY KEY (id)) TYPE=INNODB;
CREATE TABLE t2(id INT PRIMARY KEY, t1_id INT, INDEX par_ind (t1_id) ) TYPE=INNODB;
INSERT INTO t1 VALUES(1);
INSERT INTO t2 VALUES(1, 1);
SELECT * from t1;
UPDATE t1,t2 SET t1.id=t1.id+1, t2.t1_id=t1.id+1;
SELECT * from t1;
UPDATE t1,t2 SET t1.id=t1.id+1;
SELECT * from t1;
DROP TABLE IF EXISTS t1,t2;
...@@ -831,7 +831,7 @@ class multi_update : public select_result ...@@ -831,7 +831,7 @@ class multi_update : public select_result
uint table_count; uint table_count;
Copy_field *copy_field; Copy_field *copy_field;
enum enum_duplicates handle_duplicates; enum enum_duplicates handle_duplicates;
bool do_update, trans_safe, transactional_tables, log_delayed; bool do_update, trans_safe, transactional_tables, log_delayed, on_the_fly;
public: public:
multi_update(THD *thd_arg, TABLE_LIST *ut, List<Item> *fields, multi_update(THD *thd_arg, TABLE_LIST *ut, List<Item> *fields,
......
...@@ -413,7 +413,7 @@ multi_update::multi_update(THD *thd_arg, TABLE_LIST *table_list, ...@@ -413,7 +413,7 @@ multi_update::multi_update(THD *thd_arg, TABLE_LIST *table_list,
:all_tables(table_list), update_tables(0), thd(thd_arg), tmp_tables(0), :all_tables(table_list), update_tables(0), thd(thd_arg), tmp_tables(0),
updated(0), found(0), fields(field_list), values(value_list), updated(0), found(0), fields(field_list), values(value_list),
table_count(0), copy_field(0), handle_duplicates(handle_duplicates_arg), table_count(0), copy_field(0), handle_duplicates(handle_duplicates_arg),
do_update(1), trans_safe(0) do_update(1), trans_safe(0), on_the_fly(1)
{} {}
...@@ -538,12 +538,15 @@ multi_update::initialize_tables(JOIN *join) ...@@ -538,12 +538,15 @@ multi_update::initialize_tables(JOIN *join)
main_table=join->join_tab->table; main_table=join->join_tab->table;
trans_safe= transactional_tables= main_table->file->has_transactions(); trans_safe= transactional_tables= main_table->file->has_transactions();
log_delayed= trans_safe || main_table->tmp_table != NO_TMP_TABLE; log_delayed= trans_safe || main_table->tmp_table != NO_TMP_TABLE;
#ifdef HAVE_INNOBASE_DB
if (main_table->db_type == DB_TYPE_INNODB)
on_the_fly=0;
#endif
/* Create a temporary table for all tables after except main table */ /* Create a temporary table for all tables after except main table */
for (table_ref= update_tables; table_ref; table_ref=table_ref->next) for (table_ref= update_tables; table_ref; table_ref=table_ref->next)
{ {
TABLE *table=table_ref->table; TABLE *table=table_ref->table;
if (table != main_table) if (!on_the_fly || table != main_table)
{ {
uint cnt= table_ref->shared; uint cnt= table_ref->shared;
ORDER group; ORDER group;
...@@ -623,7 +626,7 @@ bool multi_update::send_data(List<Item> &not_used_values) ...@@ -623,7 +626,7 @@ bool multi_update::send_data(List<Item> &not_used_values)
uint offset= cur_table->shared; uint offset= cur_table->shared;
table->file->position(table->record[0]); table->file->position(table->record[0]);
if (table == main_table) if (on_the_fly && table == main_table)
{ {
table->status|= STATUS_UPDATED; table->status|= STATUS_UPDATED;
store_record(table,1); store_record(table,1);
...@@ -716,7 +719,7 @@ int multi_update::do_updates(bool from_send_error) ...@@ -716,7 +719,7 @@ int multi_update::do_updates(bool from_send_error)
for (cur_table= update_tables; cur_table ; cur_table= cur_table->next) for (cur_table= update_tables; cur_table ; cur_table= cur_table->next)
{ {
table = cur_table->table; table = cur_table->table;
if (table == main_table) if (on_the_fly && table == main_table)
continue; // Already updated continue; // Already updated
org_updated= updated; org_updated= updated;
......
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