Commit e2285c54 authored by unknown's avatar unknown
Browse files

Fixed bug in multiple-table-delete where some rows was not deleted


mysql-test/r/delete.result:
  Test case for bug in multiple-table-delete where some rows was not deleted
mysql-test/t/delete.test:
  Test case for bug in multiple-table-delete where some rows was not deleted
sql/item_subselect.cc:
  Code cleanup
sql/opt_range.cc:
  Code cleanup
sql/sql_delete.cc:
  Fixed bug in multiple-table-delete where some rows was not deleted
  This happend when the first table-to-delete-from was not the the table that was scanned.
  Fixed this by only doing 'delete-on-the-fly' for the first table.
  Fixed also some wrong error handling in multi-table-delete
parent 6a7dedf2
Loading
Loading
Loading
Loading
+21 −1
Original line number Diff line number Diff line
drop table if exists t1,t11,t12,t2;
drop table if exists t1,t2,t3,t11,t12;
CREATE TABLE t1 (a tinyint(3), b tinyint(5));
INSERT INTO t1 VALUES (1,1);
INSERT LOW_PRIORITY INTO t1 VALUES (1,2);
@@ -172,3 +172,23 @@ a
0
2
DROP TABLE t1;
CREATE TABLE t1 (a int not null,b int not null);
CREATE TABLE t2 (a int not null, b int not null, primary key (a,b));
CREATE TABLE t3 (a int not null, b int not null, primary key (a,b));
insert into t1 values (1,1),(2,1),(1,3);
insert into t2 values (1,1),(2,2),(3,3);
insert into t3 values (1,1),(2,1),(1,3);
select * from t1,t2,t3 where t1.a=t2.a AND t2.b=t3.a and t1.b=t3.b;
a	b	a	b	a	b
1	1	1	1	1	1
2	1	2	2	2	1
1	3	1	1	1	3
explain select * from t1,t2,t3 where t1.a=t2.a AND t2.b=t3.a and t1.b=t3.b;
id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
1	SIMPLE	t1	ALL	NULL	NULL	NULL	NULL	3	
1	SIMPLE	t2	index	PRIMARY	PRIMARY	8	NULL	3	Using where; Using index
1	SIMPLE	t3	index	PRIMARY	PRIMARY	8	NULL	3	Using where; Using index
delete t2.*,t3.* from t1,t2,t3 where t1.a=t2.a AND t2.b=t3.a and t1.b=t3.b;
select * from t3;
a	b
drop table t1,t2,t3;
+18 −1
Original line number Diff line number Diff line
@@ -3,7 +3,7 @@
#

--disable_warnings
drop table if exists t1,t11,t12,t2;
drop table if exists t1,t2,t3,t11,t12;
--enable_warnings
CREATE TABLE t1 (a tinyint(3), b tinyint(5));
INSERT INTO t1 VALUES (1,1);
@@ -152,3 +152,20 @@ INSERT INTO t1 VALUES (0),(1),(2);
DELETE FROM t1 WHERE t1.a > 0 ORDER BY t1.a LIMIT 1;
SELECT * FROM t1;
DROP TABLE t1;

#
# Test of multi-delete where we are not scanning the first table
#

CREATE TABLE t1 (a int not null,b int not null);
CREATE TABLE t2 (a int not null, b int not null, primary key (a,b));
CREATE TABLE t3 (a int not null, b int not null, primary key (a,b));
insert into t1 values (1,1),(2,1),(1,3);
insert into t2 values (1,1),(2,2),(3,3);
insert into t3 values (1,1),(2,1),(1,3);
select * from t1,t2,t3 where t1.a=t2.a AND t2.b=t3.a and t1.b=t3.b;
explain select * from t1,t2,t3 where t1.a=t2.a AND t2.b=t3.a and t1.b=t3.b;
delete t2.*,t3.* from t1,t2,t3 where t1.a=t2.a AND t2.b=t3.a and t1.b=t3.b;
# This should be empty
select * from t3;
drop table t1,t2,t3;
+1 −2
Original line number Diff line number Diff line
@@ -773,9 +773,8 @@ Item_in_subselect::single_value_transformer(JOIN *join,
					    Comp_creator *func)
{
  Item_subselect::trans_res result= RES_ERROR;
  DBUG_ENTER("Item_in_subselect::single_value_transformer");

  SELECT_LEX *select_lex= join->select_lex;
  DBUG_ENTER("Item_in_subselect::single_value_transformer");

  /*
    Check that the right part of the subselect contains no more than one
+4 −4
Original line number Diff line number Diff line
@@ -7957,7 +7957,7 @@ void QUICK_GROUP_MIN_MAX_SELECT::update_key_stat()
  max_used_key_length= real_prefix_len;
  if (min_max_ranges.elements > 0)
  {
    QUICK_RANGE *cur_range= 0;
    QUICK_RANGE *cur_range;
    if (have_min)
    { /* Check if the right-most range has a lower boundary. */
      get_dynamic(&min_max_ranges, (gptr)&cur_range,
@@ -7965,7 +7965,7 @@ void QUICK_GROUP_MIN_MAX_SELECT::update_key_stat()
      if (!(cur_range->flag & NO_MIN_RANGE))
      {
        max_used_key_length+= min_max_arg_len;
        ++used_key_parts;
        used_key_parts++;
        return;
      }
    }
@@ -7975,7 +7975,7 @@ void QUICK_GROUP_MIN_MAX_SELECT::update_key_stat()
      if (!(cur_range->flag & NO_MAX_RANGE))
      {
        max_used_key_length+= min_max_arg_len;
        ++used_key_parts;
        used_key_parts++;
        return;
      }
    }
@@ -7983,7 +7983,7 @@ void QUICK_GROUP_MIN_MAX_SELECT::update_key_stat()
  else if (have_min && min_max_arg_part && min_max_arg_part->field->is_null())
  {
    max_used_key_length+= min_max_arg_len;
    ++used_key_parts;
    used_key_parts++;
  }
}

+3 −2
Original line number Diff line number Diff line
@@ -1854,7 +1854,8 @@ class multi_delete :public select_result_interceptor
  ha_rows deleted, found;
  uint num_of_tables;
  int error;
  bool do_delete, transactional_tables, normal_tables;
  bool do_delete, transactional_tables, normal_tables, delete_while_scanning;

public:
  multi_delete(THD *thd, TABLE_LIST *dt, uint num_of_tables);
  ~multi_delete();
@@ -1862,7 +1863,7 @@ class multi_delete :public select_result_interceptor
  bool send_data(List<Item> &items);
  bool initialize_tables (JOIN *join);
  void send_error(uint errcode,const char *err);
  int  do_deletes (bool from_send_error);
  int  do_deletes();
  bool send_eof();
};

Loading