revision-id: 540e6379351e390245cf6877e9532340dc0313be (mariadb-10.11.1-59-g540e637) parent(s): efc4614112e8f252ac83320e0ad7035836b8a383 author: Lena Startseva committer: Igor Babaev timestamp: 2023-02-14 13:54:34 -0800 message: MDEV-29390: Improve coverage for UPDATE and DELETE statements in MTR test suites Created tests for "delete" based on update_use_source.test For the update_use_source.test tests, data recovery in the table has been changed from a rollback transaction to a complete delete and re-insert of the data with optimize table. Cases are now being checked on three engines. Added tests for update/delete with LooseScan and DuplicateWeedout optimization strategies Added tests for engine MEMORY on delete and update Added tests for multi-update with JSON_TABLE Added tests for multi-update and multi-delete for engine Connect --- mysql-test/include/delete_use_source.inc | 87 + mysql-test/include/delete_use_source_cases.inc | 289 + .../include/delete_use_source_cases_memory.inc | 293 + mysql-test/include/delete_use_source_memory.inc | 27 + mysql-test/include/update_use_source.inc | 293 +- mysql-test/include/update_use_source_cases.inc | 159 + mysql-test/include/update_use_source_ext.inc | 59 + mysql-test/main/delete_single_to_multi.result | 623 ++ mysql-test/main/delete_single_to_multi.test | 224 + mysql-test/main/delete_use_source_engines.result | 9499 ++++++++++++++++++++ mysql-test/main/delete_use_source_engines.test | 22 + mysql-test/main/update_single_to_multi.result | 539 ++ mysql-test/main/update_single_to_multi.test | 238 + mysql-test/main/update_use_source.result | 5582 +++++++++++- mysql-test/main/update_use_source.test | 222 +- mysql-test/suite/json/r/json_table.result | 101 + mysql-test/suite/json/t/json_table.test | 94 + storage/connect/mysql-test/connect/r/upd.result | 160 + storage/connect/mysql-test/connect/t/upd.test | 96 + 19 files changed, 17838 insertions(+), 769 deletions(-) diff --git a/mysql-test/include/delete_use_source.inc b/mysql-test/include/delete_use_source.inc new file mode 100644 index 0000000..3c43207 --- /dev/null +++ b/mysql-test/include/delete_use_source.inc @@ -0,0 +1,87 @@ +let $engine = `select @@default_storage_engine`; + +create table t1 (c1 integer, c2 integer, c3 integer); + +insert into t1(c1,c2,c3) + values (1,1,1),(1,2,2),(1,3,3), + (2,1,4),(2,2,5),(2,3,6), + (2,4,7),(2,5,8); +insert into t1 select c1+10,c2,c3+10 from t1; +insert into t1 select c1+20,c2+1,c3+20 from t1; +analyze table t1 persistent for all; + +create view v1 as select * from t1 where c2=2; + +--echo Test without any index +--source include/delete_use_source_cases.inc + +--echo Test with an index +create index t1_c2 on t1 (c2,c1); +--source include/delete_use_source_cases.inc + +--echo Test with a primary key +drop index t1_c2 on t1; +alter table t1 add primary key (c3); +--source include/delete_use_source_cases.inc + +drop view v1; +drop table t1; + +--echo # +--echo # Test on dynamic columns (blob) +--echo # +create table assets ( + item_name varchar(32) primary key, -- A common attribute for all items + dynamic_cols blob -- Dynamic columns will be stored here +); + +INSERT INTO assets + VALUES ('MariaDB T-shirt', + COLUMN_CREATE('color', 'blue', 'size', 'XL')); +INSERT INTO assets + VALUES ('Thinkpad Laptop', + COLUMN_CREATE('color', 'black', 'price', 500)); +INSERT INTO assets + VALUES ('Fridge', + COLUMN_CREATE('color', 'white', 'warranty', '5 years')); +INSERT INTO assets + VALUES ('Microwave', + COLUMN_CREATE('warranty', '3 years')); +SELECT item_name, COLUMN_GET(dynamic_cols, 'color' as char) AS color + FROM assets ORDER BY item_name; +UPDATE assets SET dynamic_cols=COLUMN_DELETE(dynamic_cols, 'color') + WHERE item_name='Fridge'; +SELECT item_name, COLUMN_GET(dynamic_cols, 'color' as char) AS color + FROM assets ORDER BY item_name; +DELETE FROM assets + WHERE item_name in + (select b.item_name from assets b + where COLUMN_GET(b.dynamic_cols, 'color' as char) ='black'); +SELECT item_name, COLUMN_GET(dynamic_cols, 'color' as char) AS color + FROM assets ORDER BY item_name; +DELETE FROM assets WHERE item_name='Microwave'; +SELECT item_name, COLUMN_GET(dynamic_cols, 'color' as char) AS color + FROM assets ORDER BY item_name; +drop table assets ; + + +--echo # +--echo # Test on fulltext columns +--echo # +CREATE TABLE ft2(copy TEXT,FULLTEXT(copy)); +INSERT INTO ft2(copy) VALUES + ('MySQL vs MariaDB database'), + ('Oracle vs MariaDB database'), + ('PostgreSQL vs MariaDB database'), + ('MariaDB overview'), + ('Foreign keys'), + ('Primary keys'), + ('Indexes'), + ('Transactions'), + ('Triggers'); + +SELECT * FROM ft2 WHERE MATCH(copy) AGAINST('database'); +DELETE FROM ft2 WHERE MATCH(copy) AGAINST('database'); +SELECT * FROM ft2 WHERE MATCH(copy) AGAINST('database'); +drop table ft2; + diff --git a/mysql-test/include/delete_use_source_cases.inc b/mysql-test/include/delete_use_source_cases.inc new file mode 100644 index 0000000..35ecf4e --- /dev/null +++ b/mysql-test/include/delete_use_source_cases.inc @@ -0,0 +1,289 @@ +--echo # +--echo # Delete with value from subquery on the same table +--echo # +let $c = c1=(select a.c3 from t1 a where a.c3 = t1.c3); +eval create table tmp as select * from t1 where $c; +let $q = delete from t1 where $c; +eval explain select * from t1 where $c; +eval explain $q; +--enable_info ONCE +eval $q; +--sorted_result +select * from t1; +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; + +--echo # +--echo # Delete with EXISTS subquery over the updated table +--echo # in WHERE + possibly sargable condition +--echo # + +analyze table t1 persistent for all; + +let $c = c1 = 1 and exists (select 'X' from t1 a where a.c1 = t1.c2); +eval create table tmp as select * from t1 where $c; +let $q = delete from t1 where $c; +eval explain select * from t1 where $c; +eval explain $q; +eval analyze $q; +--sorted_result +select * from t1; +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; + +--echo # +--echo # Delete with EXISTS subquery over the updated table +--echo # in WHERE + non-sargable condition +--echo # + +analyze table t1 persistent for all; + +let $c = exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 = 3; +eval create table tmp as select * from t1 where $c; +let $q = delete from t1 where $c; +eval explain select * from t1 where $c; +eval explain $q; +--enable_info ONCE +eval $q; +--sorted_result +select * from t1; +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; + +--echo # +--echo # Delete with order by +--echo # + +analyze table t1 persistent for all; + +let $c = exists (select 'X' from t1 a where a.c2 = t1.c2) + and c2 >= 3 order by c2; +eval create table tmp as select * from t1 where $c; +let $q = delete from t1 where $c; +eval explain select * from t1 where $c; +eval explain $q; +eval analyze $q; +--sorted_result +select * from t1; +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; + +--echo # +--echo # Delete with IN predicand over the updated table in WHERE +--echo # +let $c = c3 in (select distinct a.c1 from t1 a where t1.c2=a.c2); +eval create table tmp as select * from t1 where $c; +let $q = delete from t1 where $c; +eval explain select * from t1 where $c; +eval explain $q; +--enable_info ONCE +eval $q; +--sorted_result +select * from t1; +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; + +--echo # +--echo # Delete with a limit - can be deleted +--echo # +let $c = c1 in (select a.c2 from t1 a where a.c2 = t1.c3) limit 1; +eval create table tmp as select * from t1 where $c; +let $q = delete from t1 where $c; +eval explain select * from t1 where $c; +eval explain $q; +eval analyze $q; +--sorted_result +select * from t1; +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; + +--echo # +--echo # Delete with a limit and an order by +--echo # + +let $c = c1 in (select a.c2 from t1 a where a.c3 = t1.c3) + order by c3 desc limit 1; +eval create table tmp as select * from t1 where $c; +let $q = delete from t1 where $c; +eval explain select * from t1 where $c; +eval explain $q; +--enable_info ONCE +eval $q; +--sorted_result +select * from t1; +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; + +--echo # +--echo # Delete: 2 execution of PS +--echo # + +prepare create_tmp_stmt from + "create table tmp as select * from t1 + where c2=(select a.c3 from t1 a where a.c3 = ?)"; +prepare delete_t1_stmt from + "delete from t1 where c2=(select a.c3 from t1 a where a.c3 = ?)"; +set @a:=5; +execute create_tmp_stmt using @a; +execute delete_t1_stmt using @a; +execute delete_t1_stmt using @a; +--sorted_result +select * from t1; + +prepare insert_tmp_stmt from + "insert into tmp(c1,c2,c3) select * from t1 + where c2=(select a.c3 from t1 a where a.c3 = ?)"; +set @a:=2; +execute insert_tmp_stmt using @a; +execute delete_t1_stmt using @a; +--sorted_result +select * from t1; + +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +--sorted_result +select * from t1; + +drop table tmp; + +--echo # +--echo # Delete in stored procedure +--echo # + +delimiter //; +create procedure sp() +begin + delete from t1 where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) + order by c3 desc limit 1; +end +// +delimiter ;// + +create table tmp as select * from t1 + where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) + order by c3 desc limit 1; +CALL sp; +insert into tmp(c1,c2,c3) select * from t1 + where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) + order by c3 desc limit 1; +CALL sp; +insert into tmp(c1,c2,c3) select * from t1 + where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) + order by c3 desc limit 1; +CALL sp; +--sorted_result +select * from t1; +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop procedure sp; +drop table tmp; + +--echo # +--echo # Delete in stored function +--echo # +delimiter //; +create function f1(IN a INT) returns int +begin + delete from t1 where c3 < a order by c3 limit 1; + return 1; +end;// +delimiter ;// + +set @a:=7; +create table tmp as select * from t1 where c3 < @a + order by c3 limit 1; +select f1(@a); +insert into tmp(c1,c2,c3) select * from t1 where c3 < @a + order by c3 limit 1; +select f1(@a); +--sorted_result +select * from t1; +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop function f1; +drop table tmp; + +--echo # +--echo # Delete in trigger +--echo # + +create table t2 (c1 integer); +insert into t2(c1) values (1), (2), (3), (4), (5), (6), (7), (8); + +CREATE TABLE cnt(del integer); +INSERT INTO cnt VALUES(0); + +CREATE TRIGGER tr1 AFTER DELETE ON t1 FOR EACH ROW + UPDATE cnt SET del=del+1; +CREATE TRIGGER tr2 AFTER DELETE ON t1 FOR EACH ROW + DELETE FROM t2 WHERE c1> (SELECT count(*)-1 FROM t2); + +CREATE TABLE tmp as SELECT * FROM t1 WHERE c2>=3; +--enable_info ONCE +DELETE FROM t1 WHERE c2>=3; + +--sorted_result +select * from t1; +--sorted_result +SELECT * FROM t2; +SELECT * FROM cnt; + +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; + +DROP TRIGGER tr1; +DROP TRIGGER tr2; +drop table t2, cnt, tmp; + +--echo # +--echo # Delete with a reference to view in subquery +--echo # +let $c = t1.c2 in ( select max(a.c2) from v1 a + where a.c1 = t1.c1); +eval create table tmp as select * from t1 where $c; +let $q = delete from t1 where $c; +eval explain select * from t1 where $c; +eval explain $q; +eval analyze $q; +--sorted_result +select * from t1; +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; + +--echo # +--echo # Delete from view +--echo # + +analyze table t1 persistent for all; + +let $c = v1.c1 in + (select max(a.c1) from t1 a where a.c2 = v1.c2) and c3 = 5; +eval create table tmp as select * from v1 where $c; +let $q = delete from v1 where $c; +eval explain select * from v1 where $c; +eval explain $q; +--enable_info ONCE +eval $q; +--sorted_result +select * from t1; +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; + +--echo # +--echo # Delete from view using reference +--echo # to the same view in subquery +--echo # + +analyze table t1 persistent for all; + +let $c = v1.c2 in (select max(a.c2) from t1 a where a.c3 = v1.c3) + and c1 = 2 + and exists (select 'X' from v1 a where a.c1 = v1.c1); +eval create table tmp as select * from v1 where $c; +let $q = delete from v1 where $c; +--replace_column 9 # +eval explain select * from v1 where $c; +--replace_column 9 # +eval explain $q; +--replace_column 9 # +eval analyze $q; +--sorted_result +select * from t1; +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; diff --git a/mysql-test/include/delete_use_source_cases_memory.inc b/mysql-test/include/delete_use_source_cases_memory.inc new file mode 100644 index 0000000..a246774 --- /dev/null +++ b/mysql-test/include/delete_use_source_cases_memory.inc @@ -0,0 +1,293 @@ +--echo # +--echo # Delete with value from subquery on the same table +--echo # +let $c = c1=(select a.c3 from t1 a where a.c3 = t1.c3); +eval create table tmp as select * from t1 where $c; +let $q = delete from t1 where $c; +eval explain select * from t1 where $c; +eval explain $q; +--enable_info ONCE +eval $q; +--sorted_result +select * from t1; +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; + +--echo # +--echo # Delete with EXISTS subquery over the updated table +--echo # in WHERE + possibly sargable condition +--echo # + +analyze table t1 persistent for all; + +let $c = c1 = 1 and exists (select 'X' from t1 a where a.c1 = t1.c2); +eval create table tmp as select * from t1 where $c; +let $q = delete from t1 where $c; +eval explain select * from t1 where $c; +eval explain $q; +--enable_info ONCE +eval $q; +--sorted_result +select * from t1; +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; + +--echo # +--echo # Delete with EXISTS subquery over the updated table +--echo # in WHERE + non-sargable condition +--echo # + +analyze table t1 persistent for all; + +let $c = exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 = 3; +eval create table tmp as select * from t1 where $c; +let $q = delete from t1 where $c; +eval explain select * from t1 where $c; +eval explain $q; +--enable_info ONCE +eval $q; +--sorted_result +select * from t1; +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; + +--echo # +--echo # Delete with order by +--echo # + +analyze table t1 persistent for all; + +let $c = exists (select 'X' from t1 a where a.c2 = t1.c2) + and c2 >= 3 order by c2; +eval create table tmp as select * from t1 where $c; +let $q = delete from t1 where $c; +eval explain select * from t1 where $c; +eval explain $q; +--enable_info ONCE +eval $q; +--sorted_result +select * from t1; +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; + +--echo # +--echo # Delete with IN predicand over the updated table in WHERE +--echo # +let $c = c3 in (select distinct a.c1 from t1 a where t1.c2=a.c2); +eval create table tmp as select * from t1 where $c; +let $q = delete from t1 where $c; +eval explain select * from t1 where $c; +eval explain $q; +--enable_info ONCE +eval $q; +--sorted_result +select * from t1; +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; + +--echo # +--echo # Delete with a limit - can be deleted +--echo # +let $c = c1 in (select a.c2 from t1 a where a.c2 = t1.c3) limit 1; +eval create table tmp as select * from t1 where $c; +let $q = delete from t1 where $c; +eval explain select * from t1 where $c; +eval explain $q; +--enable_info ONCE +eval $q; +--sorted_result +select * from t1; +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; + +--echo # +--echo # Delete with a limit and an order by +--echo # + +let $c = c1 in (select a.c2 from t1 a where a.c3 = t1.c3) + order by c3 desc limit 1; +eval create table tmp as select * from t1 where $c; +let $q = delete from t1 where $c; +eval explain select * from t1 where $c; +eval explain $q; +--enable_info ONCE +eval $q; +--sorted_result +select * from t1; +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; + +--echo # +--echo # Delete: 2 execution of PS +--echo # + +prepare create_tmp_stmt from + "create table tmp as select * from t1 + where c2=(select a.c3 from t1 a where a.c3 = ?)"; +prepare delete_t1_stmt from + "delete from t1 where c2=(select a.c3 from t1 a where a.c3 = ?)"; +set @a:=5; +execute create_tmp_stmt using @a; +execute delete_t1_stmt using @a; +execute delete_t1_stmt using @a; +--sorted_result +select * from t1; + +prepare insert_tmp_stmt from + "insert into tmp(c1,c2,c3) select * from t1 + where c2=(select a.c3 from t1 a where a.c3 = ?)"; +set @a:=2; +execute insert_tmp_stmt using @a; +execute delete_t1_stmt using @a; +--sorted_result +select * from t1; +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +--sorted_result +select * from t1; + +drop table tmp; + +--echo # +--echo # Delete in stored procedure +--echo # + +delimiter //; +create procedure sp() +begin + delete from t1 where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) + order by c3 desc limit 1; +end +// +delimiter ;// + +create table tmp as select * from t1 + where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) + order by c3 desc limit 1; +CALL sp; +insert into tmp(c1,c2,c3) select * from t1 + where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) + order by c3 desc limit 1; +CALL sp; +insert into tmp(c1,c2,c3) select * from t1 + where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) + order by c3 desc limit 1; +CALL sp; +--sorted_result +select * from t1; +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop procedure sp; +drop table tmp; + +--echo # +--echo # Delete in stored function +--echo # +delimiter //; +create function f1(IN a INT) returns int +begin + delete from t1 where c3 < a order by c3 limit 1; + return 1; +end;// +delimiter ;// + +set @a:=7; +create table tmp as select * from t1 where c3 < @a + order by c3 limit 1; +select f1(@a); +insert into tmp(c1,c2,c3) select * from t1 where c3 < @a + order by c3 limit 1; +select f1(@a); +--sorted_result +select * from t1; +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop function f1; +drop table tmp; + +--echo # +--echo # Delete in trigger +--echo # + +create table t2 (c1 integer); +insert into t2(c1) values (1), (2), (3), (4), (5), (6), (7), (8); + +CREATE TABLE cnt(del integer); +INSERT INTO cnt VALUES(0); + +CREATE TRIGGER tr1 AFTER DELETE ON t1 FOR EACH ROW + UPDATE cnt SET del=del+1; +CREATE TRIGGER tr2 AFTER DELETE ON t1 FOR EACH ROW + DELETE FROM t2 WHERE c1> (SELECT count(*)-1 FROM t2); + +CREATE TABLE tmp as SELECT * FROM t1 WHERE c2>=3; +--enable_info ONCE +DELETE FROM t1 WHERE c2>=3; + +--sorted_result +select * from t1; +--sorted_result +SELECT * FROM t2; +SELECT * FROM cnt; + +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; + +DROP TRIGGER tr1; +DROP TRIGGER tr2; +drop table t2, cnt, tmp; + +--echo # +--echo Delete with a reference to view in subquery +--echo # +let $c = t1.c2 in ( select max(a.c2) from v1 a + where a.c1 = t1.c1); +eval create table tmp as select * from t1 where $c; +let $q = delete from t1 where $c; +eval explain select * from t1 where $c; +eval explain $q; +--enable_info ONCE +eval $q; +--sorted_result +select * from t1; +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; + +--echo # +--echo # Delete from view +--echo # + +analyze table t1 persistent for all; + +let $c = v1.c1 in + (select max(a.c1) from t1 a where a.c2 = v1.c2) and c3 = 5; +eval create table tmp as select * from v1 where $c; +let $q = delete from v1 where $c; +eval explain select * from v1 where $c; +eval explain $q; +--enable_info ONCE +eval $q; +--sorted_result +select * from t1; +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; + +--echo # +--echo # Delete from view using reference +--echo # to the same view in subquery +--echo # + +analyze table t1 persistent for all; + +let $c = v1.c2 in (select max(a.c2) from t1 a where a.c3 = v1.c3) + and c1 = 2 + and exists (select 'X' from v1 a where a.c1 = v1.c1); +eval create table tmp as select * from v1 where $c; +let $q = delete from v1 where $c; +--replace_column 9 # +eval explain select * from v1 where $c; +--replace_column 9 # +eval explain $q; +--enable_info ONCE +eval $q; +--sorted_result +select * from t1; +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; + diff --git a/mysql-test/include/delete_use_source_memory.inc b/mysql-test/include/delete_use_source_memory.inc new file mode 100644 index 0000000..8e4640b --- /dev/null +++ b/mysql-test/include/delete_use_source_memory.inc @@ -0,0 +1,27 @@ +create table t1 (c1 integer, c2 integer, c3 integer); + +insert into t1(c1,c2,c3) + values (1,1,1),(1,2,2),(1,3,3), + (2,1,4),(2,2,5),(2,3,6), + (2,4,7),(2,5,8); +insert into t1 select c1+10,c2,c3+10 from t1; +insert into t1 select c1+20,c2+1,c3+20 from t1; +analyze table t1 persistent for all; + +create view v1 as select * from t1 where c2=2; + +--echo Test without any index +--source include/delete_use_source_cases_memory.inc + +--echo Test with an index +create index t1_c2 on t1 (c2,c1); +--source include/delete_use_source_cases_memory.inc + +--echo Test with a primary key +drop index t1_c2 on t1; +alter table t1 add primary key (c3); +--source include/delete_use_source_cases_memory.inc + +drop view v1; +drop table t1; + diff --git a/mysql-test/include/update_use_source.inc b/mysql-test/include/update_use_source.inc index 3c48770..196f141 100644 --- a/mysql-test/include/update_use_source.inc +++ b/mysql-test/include/update_use_source.inc @@ -1,150 +1,189 @@ # Include to test update with same table as source and target ---echo # ---echo # Update a with value from subquery on the same table, no search clause. ALL access ---echo # - -#Enable view protocol after fix MDEV-29207 ---disable_view_protocol -start transaction; +create table t1 (old_c1 integer, + old_c2 integer, + c1 integer, + c2 integer, + c3 integer); +insert into t1 select c1+10,c2,c3+10, NULL, NULL from t1; +insert into t1 select c1+20,c2+1,c3+20, NULL, NULL from t1; +analyze table t1 persistent for all; + +create view v1 as select * from t1 where c2=2; +delimiter /; +create trigger trg_t1 before update on t1 for each row +begin + set new.old_c1=old.c1; + set new.old_c2=old.c2; +end; +/ +delimiter ;/ + +insert into t1(c1,c2,c3) + values (1,1,1), (1,2,2), (1,3,3), + (2,1,4), (2,2,5), (2,3,6), + (2,4,7), (2,5,8); +analyze table t1; +select * from t1; + +create table tmp as select * from t1; + +--echo # Test without any index +--source include/update_use_source_cases.inc + +--echo # Test with an index on updated columns +create index t1_c2 on t1 (c2,c1); +analyze table t1; +--source include/update_use_source_cases.inc + +--echo # Test with an index on updated columns +create index t1_c3 on t1 (c3); +analyze table t1; +--source include/update_use_source_cases.inc + +--echo # Test with a primary key on updated columns +drop index t1_c3 on t1; +alter table t1 add primary key (c3); +analyze table t1; +--source include/update_use_source_cases.inc + +--echo # Update with error "Subquery returns more than 1 row" +--error ER_SUBQUERY_NO_1_ROW +update t1 set c2=(select c2 from t1); +--sorted_result +select c1,c2,c3 from t1; + +--echo # Update with error "Subquery returns more than 1 row" +--echo # and order by +--error ER_SUBQUERY_NO_1_ROW +update t1 set c2=(select c2 from t1) order by c3; +--sorted_result +select c1,c2,c3 from t1; + +-- echo # Duplicate value on update a primary key +--error ER_DUP_ENTRY + +update t1 set c3=0 + where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 >= 3; +--sorted_result +select c1,c2,c3 from t1; +truncate table t1; +insert into t1 select * from tmp; + +-- echo # Duplicate value on update a primary key with ignore --enable_info ONCE -update t1 - set c1=(select a.c3 - from t1 a - where a.c3 = t1.c3); -select concat(old_c1,'->',c1),c3, case when c1 != old_c1 then '*' else ' ' end "Changed" from t1 ; -rollback; - ---echo # ---echo # Update with search clause on the same table ---echo # - -start transaction; +update ignore t1 set c3=0 + where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 >= 3; +--sorted_result +select c1,c2,c3 from t1; +truncate table t1; +insert into t1 select * from tmp; + +-- echo # Duplicate value on update a primary key and limit +--error ER_DUP_ENTRY +update t1 set c3=0 + where exists (select 'X' from t1 a where a.c2 = t1.c2) + and c2 >= 3 limit 2; +--sorted_result +select c1,c2,c3 from t1; +truncate table t1; +insert into t1 select * from tmp; + +-- echo # Duplicate value on update a primary key with ignore +-- echo # and limit --enable_info ONCE -update t1 - set c1=10 - where c1 <2 - and exists (select 'X' - from t1 a - where a.c1 = t1.c1); -select concat(old_c1,'->',c1),c3, case when c1 != old_c1 then '*' else ' ' end "Changed" from t1 ; -rollback; - ---echo # ---echo # Update via RANGE or INDEX access if an index or a primary key exists ---echo # - -explain update t1 set c1=0 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 > 3; -start transaction; +update ignore t1 set c3=0 + where exists (select 'X' from t1 a where a.c2 = t1.c2) + and c2 >= 3 limit 2; +--sorted_result +select c1,c2,c3 from t1; +truncate table t1; +insert into t1 select * from tmp; + +--echo # Update no rows found --enable_info ONCE -update t1 set c1=c1+10 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 >= 3; -select concat(old_c1,'->',c1),c3, case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; -rollback; - ---echo # ---echo # Update with order by ---echo # - -start transaction; -update t1 set c1=c1+10 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 >= 3 order by c2; -select concat(old_c1,'->',c1),c3, case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; -rollback; - ---echo # ---echo Update using a view in subquery ---echo # - -start transaction; +update t1 set c1=10 + where c1 <2 and exists (select 'X' from t1 a where a.c1 = t1.c1 + 10); +--sorted_result +select c1,c2,c3 from t1; +truncate table t1; +insert into t1 select * from tmp; + +--echo # Update no rows changed +drop trigger trg_t1; --enable_info ONCE -update t1 - set c1=c1 +(select max(a.c2) - from v1 a - where a.c1 = t1.c1) ; -select concat(old_c1,'->',c1),c3, case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; -rollback; +update t1 set c1=c1 + where c1 <2 and exists (select 'X' from t1 a where a.c1 = t1.c1); +--sorted_result +select c1,c2,c3 from t1; +truncate table t1; +insert into t1 select * from tmp; --echo # ---echo # Update throw a view +--echo # Check call of after trigger --echo # -start transaction; ---enable_info ONCE -update v1 - set c1=c1 + (select max(a.c2) - from t1 a - where a.c1 = v1.c1) +10 -where c3 > 3; -select concat(old_c1,'->',c1),c3, case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; -rollback; - ---echo # ---echo # Update through a view and using the view in subquery ---echo # +delimiter /; +create or replace trigger trg_t2 after update on t1 for each row +begin + declare msg varchar(100); + if (new.c3 = 5) then + set msg=concat('in after update trigger on ',new.c3); + SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = msg; + end if; +end; +/ +delimiter ;/ +--error 1644 -start transaction; ---enable_info ONCE -update v1 - set c1=c1 + 1 - where c1 <2 - and exists (select 'X' - from v1 a - where a.c1 = v1.c1); -select concat(old_c1,'->',c1),c3, case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; -rollback; +update t1 set c1=2 + where c3 in (select distinct a.c3 from t1 a where a.c1=t1.c1); +--sorted_result +select c1,c2,c3 from t1; +truncate table t1; +insert into t1 select * from tmp; --echo # ---echo # Update through a view and using the view in subquery +--echo # Check update with order by and after trigger --echo # -start transaction; ---enable_info ONCE -update v1 - set c1=(select max(a.c1)+10 - from v1 a - where a.c1 = v1.c1) - where c1 <10 - and exists (select 'X' - from v1 a - where a.c2 = v1.c2); -select concat(old_c1,'->',c1),c3, case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; -rollback; +--error 1644 +update t1 set c1=2 + where c3 in (select distinct a.c3 from t1 a where a.c1=t1.c1) + order by t1.c2, t1.c1; +--sorted_result +select c1,c2,c3 from t1; +truncate table t1; +insert into t1 select * from tmp; + +drop view v1; --echo # ---echo # Update of the index or primary key (c3) +--echo # Check update on view with check option --echo # -start transaction; -explain update t1 set c3=c3+10 where c2 in (select distinct a.c2 from t1 a where t1.c1=a.c1); ---enable_info ONCE -update t1 set c3=c3+10 where c2 in (select distinct a.c2 from t1 a where t1.c1=a.c1); -select c3 from t1; -rollback; +create view v1 as select * from t1 where c2=2 with check option; ---echo # ---echo # update with a limit ---echo # +-- error 1369 +update v1 set c2=3 where c1=1; +--sorted_result +select c1,c2,c3 from t1; +truncate table t1; +insert into t1 select * from tmp; -start transaction; ---enable_info ONCE -update t1 - set c1=(select a.c3 - from t1 a - where a.c3 = t1.c3) - limit 2; -select concat(old_c1,'->',c1),c3, case when c1 != old_c1 then '*' else ' ' end "Changed" from t1 ; -rollback; +-- error 1369 +update v1 set c2=(select max(c3) from v1) where c1=1; +--sorted_result +select c1,c2,c3 from t1; +truncate table t1; +insert into t1 select * from tmp; ---echo # ---echo # update with a limit and an order by ---echo # +update v1 set c2=(select min(va.c3) from v1 va), c1=0 where c1=1; +--sorted_result +select c1,c2,c3 from t1; +truncate table t1; +insert into t1 select * from tmp; -start transaction; ---enable_info ONCE -update t1 - set c1=(select a.c3 - from t1 a - where a.c3 = t1.c3) - order by c3 desc limit 2; -select concat(old_c1,'->',c1),c3, case when c1 != old_c1 then '*' else ' ' end "Changed" from t1 ; -rollback; ---enable_view_protocol +drop table tmp; +drop view v1; +drop table t1; diff --git a/mysql-test/include/update_use_source_cases.inc b/mysql-test/include/update_use_source_cases.inc new file mode 100644 index 0000000..55b45a3 --- /dev/null +++ b/mysql-test/include/update_use_source_cases.inc @@ -0,0 +1,159 @@ +--echo # +--echo # Update with value from subquery on the same table +--echo # + +let $q=update t1 set c1=(select a.c3 from t1 a where a.c3 = t1.c3); +eval explain $q; +--enable_info ONCE +eval $q; +select concat(old_c1,'->',c1),c3, + case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +truncate table t1; +insert into t1 select * from tmp; + +--echo # +--echo # Update with EXISTS subquery over the updated table +--echo # in WHERE + possibly sargable condition +--echo # + +let $q=update t1 set c1=10 + where c1 <2 + and exists (select 'X' from t1 a where a.c1 = t1.c1); +eval explain $q; +--enable_info ONCE +eval $q; +select concat(old_c1,'->',c1),c3, + case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +truncate table t1; +insert into t1 select * from tmp; + +--echo # +--echo # Update with EXISTS subquery over the updated table +--echo # in WHERE + non-sargable condition +--echo # + +let $q=update t1 set c1=c1+10 + where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 >= 3; +eval explain $q; +--enable_info ONCE +eval $q; +select concat(old_c1,'->',c1),c3, + case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +truncate table t1; +insert into t1 select * from tmp; + +--echo # +--echo # Update with order by +--echo # + +let $q=update t1 set c1=c1+10 + where exists (select 'X' from t1 a where a.c2 = t1.c2) + and c2 >= 3 order by c2; +eval explain $q; +--enable_info ONCE +eval $q; +select concat(old_c1,'->',c1),c3, + case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +truncate table t1; +insert into t1 select * from tmp; + +--echo # +--echo # Update with a reference to view in subquery +--echo # + +let $q=update t1 set c1=c1 +(select max(a.c2) from v1 a + where a.c1 = t1.c1); +eval explain $q; +--enable_info ONCE +eval $q; +select concat(old_c1,'->',c1),c3, + case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +truncate table t1; +insert into t1 select * from tmp; + +--echo # +--echo # Update view +--echo # + +let $q=update v1 set c1=c1 + (select max(a.c2) from t1 a + where a.c1 = v1.c1) +10 where c3 > 3; +eval explain $q; +--enable_info ONCE +eval $q; +select concat(old_c1,'->',c1),c3, + case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +truncate table t1; +insert into t1 select * from tmp; + +--echo # +--echo # Update view with reference to the same view in subquery +--echo # + +let $q=update v1 set c1=c1 + 1 + where c1 <2 + and exists (select 'X' from v1 a where a.c1 = v1.c1); +eval explain $q; +--enable_info ONCE +eval $q; +select concat(old_c1,'->',c1),c3, + case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +truncate table t1; +insert into t1 select * from tmp; + +--echo # +--echo # Update view with EXISTS and reference to the same view in subquery +--echo # + +let $q=update v1 + set c1=(select max(a.c1)+10 from v1 a where a.c1 = v1.c1) + where c1 <10 and exists (select 'X' from v1 a where a.c2 = v1.c2); +eval explain $q; +--enable_info ONCE +eval $q; +select concat(old_c1,'->',c1),c3, + case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +truncate table t1; +insert into t1 select * from tmp; + +--echo # +--echo # Update with IN predicand over the updated table in WHERE +--echo # + +let $q=update t1 set c3=c3+10 + where c2 in (select distinct a.c2 from t1 a where t1.c1=a.c1); +eval explain $q; +--enable_info ONCE +eval $q; +--sorted_result +select c3 from t1; +truncate table t1; +insert into t1 select * from tmp; + +--echo # +--echo # Update with a limit +--echo # + +let $q=update t1 + set c1=(select a.c3 from t1 a where a.c3 = t1.c3) limit 2; +eval explain $q; +--enable_info ONCE +eval $q; +select concat(old_c1,'->',c1),c3, + case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +truncate table t1; +insert into t1 select * from tmp; + +--echo # +--echo # Update with a limit and an order by +--echo # + +let $q=update t1 + set c1=(select a.c3 from t1 a where a.c3 = t1.c3) + order by c3 desc limit 2; +#eval explain $q; +--enable_info ONCE +eval $q; +select concat(old_c1,'->',c1),c3, + case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +truncate table t1; +insert into t1 select * from tmp; diff --git a/mysql-test/include/update_use_source_ext.inc b/mysql-test/include/update_use_source_ext.inc new file mode 100644 index 0000000..004f7a9 --- /dev/null +++ b/mysql-test/include/update_use_source_ext.inc @@ -0,0 +1,59 @@ +--echo # +--echo # Test on dynamic columns (blob) +--echo # + +create table assets ( + item_name varchar(32) primary key, -- A common attribute for all items + dynamic_cols blob -- Dynamic columns will be stored here +); +INSERT INTO assets VALUES ('MariaDB T-shirt', + COLUMN_CREATE('color', 'blue', 'size', 'XL')); +INSERT INTO assets VALUES ('Thinkpad Laptop', + COLUMN_CREATE('color', 'black', 'price', 500)); +SELECT item_name, COLUMN_GET(dynamic_cols, 'color' as char) AS color + FROM assets; +UPDATE assets + SET dynamic_cols=COLUMN_ADD(dynamic_cols, 'warranty', '3 years') + WHERE item_name='Thinkpad Laptop'; +SELECT item_name, + COLUMN_GET(dynamic_cols, 'warranty' as char) AS color + FROM assets; +UPDATE assets + SET dynamic_cols=COLUMN_ADD(dynamic_cols, 'warranty', '4 years') + WHERE item_name in + (select b.item_name from assets b + where COLUMN_GET(b.dynamic_cols, 'color' as char) ='black'); +SELECT item_name, + COLUMN_GET(dynamic_cols, 'warranty' as char) AS color + FROM assets; + +UPDATE assets SET dynamic_cols=COLUMN_ADD(dynamic_cols, 'warranty', + (select COLUMN_GET(b.dynamic_cols, 'color' as char) + from assets b + where assets.item_name = item_name)); +SELECT item_name, + COLUMN_GET(dynamic_cols, 'warranty' as char) AS color + FROM assets; +drop table assets; + +--echo # +--echo # Test on fulltext columns +--echo # +CREATE TABLE ft2(copy TEXT,FULLTEXT(copy)); +INSERT INTO ft2(copy) VALUES + ('MySQL vs MariaDB database'), + ('Oracle vs MariaDB database'), + ('PostgreSQL vs MariaDB database'), + ('MariaDB overview'), + ('Foreign keys'), + ('Primary keys'), + ('Indexes'), + ('Transactions'), + ('Triggers'); +SELECT * FROM ft2 WHERE MATCH(copy) AGAINST('database'); + +update ft2 set copy = (select max(concat('mykeyword ',substr(b.copy,1,5))) + from ft2 b WHERE MATCH(b.copy) AGAINST('database')) + where MATCH(copy) AGAINST('keys'); +SELECT * FROM ft2 WHERE MATCH(copy) AGAINST('mykeyword'); +drop table ft2; diff --git a/mysql-test/main/delete_single_to_multi.result b/mysql-test/main/delete_single_to_multi.result index 9bd5e93..b49f07e 100644 --- a/mysql-test/main/delete_single_to_multi.result +++ b/mysql-test/main/delete_single_to_multi.result @@ -2390,4 +2390,627 @@ o_orderkey o_totalprice 4903 34363.63 5607 24660.06 drop table t; +# LooseScan +# ========= +create index i_l_sup_part on lineitem(l_suppkey, l_partkey); +create index i_ps_sup_part on partsupp(ps_suppkey, ps_partkey); +analyze table lineitem; +Table Op Msg_type Msg_text +dbt3_s001.lineitem analyze status Engine-independent statistics collected +dbt3_s001.lineitem analyze status Table is already up to date +analyze table partsupp; +Table Op Msg_type Msg_text +dbt3_s001.partsupp analyze status Engine-independent statistics collected +dbt3_s001.partsupp analyze status Table is already up to date +explain +select count(*) from lineitem where l_suppkey in +(select ps_suppkey from partsupp +where ps_partkey in (1,2,3)); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY partsupp index PRIMARY,i_ps_partkey,i_ps_suppkey,i_ps_sup_part i_ps_sup_part 8 NULL 700 Using where; Using index; LooseScan +1 PRIMARY lineitem ref i_l_suppkey,i_l_sup_part i_l_suppkey 5 dbt3_s001.partsupp.ps_suppkey 600 Using index +explain format=json +select count(*) from lineitem where l_suppkey in +(select ps_suppkey from partsupp +where ps_partkey in (1,2,3)); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "nested_loop": [ + { + "table": { + "table_name": "partsupp", + "access_type": "index", + "possible_keys": [ + "PRIMARY", + "i_ps_partkey", + "i_ps_suppkey", + "i_ps_sup_part" + ], + "key": "i_ps_sup_part", + "key_length": "8", + "used_key_parts": ["ps_suppkey", "ps_partkey"], + "rows": 700, + "filtered": 1.428571463, + "attached_condition": "partsupp.ps_partkey in (1,2,3)", + "using_index": true, + "loose_scan": true + } + }, + { + "table": { + "table_name": "lineitem", + "access_type": "ref", + "possible_keys": ["i_l_suppkey", "i_l_sup_part"], + "key": "i_l_suppkey", + "key_length": "5", + "used_key_parts": ["l_suppkey"], + "ref": ["dbt3_s001.partsupp.ps_suppkey"], + "rows": 600, + "filtered": 100, + "using_index": true + } + } + ] + } +} +select count(*) from lineitem where l_suppkey in +(select ps_suppkey from partsupp +where ps_partkey in (1,2,3)); +count(*) +5373 +create table t as +select * from lineitem where l_suppkey in +(select ps_suppkey from partsupp +where ps_partkey in (1,2,3)); +explain +delete from lineitem where l_suppkey in +(select ps_suppkey from partsupp +where ps_partkey in (1,2,3)); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY partsupp index PRIMARY,i_ps_partkey,i_ps_suppkey,i_ps_sup_part i_ps_sup_part 8 NULL 700 Using where; Using index; LooseScan +1 PRIMARY lineitem ref i_l_suppkey,i_l_sup_part i_l_suppkey 5 dbt3_s001.partsupp.ps_suppkey 600 +explain format=json +delete from lineitem where l_suppkey in +(select ps_suppkey from partsupp +where ps_partkey in (1,2,3)); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "nested_loop": [ + { + "table": { + "table_name": "partsupp", + "access_type": "index", + "possible_keys": [ + "PRIMARY", + "i_ps_partkey", + "i_ps_suppkey", + "i_ps_sup_part" + ], + "key": "i_ps_sup_part", + "key_length": "8", + "used_key_parts": ["ps_suppkey", "ps_partkey"], + "rows": 700, + "filtered": 1.428571463, + "attached_condition": "partsupp.ps_partkey in (1,2,3)", + "using_index": true, + "loose_scan": true + } + }, + { + "table": { + "table_name": "lineitem", + "access_type": "ref", + "possible_keys": ["i_l_suppkey", "i_l_sup_part"], + "key": "i_l_suppkey", + "key_length": "5", + "used_key_parts": ["l_suppkey"], + "ref": ["dbt3_s001.partsupp.ps_suppkey"], + "rows": 600, + "filtered": 100 + } + } + ] + } +} +delete from lineitem where l_suppkey in +(select ps_suppkey from partsupp +where ps_partkey in (1,2,3)); +select count(*) from lineitem where l_suppkey in +(select ps_suppkey from partsupp +where ps_partkey in (1,2,3)); +count(*) +0 +insert into lineitem select * from t; +select count(*) from lineitem where l_suppkey in +(select ps_suppkey from partsupp +where ps_partkey in (1,2,3)); +count(*) +5373 +drop table t; +# LooseScan PS +# ============ +prepare stmt from " +delete from lineitem where l_suppkey in +(select ps_suppkey from partsupp +where ps_partkey in (1,2,3)); +"; +select count(*) from lineitem where l_suppkey in +(select ps_suppkey from partsupp +where ps_partkey in (1,2,3)); +count(*) +5373 +create table t as +select * from lineitem where l_suppkey in +(select ps_suppkey from partsupp +where ps_partkey in (1,2,3)); +execute stmt; +select count(*) from lineitem where l_suppkey in +(select ps_suppkey from partsupp +where ps_partkey in (1,2,3)); +count(*) +0 +insert into lineitem select * from t; +select count(*) from lineitem where l_suppkey in +(select ps_suppkey from partsupp +where ps_partkey in (1,2,3)); +count(*) +5373 +create table r as +select * from lineitem where l_suppkey in +(select ps_suppkey from partsupp +where ps_partkey in (1,2,3)); +execute stmt; +select count(*) from lineitem where l_suppkey in +(select ps_suppkey from partsupp +where ps_partkey in (1,2,3)); +count(*) +0 +insert into lineitem select * from r; +select count(*) from lineitem where l_suppkey in +(select ps_suppkey from partsupp +where ps_partkey in (1,2,3)); +count(*) +5373 +drop tables r, t; +deallocate prepare stmt; +# LooseScan SP +# ============ +create procedure p() +delete from lineitem where l_suppkey in +(select ps_suppkey from partsupp +where ps_partkey in (1,2,3)); +select count(*) from lineitem where l_suppkey in +(select ps_suppkey from partsupp +where ps_partkey in (1,2,3)); +count(*) +5373 +create table t as +select * from lineitem where l_suppkey in +(select ps_suppkey from partsupp +where ps_partkey in (1,2,3)); +call p(); +select count(*) from lineitem where l_suppkey in +(select ps_suppkey from partsupp +where ps_partkey in (1,2,3)); +count(*) +0 +insert into lineitem select * from t; +select count(*) from lineitem where l_suppkey in +(select ps_suppkey from partsupp +where ps_partkey in (1,2,3)); +count(*) +5373 +create table r as +select * from lineitem where l_suppkey in +(select ps_suppkey from partsupp +where ps_partkey in (1,2,3)); +call p(); +select count(*) from lineitem where l_suppkey in +(select ps_suppkey from partsupp +where ps_partkey in (1,2,3)); +count(*) +0 +insert into lineitem select * from r; +select count(*) from lineitem where l_suppkey in +(select ps_suppkey from partsupp +where ps_partkey in (1,2,3)); +count(*) +5373 +drop tables r, t; +drop procedure p; +drop index i_l_sup_part on lineitem; +drop index i_ps_sup_part on partsupp; +# DuplicateWeedout +# ================ +set @tmp_optimizer_switch= @@optimizer_switch; +set optimizer_switch='materialization=off'; +analyze table lineitem; +Table Op Msg_type Msg_text +dbt3_s001.lineitem analyze status Engine-independent statistics collected +dbt3_s001.lineitem analyze status Table is already up to date +analyze table orders; +Table Op Msg_type Msg_text +dbt3_s001.orders analyze status Engine-independent statistics collected +dbt3_s001.orders analyze status OK +explain +select count(*) from lineitem where l_partkey in ( +select ps_partkey +from partsupp join lineitem on ps_partkey=l_partkey +where ps_suppkey in ( +select s_suppkey from supplier where s_suppkey < 2 +) +); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY supplier range PRIMARY PRIMARY 4 NULL 1 Using where; Using index; Start temporary +1 PRIMARY partsupp ref PRIMARY,i_ps_partkey,i_ps_suppkey i_ps_suppkey 4 dbt3_s001.supplier.s_suppkey 70 Using where +1 PRIMARY lineitem ref i_l_suppkey_partkey,i_l_partkey i_l_partkey 5 dbt3_s001.partsupp.ps_partkey 30 Using index +1 PRIMARY lineitem ref i_l_suppkey_partkey,i_l_partkey i_l_partkey 5 dbt3_s001.partsupp.ps_partkey 30 Using index; End temporary +explain format=json +select count(*) from lineitem where l_partkey in ( +select ps_partkey +from partsupp join lineitem on ps_partkey=l_partkey +where ps_suppkey in ( +select s_suppkey from supplier where s_suppkey < 2 +) +); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "nested_loop": [ + { + "duplicates_removal": [ + { + "table": { + "table_name": "supplier", + "access_type": "range", + "possible_keys": ["PRIMARY"], + "key": "PRIMARY", + "key_length": "4", + "used_key_parts": ["s_suppkey"], + "rows": 1, + "filtered": 100, + "attached_condition": "supplier.s_suppkey < 2", + "using_index": true + } + }, + { + "table": { + "table_name": "partsupp", + "access_type": "ref", + "possible_keys": ["PRIMARY", "i_ps_partkey", "i_ps_suppkey"], + "key": "i_ps_suppkey", + "key_length": "4", + "used_key_parts": ["ps_suppkey"], + "ref": ["dbt3_s001.supplier.s_suppkey"], + "rows": 70, + "filtered": 100, + "attached_condition": "partsupp.ps_partkey is not null" + } + }, + { + "table": { + "table_name": "lineitem", + "access_type": "ref", + "possible_keys": ["i_l_suppkey_partkey", "i_l_partkey"], + "key": "i_l_partkey", + "key_length": "5", + "used_key_parts": ["l_partkey"], + "ref": ["dbt3_s001.partsupp.ps_partkey"], + "rows": 30, + "filtered": 100, + "using_index": true + } + }, + { + "table": { + "table_name": "lineitem", + "access_type": "ref", + "possible_keys": ["i_l_suppkey_partkey", "i_l_partkey"], + "key": "i_l_partkey", + "key_length": "5", + "used_key_parts": ["l_partkey"], + "ref": ["dbt3_s001.partsupp.ps_partkey"], + "rows": 30, + "filtered": 100, + "using_index": true + } + } + ] + } + ] + } +} +select count(*) from lineitem where l_partkey in ( +select ps_partkey +from partsupp join lineitem on ps_partkey=l_partkey +where ps_suppkey in ( +select s_suppkey from supplier where s_suppkey < 2 +) +); +count(*) +2126 +create table t as +select * from lineitem where l_partkey in ( +select ps_partkey +from partsupp join lineitem on ps_partkey=l_partkey +where ps_suppkey in ( +select s_suppkey from supplier where s_suppkey < 2 +) +); +explain +delete from lineitem where l_partkey in ( +select ps_partkey +from partsupp join lineitem on ps_partkey=l_partkey +where ps_suppkey in ( +select s_suppkey from supplier where s_suppkey < 2 +) +); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY supplier range PRIMARY PRIMARY 4 NULL 1 Using where; Using index; Start temporary +1 PRIMARY partsupp ref PRIMARY,i_ps_partkey,i_ps_suppkey i_ps_suppkey 4 dbt3_s001.supplier.s_suppkey 70 Using where +1 PRIMARY lineitem ref i_l_suppkey_partkey,i_l_partkey i_l_partkey 5 dbt3_s001.partsupp.ps_partkey 30 +1 PRIMARY lineitem ref i_l_suppkey_partkey,i_l_partkey i_l_partkey 5 dbt3_s001.partsupp.ps_partkey 30 Using index; End temporary +explain format=json +delete from lineitem where l_partkey in ( +select ps_partkey +from partsupp join lineitem on ps_partkey=l_partkey +where ps_suppkey in ( +select s_suppkey from supplier where s_suppkey < 2 +) +); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "nested_loop": [ + { + "duplicates_removal": [ + { + "table": { + "table_name": "supplier", + "access_type": "range", + "possible_keys": ["PRIMARY"], + "key": "PRIMARY", + "key_length": "4", + "used_key_parts": ["s_suppkey"], + "rows": 1, + "filtered": 100, + "attached_condition": "supplier.s_suppkey < 2", + "using_index": true + } + }, + { + "table": { + "table_name": "partsupp", + "access_type": "ref", + "possible_keys": ["PRIMARY", "i_ps_partkey", "i_ps_suppkey"], + "key": "i_ps_suppkey", + "key_length": "4", + "used_key_parts": ["ps_suppkey"], + "ref": ["dbt3_s001.supplier.s_suppkey"], + "rows": 70, + "filtered": 100, + "attached_condition": "partsupp.ps_partkey is not null" + } + }, + { + "table": { + "table_name": "lineitem", + "access_type": "ref", + "possible_keys": ["i_l_suppkey_partkey", "i_l_partkey"], + "key": "i_l_partkey", + "key_length": "5", + "used_key_parts": ["l_partkey"], + "ref": ["dbt3_s001.partsupp.ps_partkey"], + "rows": 30, + "filtered": 100 + } + }, + { + "table": { + "table_name": "lineitem", + "access_type": "ref", + "possible_keys": ["i_l_suppkey_partkey", "i_l_partkey"], + "key": "i_l_partkey", + "key_length": "5", + "used_key_parts": ["l_partkey"], + "ref": ["dbt3_s001.partsupp.ps_partkey"], + "rows": 30, + "filtered": 100, + "using_index": true + } + } + ] + } + ] + } +} +delete from lineitem where l_partkey in ( +select ps_partkey +from partsupp join lineitem on ps_partkey=l_partkey +where ps_suppkey in ( +select s_suppkey from supplier where s_suppkey < 2 +) +); +select count(*) from lineitem where l_partkey in ( +select ps_partkey +from partsupp join lineitem on ps_partkey=l_partkey +where ps_suppkey in ( +select s_suppkey from supplier where s_suppkey < 2 +) +); +count(*) +0 +insert into lineitem select * from t; +select count(*) from lineitem where l_partkey in ( +select ps_partkey +from partsupp join lineitem on ps_partkey=l_partkey +where ps_suppkey in ( +select s_suppkey from supplier where s_suppkey < 2 +) +); +count(*) +2126 +drop table t; +# DuplicateWeedout PS +# =================== +prepare stmt from " +delete from lineitem where l_partkey in ( +select ps_partkey +from partsupp join lineitem on ps_partkey=l_partkey +where ps_suppkey in ( +select s_suppkey from supplier where s_suppkey < 2 +) +); +"; +select count(*) from lineitem where l_partkey in ( +select ps_partkey +from partsupp join lineitem on ps_partkey=l_partkey +where ps_suppkey in ( +select s_suppkey from supplier where s_suppkey < 2 +) +); +count(*) +2126 +create table t as +select * from lineitem where l_partkey in ( +select ps_partkey +from partsupp join lineitem on ps_partkey=l_partkey +where ps_suppkey in ( +select s_suppkey from supplier where s_suppkey < 2 +) +); +execute stmt; +select count(*) from lineitem where l_partkey in ( +select ps_partkey +from partsupp join lineitem on ps_partkey=l_partkey +where ps_suppkey in ( +select s_suppkey from supplier where s_suppkey < 2 +) +); +count(*) +0 +insert into lineitem select * from t; +select count(*) from lineitem where l_partkey in ( +select ps_partkey +from partsupp join lineitem on ps_partkey=l_partkey +where ps_suppkey in ( +select s_suppkey from supplier where s_suppkey < 2 +) +); +count(*) +2126 +create table r as +select * from lineitem where l_partkey in ( +select ps_partkey +from partsupp join lineitem on ps_partkey=l_partkey +where ps_suppkey in ( +select s_suppkey from supplier where s_suppkey < 2 +) +); +execute stmt; +select count(*) from lineitem where l_partkey in ( +select ps_partkey +from partsupp join lineitem on ps_partkey=l_partkey +where ps_suppkey in ( +select s_suppkey from supplier where s_suppkey < 2 +) +); +count(*) +0 +insert into lineitem select * from r; +select count(*) from lineitem where l_partkey in ( +select ps_partkey +from partsupp join lineitem on ps_partkey=l_partkey +where ps_suppkey in ( +select s_suppkey from supplier where s_suppkey < 2 +) +); +count(*) +2126 +drop tables r, t; +deallocate prepare stmt; +# DuplicateWeedout SP +# =================== +create procedure p() +delete from lineitem where l_partkey in ( +select ps_partkey +from partsupp join lineitem on ps_partkey=l_partkey +where ps_suppkey in ( +select s_suppkey from supplier where s_suppkey < 2 +) +); +select count(*) from lineitem where l_partkey in ( +select ps_partkey +from partsupp join lineitem on ps_partkey=l_partkey +where ps_suppkey in ( +select s_suppkey from supplier where s_suppkey < 2 +) +); +count(*) +2126 +create table t as +select * from lineitem where l_partkey in ( +select ps_partkey +from partsupp join lineitem on ps_partkey=l_partkey +where ps_suppkey in ( +select s_suppkey from supplier where s_suppkey < 2 +) +); +call p(); +select count(*) from lineitem where l_partkey in ( +select ps_partkey +from partsupp join lineitem on ps_partkey=l_partkey +where ps_suppkey in ( +select s_suppkey from supplier where s_suppkey < 2 +) +); +count(*) +0 +insert into lineitem select * from t; +select count(*) from lineitem where l_partkey in ( +select ps_partkey +from partsupp join lineitem on ps_partkey=l_partkey +where ps_suppkey in ( +select s_suppkey from supplier where s_suppkey < 2 +) +); +count(*) +2126 +create table r as +select * from lineitem where l_partkey in ( +select ps_partkey +from partsupp join lineitem on ps_partkey=l_partkey +where ps_suppkey in ( +select s_suppkey from supplier where s_suppkey < 2 +) +); +call p(); +select count(*) from lineitem where l_partkey in ( +select ps_partkey +from partsupp join lineitem on ps_partkey=l_partkey +where ps_suppkey in ( +select s_suppkey from supplier where s_suppkey < 2 +) +); +count(*) +0 +insert into lineitem select * from r; +select count(*) from lineitem where l_partkey in ( +select ps_partkey +from partsupp join lineitem on ps_partkey=l_partkey +where ps_suppkey in ( +select s_suppkey from supplier where s_suppkey < 2 +) +); +count(*) +2126 +drop tables r, t; +drop procedure p; +set @@optimizer_switch=@tmp_optimizer_switch; DROP DATABASE dbt3_s001; diff --git a/mysql-test/main/delete_single_to_multi.test b/mysql-test/main/delete_single_to_multi.test index 2c49128..3a2a683 100644 --- a/mysql-test/main/delete_single_to_multi.test +++ b/mysql-test/main/delete_single_to_multi.test @@ -798,4 +798,228 @@ eval select o_orderkey, o_totalprice from orders where $c11; drop table t; +--echo # LooseScan +--echo # ========= + +create index i_l_sup_part on lineitem(l_suppkey, l_partkey); +create index i_ps_sup_part on partsupp(ps_suppkey, ps_partkey); + +analyze table lineitem; +analyze table partsupp; + +let $c12 = l_suppkey in + (select ps_suppkey from partsupp + where ps_partkey in (1,2,3)); + +eval +explain +select count(*) from lineitem where $c12; +eval +explain format=json +select count(*) from lineitem where $c12; +eval +select count(*) from lineitem where $c12; +eval +create table t as +select * from lineitem where $c12; + +eval +explain +delete from lineitem where $c12; +eval +explain format=json +delete from lineitem where $c12; +eval +delete from lineitem where $c12; +eval +select count(*) from lineitem where $c12; + +insert into lineitem select * from t; +eval +select count(*) from lineitem where $c12; + +drop table t; + +--echo # LooseScan PS +--echo # ============ + +eval +prepare stmt from " +delete from lineitem where $c12; +"; + +eval +select count(*) from lineitem where $c12; +eval +create table t as +select * from lineitem where $c12; +execute stmt; +eval +select count(*) from lineitem where $c12; +insert into lineitem select * from t; +eval +select count(*) from lineitem where $c12; + +eval +create table r as +select * from lineitem where $c12; +execute stmt; +eval +select count(*) from lineitem where $c12; +insert into lineitem select * from r; +eval +select count(*) from lineitem where $c12; + +drop tables r, t; +deallocate prepare stmt; + +--echo # LooseScan SP +--echo # ============ + +eval +create procedure p() +delete from lineitem where $c12; + +eval +select count(*) from lineitem where $c12; +eval +create table t as +select * from lineitem where $c12; +call p(); +eval +select count(*) from lineitem where $c12; +insert into lineitem select * from t; +eval +select count(*) from lineitem where $c12; + +eval +create table r as +select * from lineitem where $c12; +call p(); +eval +select count(*) from lineitem where $c12; +insert into lineitem select * from r; +eval +select count(*) from lineitem where $c12; + +drop tables r, t; +drop procedure p; + +drop index i_l_sup_part on lineitem; +drop index i_ps_sup_part on partsupp; + +--echo # DuplicateWeedout +--echo # ================ + +set @tmp_optimizer_switch= @@optimizer_switch; +set optimizer_switch='materialization=off'; + +analyze table lineitem; +analyze table orders; + +let $c13 = l_partkey in ( + select ps_partkey + from partsupp join lineitem on ps_partkey=l_partkey + where ps_suppkey in ( + select s_suppkey from supplier where s_suppkey < 2 + ) +); + +eval +explain +select count(*) from lineitem where $c13; +eval +explain format=json +select count(*) from lineitem where $c13; +eval +select count(*) from lineitem where $c13; +eval +create table t as +select * from lineitem where $c13; + +eval +explain +delete from lineitem where $c13; +eval +explain format=json +delete from lineitem where $c13; +eval +delete from lineitem where $c13; +eval +select count(*) from lineitem where $c13; + +insert into lineitem select * from t; +eval +select count(*) from lineitem where $c13; + +drop table t; + +--echo # DuplicateWeedout PS +--echo # =================== + +eval +prepare stmt from " +delete from lineitem where $c13; +"; + +eval +select count(*) from lineitem where $c13; +eval +create table t as +select * from lineitem where $c13; +execute stmt; +eval +select count(*) from lineitem where $c13; +insert into lineitem select * from t; +eval +select count(*) from lineitem where $c13; + +eval +create table r as +select * from lineitem where $c13; +execute stmt; +eval +select count(*) from lineitem where $c13; +insert into lineitem select * from r; +eval +select count(*) from lineitem where $c13; + +drop tables r, t; +deallocate prepare stmt; + +--echo # DuplicateWeedout SP +--echo # =================== + +eval +create procedure p() +delete from lineitem where $c13; + +eval +select count(*) from lineitem where $c13; +eval +create table t as +select * from lineitem where $c13; +call p(); +eval +select count(*) from lineitem where $c13; +insert into lineitem select * from t; +eval +select count(*) from lineitem where $c13; + +eval +create table r as +select * from lineitem where $c13; +call p(); +eval +select count(*) from lineitem where $c13; +insert into lineitem select * from r; +eval +select count(*) from lineitem where $c13; + +drop tables r, t; +drop procedure p; + +set @@optimizer_switch=@tmp_optimizer_switch; + + DROP DATABASE dbt3_s001; diff --git a/mysql-test/main/delete_use_source_engines.result b/mysql-test/main/delete_use_source_engines.result new file mode 100644 index 0000000..b038b77 --- /dev/null +++ b/mysql-test/main/delete_use_source_engines.result @@ -0,0 +1,9499 @@ +set @save_default_engine=@@default_storage_engine; +set global innodb_stats_persistent=1; +set default_storage_engine=InnoDB; +create table t1 (c1 integer, c2 integer, c3 integer); +insert into t1(c1,c2,c3) +values (1,1,1),(1,2,2),(1,3,3), +(2,1,4),(2,2,5),(2,3,6), +(2,4,7),(2,5,8); +insert into t1 select c1+10,c2,c3+10 from t1; +insert into t1 select c1+20,c2+1,c3+20 from t1; +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +create view v1 as select * from t1 where c2=2; +Test without any index +# +# Delete with value from subquery on the same table +# +create table tmp as select * from t1 where c1=(select a.c3 from t1 a where a.c3 = t1.c3); +explain select * from t1 where c1=(select a.c3 from t1 a where a.c3 = t1.c3); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 32 Using where +explain delete from t1 where c1=(select a.c3 from t1 a where a.c3 = t1.c3); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 32 Using where +delete from t1 where c1=(select a.c3 from t1 a where a.c3 = t1.c3); +affected rows: 4 +select * from t1; +c1 c2 c3 +1 2 2 +1 3 3 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete with EXISTS subquery over the updated table +# in WHERE + possibly sargable condition +# +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +create table tmp as select * from t1 where c1 = 1 and exists (select 'X' from t1 a where a.c1 = t1.c2); +explain select * from t1 where c1 = 1 and exists (select 'X' from t1 a where a.c1 = t1.c2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ALL NULL NULL NULL NULL 32 +explain delete from t1 where c1 = 1 and exists (select 'X' from t1 a where a.c1 = t1.c2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ALL NULL NULL NULL NULL 32 +analyze delete from t1 where c1 = 1 and exists (select 'X' from t1 a where a.c1 = t1.c2); +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 32.00 9.38 9.38 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 0.67 100.00 100.00 +2 MATERIALIZED a ALL NULL NULL NULL NULL 32 32.00 100.00 100.00 +select * from t1; +c1 c2 c3 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete with EXISTS subquery over the updated table +# in WHERE + non-sargable condition +# +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +create table tmp as select * from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 = 3; +explain select * from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 = 3; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ALL NULL NULL NULL NULL 32 Using where +explain delete from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 = 3; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ALL NULL NULL NULL NULL 32 Using where +delete from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 = 3; +affected rows: 8 +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +11 1 11 +11 2 12 +12 1 14 +12 2 15 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 4 7 +2 5 8 +21 2 21 +21 4 23 +22 2 24 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 4 33 +32 2 34 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete with order by +# +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +create table tmp as select * from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 order by c2; +explain select * from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 order by c2; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where; Using filesort +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ALL NULL NULL NULL NULL 32 +explain delete from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 order by c2; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ALL NULL NULL NULL NULL 32 +analyze delete from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 order by c2; +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 32.00 62.50 62.50 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 1.00 100.00 100.00 +2 MATERIALIZED a ALL NULL NULL NULL NULL 32 32.00 62.50 100.00 +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +11 1 11 +11 2 12 +12 1 14 +12 2 15 +2 1 4 +2 2 5 +21 2 21 +22 2 24 +31 2 31 +32 2 34 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete with IN predicand over the updated table in WHERE +# +create table tmp as select * from t1 where c3 in (select distinct a.c1 from t1 a where t1.c2=a.c2); +explain select * from t1 where c3 in (select distinct a.c1 from t1 a where t1.c2=a.c2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 +1 PRIMARY a ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) +explain delete from t1 where c3 in (select distinct a.c1 from t1 a where t1.c2=a.c2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 +1 PRIMARY a ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1) +delete from t1 where c3 in (select distinct a.c1 from t1 a where t1.c2=a.c2); +affected rows: 8 +select * from t1; +c1 c2 c3 +1 3 3 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete with a limit - can be deleted +# +create table tmp as select * from t1 where c1 in (select a.c2 from t1 a where a.c2 = t1.c3) limit 1; +explain select * from t1 where c1 in (select a.c2 from t1 a where a.c2 = t1.c3) limit 1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +1 PRIMARY a ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) +explain delete from t1 where c1 in (select a.c2 from t1 a where a.c2 = t1.c3) limit 1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +1 PRIMARY a ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1) +analyze delete from t1 where c1 in (select a.c2 from t1 a where a.c2 = t1.c3) limit 1; +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 30.00 100.00 13.33 Using where +1 PRIMARY a ALL NULL NULL NULL NULL 32 24.25 100.00 1.03 Using where; FirstMatch(t1) +select * from t1; +c1 c2 c3 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete with a limit and an order by +# +create table tmp as select * from t1 where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +explain select * from t1 where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using temporary; Using filesort +1 PRIMARY a ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) +explain delete from t1 where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where; Using filesort +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 32 Using where +delete from t1 where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +affected rows: 1 +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete: 2 execution of PS +# +prepare create_tmp_stmt from +"create table tmp as select * from t1 + where c2=(select a.c3 from t1 a where a.c3 = ?)"; +prepare delete_t1_stmt from +"delete from t1 where c2=(select a.c3 from t1 a where a.c3 = ?)"; +set @a:=5; +execute create_tmp_stmt using @a; +execute delete_t1_stmt using @a; +execute delete_t1_stmt using @a; +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 6 38 +prepare insert_tmp_stmt from +"insert into tmp(c1,c2,c3) select * from t1 + where c2=(select a.c3 from t1 a where a.c3 = ?)"; +set @a:=2; +execute insert_tmp_stmt using @a; +execute delete_t1_stmt using @a; +select * from t1; +c1 c2 c3 +1 1 1 +1 3 3 +11 1 11 +11 3 13 +12 1 14 +12 3 16 +12 4 17 +2 1 4 +2 3 6 +2 4 7 +21 3 22 +21 4 23 +22 3 25 +22 4 26 +22 6 28 +31 3 32 +31 4 33 +32 3 35 +32 4 36 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +drop table tmp; +# +# Delete in stored procedure +# +create procedure sp() +begin +delete from t1 where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +end +// +create table tmp as select * from t1 +where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +CALL sp; +insert into tmp(c1,c2,c3) select * from t1 +where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +CALL sp; +insert into tmp(c1,c2,c3) select * from t1 +where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +CALL sp; +select * from t1; +c1 c2 c3 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop procedure sp; +drop table tmp; +# +# Delete in stored function +# +create function f1(IN a INT) returns int +begin +delete from t1 where c3 < a order by c3 limit 1; +return 1; +end;// +set @a:=7; +create table tmp as select * from t1 where c3 < @a +order by c3 limit 1; +select f1(@a); +f1(@a) +1 +insert into tmp(c1,c2,c3) select * from t1 where c3 < @a +order by c3 limit 1; +select f1(@a); +f1(@a) +1 +select * from t1; +c1 c2 c3 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop function f1; +drop table tmp; +# +# Delete in trigger +# +create table t2 (c1 integer); +insert into t2(c1) values (1), (2), (3), (4), (5), (6), (7), (8); +CREATE TABLE cnt(del integer); +INSERT INTO cnt VALUES(0); +CREATE TRIGGER tr1 AFTER DELETE ON t1 FOR EACH ROW +UPDATE cnt SET del=del+1; +CREATE TRIGGER tr2 AFTER DELETE ON t1 FOR EACH ROW +DELETE FROM t2 WHERE c1> (SELECT count(*)-1 FROM t2); +CREATE TABLE tmp as SELECT * FROM t1 WHERE c2>=3; +DELETE FROM t1 WHERE c2>=3; +affected rows: 20 +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +11 1 11 +11 2 12 +12 1 14 +12 2 15 +2 1 4 +2 2 5 +21 2 21 +22 2 24 +31 2 31 +32 2 34 +SELECT * FROM t2; +c1 +SELECT * FROM cnt; +del +20 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +DROP TRIGGER tr1; +DROP TRIGGER tr2; +drop table t2, cnt, tmp; +# +# Delete with a reference to view in subquery +# +create table tmp as select * from t1 where t1.c2 in ( select max(a.c2) from v1 a +where a.c1 = t1.c1); +explain select * from t1 where t1.c2 in ( select max(a.c2) from v1 a +where a.c1 = t1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 32 Using where +explain delete from t1 where t1.c2 in ( select max(a.c2) from v1 a +where a.c1 = t1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 32 Using where +analyze delete from t1 where t1.c2 in ( select max(a.c2) from v1 a +where a.c1 = t1.c1); +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 32.00 100.00 25.00 Using where +2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 32 32.00 25.00 3.12 Using where +select * from t1; +c1 c2 c3 +1 1 1 +1 3 3 +11 1 11 +11 3 13 +12 1 14 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 3 6 +2 4 7 +2 5 8 +21 3 22 +21 4 23 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 3 32 +31 4 33 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete from view +# +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +create table tmp as select * from v1 where v1.c1 in +(select max(a.c1) from t1 a where a.c2 = v1.c2) and c3 = 5; +explain select * from v1 where v1.c1 in +(select max(a.c1) from t1 a where a.c2 = v1.c2) and c3 = 5; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 32 Using where +explain delete from v1 where v1.c1 in +(select max(a.c1) from t1 a where a.c2 = v1.c2) and c3 = 5; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 32 Using where +delete from v1 where v1.c1 in +(select max(a.c1) from t1 a where a.c2 = v1.c2) and c3 = 5; +affected rows: 0 +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete from view using reference +# to the same view in subquery +# +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +create table tmp as select * from v1 where v1.c2 in (select max(a.c2) from t1 a where a.c3 = v1.c3) +and c1 = 2 +and exists (select 'X' from v1 a where a.c1 = v1.c1); +explain select * from v1 where v1.c2 in (select max(a.c2) from t1 a where a.c3 = v1.c3) +and c1 = 2 +and exists (select 'X' from v1 a where a.c1 = v1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL # Using where +1 PRIMARY <subquery3> eq_ref distinct_key distinct_key 4 func # +3 MATERIALIZED t1 ALL NULL NULL NULL NULL # Using where +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL # Using where +explain delete from v1 where v1.c2 in (select max(a.c2) from t1 a where a.c3 = v1.c3) +and c1 = 2 +and exists (select 'X' from v1 a where a.c1 = v1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL # Using where +3 MATERIALIZED t1 ALL NULL NULL NULL NULL # Using where +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL # Using where +analyze delete from v1 where v1.c2 in (select max(a.c2) from t1 a where a.c3 = v1.c3) +and c1 = 2 +and exists (select 'X' from v1 a where a.c1 = v1.c1); +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL # 32.00 3.91 3.12 Using where +3 MATERIALIZED t1 ALL NULL NULL NULL NULL # 32.00 25.00 25.00 Using where +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL # 32.00 100.00 3.12 Using where +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +Test with an index +create index t1_c2 on t1 (c2,c1); +# +# Delete with value from subquery on the same table +# +create table tmp as select * from t1 where c1=(select a.c3 from t1 a where a.c3 = t1.c3); +explain select * from t1 where c1=(select a.c3 from t1 a where a.c3 = t1.c3); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 32 Using where +explain delete from t1 where c1=(select a.c3 from t1 a where a.c3 = t1.c3); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 32 Using where +delete from t1 where c1=(select a.c3 from t1 a where a.c3 = t1.c3); +affected rows: 4 +select * from t1; +c1 c2 c3 +1 2 2 +1 3 3 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete with EXISTS subquery over the updated table +# in WHERE + possibly sargable condition +# +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +create table tmp as select * from t1 where c1 = 1 and exists (select 'X' from t1 a where a.c1 = t1.c2); +explain select * from t1 where c1 = 1 and exists (select 'X' from t1 a where a.c1 = t1.c2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL t1_c2 NULL NULL NULL 32 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a index NULL t1_c2 10 NULL 32 Using index +explain delete from t1 where c1 = 1 and exists (select 'X' from t1 a where a.c1 = t1.c2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL t1_c2 NULL NULL NULL 32 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a index NULL t1_c2 10 NULL 32 Using index +analyze delete from t1 where c1 = 1 and exists (select 'X' from t1 a where a.c1 = t1.c2); +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 PRIMARY t1 ALL t1_c2 NULL NULL NULL 32 32.00 9.38 9.38 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 0.67 100.00 100.00 +2 MATERIALIZED a index NULL t1_c2 10 NULL 32 32.00 100.00 100.00 Using index +select * from t1; +c1 c2 c3 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete with EXISTS subquery over the updated table +# in WHERE + non-sargable condition +# +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +create table tmp as select * from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 = 3; +explain select * from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 = 3; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL t1_c2 NULL NULL NULL 32 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ref t1_c2 t1_c2 5 const 8 Using index +explain delete from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 = 3; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ref t1_c2 t1_c2 5 const 8 +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ref t1_c2 t1_c2 5 const 8 Using index +delete from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 = 3; +affected rows: 8 +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +11 1 11 +11 2 12 +12 1 14 +12 2 15 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 4 7 +2 5 8 +21 2 21 +21 4 23 +22 2 24 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 4 33 +32 2 34 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete with order by +# +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +create table tmp as select * from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 order by c2; +explain select * from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 order by c2; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL t1_c2 NULL NULL NULL 32 Using where; Using filesort +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a range t1_c2 t1_c2 5 NULL 28 Using where; Using index +explain delete from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 order by c2; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 range t1_c2 t1_c2 5 NULL 28 Using index condition +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a range t1_c2 t1_c2 5 NULL 28 Using where; Using index +analyze delete from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 order by c2; +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 PRIMARY t1 range t1_c2 t1_c2 5 NULL 28 20.00 100.00 100.00 Using index condition +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 1.00 100.00 100.00 +2 MATERIALIZED a range t1_c2 t1_c2 5 NULL 28 20.00 100.00 100.00 Using where; Using index +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +11 1 11 +11 2 12 +12 1 14 +12 2 15 +2 1 4 +2 2 5 +21 2 21 +22 2 24 +31 2 31 +32 2 34 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete with IN predicand over the updated table in WHERE +# +create table tmp as select * from t1 where c3 in (select distinct a.c1 from t1 a where t1.c2=a.c2); +explain select * from t1 where c3 in (select distinct a.c1 from t1 a where t1.c2=a.c2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL t1_c2 NULL NULL NULL 32 Using where +1 PRIMARY a ref t1_c2 t1_c2 10 test.t1.c2,test.t1.c3 1 Using index; FirstMatch(t1) +explain delete from t1 where c3 in (select distinct a.c1 from t1 a where t1.c2=a.c2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL t1_c2 NULL NULL NULL 32 Using where +1 PRIMARY a ref t1_c2 t1_c2 10 test.t1.c2,test.t1.c3 1 Using index; FirstMatch(t1) +delete from t1 where c3 in (select distinct a.c1 from t1 a where t1.c2=a.c2); +affected rows: 8 +select * from t1; +c1 c2 c3 +1 3 3 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete with a limit - can be deleted +# +create table tmp as select * from t1 where c1 in (select a.c2 from t1 a where a.c2 = t1.c3) limit 1; +explain select * from t1 where c1 in (select a.c2 from t1 a where a.c2 = t1.c3) limit 1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +1 PRIMARY a ref t1_c2 t1_c2 5 test.t1.c1 5 Using index; FirstMatch(t1) +explain delete from t1 where c1 in (select a.c2 from t1 a where a.c2 = t1.c3) limit 1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +1 PRIMARY a ref t1_c2 t1_c2 5 test.t1.c1 5 Using index; FirstMatch(t1) +analyze delete from t1 where c1 in (select a.c2 from t1 a where a.c2 = t1.c3) limit 1; +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 30.00 100.00 13.33 Using where +1 PRIMARY a ref t1_c2 t1_c2 5 test.t1.c1 5 0.25 100.00 100.00 Using index; FirstMatch(t1) +select * from t1; +c1 c2 c3 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete with a limit and an order by +# +create table tmp as select * from t1 where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +explain select * from t1 where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where; Using filesort +1 PRIMARY a ref t1_c2 t1_c2 5 test.t1.c1 5 Using where; FirstMatch(t1) +explain delete from t1 where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where; Using filesort +2 DEPENDENT SUBQUERY a index_subquery t1_c2 t1_c2 5 func 5 Using where +delete from t1 where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +affected rows: 1 +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete: 2 execution of PS +# +prepare create_tmp_stmt from +"create table tmp as select * from t1 + where c2=(select a.c3 from t1 a where a.c3 = ?)"; +prepare delete_t1_stmt from +"delete from t1 where c2=(select a.c3 from t1 a where a.c3 = ?)"; +set @a:=5; +execute create_tmp_stmt using @a; +execute delete_t1_stmt using @a; +execute delete_t1_stmt using @a; +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 6 38 +prepare insert_tmp_stmt from +"insert into tmp(c1,c2,c3) select * from t1 + where c2=(select a.c3 from t1 a where a.c3 = ?)"; +set @a:=2; +execute insert_tmp_stmt using @a; +execute delete_t1_stmt using @a; +select * from t1; +c1 c2 c3 +1 1 1 +1 3 3 +11 1 11 +11 3 13 +12 1 14 +12 3 16 +12 4 17 +2 1 4 +2 3 6 +2 4 7 +21 3 22 +21 4 23 +22 3 25 +22 4 26 +22 6 28 +31 3 32 +31 4 33 +32 3 35 +32 4 36 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +drop table tmp; +# +# Delete in stored procedure +# +create procedure sp() +begin +delete from t1 where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +end +// +create table tmp as select * from t1 +where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +CALL sp; +insert into tmp(c1,c2,c3) select * from t1 +where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +CALL sp; +insert into tmp(c1,c2,c3) select * from t1 +where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +CALL sp; +select * from t1; +c1 c2 c3 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop procedure sp; +drop table tmp; +# +# Delete in stored function +# +create function f1(IN a INT) returns int +begin +delete from t1 where c3 < a order by c3 limit 1; +return 1; +end;// +set @a:=7; +create table tmp as select * from t1 where c3 < @a +order by c3 limit 1; +select f1(@a); +f1(@a) +1 +insert into tmp(c1,c2,c3) select * from t1 where c3 < @a +order by c3 limit 1; +select f1(@a); +f1(@a) +1 +select * from t1; +c1 c2 c3 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop function f1; +drop table tmp; +# +# Delete in trigger +# +create table t2 (c1 integer); +insert into t2(c1) values (1), (2), (3), (4), (5), (6), (7), (8); +CREATE TABLE cnt(del integer); +INSERT INTO cnt VALUES(0); +CREATE TRIGGER tr1 AFTER DELETE ON t1 FOR EACH ROW +UPDATE cnt SET del=del+1; +CREATE TRIGGER tr2 AFTER DELETE ON t1 FOR EACH ROW +DELETE FROM t2 WHERE c1> (SELECT count(*)-1 FROM t2); +CREATE TABLE tmp as SELECT * FROM t1 WHERE c2>=3; +DELETE FROM t1 WHERE c2>=3; +affected rows: 20 +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +11 1 11 +11 2 12 +12 1 14 +12 2 15 +2 1 4 +2 2 5 +21 2 21 +22 2 24 +31 2 31 +32 2 34 +SELECT * FROM t2; +c1 +SELECT * FROM cnt; +del +20 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +DROP TRIGGER tr1; +DROP TRIGGER tr2; +drop table t2, cnt, tmp; +# +# Delete with a reference to view in subquery +# +create table tmp as select * from t1 where t1.c2 in ( select max(a.c2) from v1 a +where a.c1 = t1.c1); +explain select * from t1 where t1.c2 in ( select max(a.c2) from v1 a +where a.c1 = t1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +2 DEPENDENT SUBQUERY t1 ref t1_c2 t1_c2 10 const,test.t1.c1 1 Using index +explain delete from t1 where t1.c2 in ( select max(a.c2) from v1 a +where a.c1 = t1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +2 DEPENDENT SUBQUERY t1 ref t1_c2 t1_c2 10 const,test.t1.c1 1 Using index +analyze delete from t1 where t1.c2 in ( select max(a.c2) from v1 a +where a.c1 = t1.c1); +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 32.00 100.00 25.00 Using where +2 DEPENDENT SUBQUERY t1 ref t1_c2 t1_c2 10 const,test.t1.c1 1 1.00 100.00 100.00 Using index +select * from t1; +c1 c2 c3 +1 1 1 +1 3 3 +11 1 11 +11 3 13 +12 1 14 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 3 6 +2 4 7 +2 5 8 +21 3 22 +21 4 23 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 3 32 +31 4 33 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete from view +# +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +create table tmp as select * from v1 where v1.c1 in +(select max(a.c1) from t1 a where a.c2 = v1.c2) and c3 = 5; +explain select * from v1 where v1.c1 in +(select max(a.c1) from t1 a where a.c2 = v1.c2) and c3 = 5; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL t1_c2 NULL NULL NULL 32 Using where +2 DEPENDENT SUBQUERY a ref t1_c2 t1_c2 5 test.t1.c2 5 Using index +explain delete from v1 where v1.c1 in +(select max(a.c1) from t1 a where a.c2 = v1.c2) and c3 = 5; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL t1_c2 NULL NULL NULL 32 Using where +2 DEPENDENT SUBQUERY a ref t1_c2 t1_c2 5 test.t1.c2 5 Using index +delete from v1 where v1.c1 in +(select max(a.c1) from t1 a where a.c2 = v1.c2) and c3 = 5; +affected rows: 0 +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete from view using reference +# to the same view in subquery +# +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +create table tmp as select * from v1 where v1.c2 in (select max(a.c2) from t1 a where a.c3 = v1.c3) +and c1 = 2 +and exists (select 'X' from v1 a where a.c1 = v1.c1); +explain select * from v1 where v1.c2 in (select max(a.c2) from t1 a where a.c3 = v1.c3) +and c1 = 2 +and exists (select 'X' from v1 a where a.c1 = v1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ref t1_c2 t1_c2 10 const,const # Using where +1 PRIMARY <subquery3> eq_ref distinct_key distinct_key 4 func # +3 MATERIALIZED t1 ref t1_c2 t1_c2 10 const,const # Using index +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL # Using where +explain delete from v1 where v1.c2 in (select max(a.c2) from t1 a where a.c3 = v1.c3) +and c1 = 2 +and exists (select 'X' from v1 a where a.c1 = v1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ref t1_c2 t1_c2 10 const,const # Using where +3 DEPENDENT SUBQUERY t1 ref t1_c2 t1_c2 10 const,func # Using where; Using index +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL # Using where +analyze delete from v1 where v1.c2 in (select max(a.c2) from t1 a where a.c3 = v1.c3) +and c1 = 2 +and exists (select 'X' from v1 a where a.c1 = v1.c1); +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 PRIMARY t1 ref t1_c2 t1_c2 10 const,const # 1.00 100.00 100.00 Using where +3 DEPENDENT SUBQUERY t1 ref t1_c2 t1_c2 10 const,func # 1.00 100.00 100.00 Using where; Using index +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL # 32.00 100.00 3.12 Using where +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +Test with a primary key +drop index t1_c2 on t1; +alter table t1 add primary key (c3); +# +# Delete with value from subquery on the same table +# +create table tmp as select * from t1 where c1=(select a.c3 from t1 a where a.c3 = t1.c3); +explain select * from t1 where c1=(select a.c3 from t1 a where a.c3 = t1.c3); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +2 DEPENDENT SUBQUERY a eq_ref PRIMARY PRIMARY 4 test.t1.c3 1 Using index +explain delete from t1 where c1=(select a.c3 from t1 a where a.c3 = t1.c3); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +2 DEPENDENT SUBQUERY a eq_ref PRIMARY PRIMARY 4 test.t1.c3 1 Using index +delete from t1 where c1=(select a.c3 from t1 a where a.c3 = t1.c3); +affected rows: 4 +select * from t1; +c1 c2 c3 +1 2 2 +1 3 3 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete with EXISTS subquery over the updated table +# in WHERE + possibly sargable condition +# +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +create table tmp as select * from t1 where c1 = 1 and exists (select 'X' from t1 a where a.c1 = t1.c2); +explain select * from t1 where c1 = 1 and exists (select 'X' from t1 a where a.c1 = t1.c2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ALL NULL NULL NULL NULL 32 +explain delete from t1 where c1 = 1 and exists (select 'X' from t1 a where a.c1 = t1.c2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ALL NULL NULL NULL NULL 32 +analyze delete from t1 where c1 = 1 and exists (select 'X' from t1 a where a.c1 = t1.c2); +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 32.00 9.38 9.38 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 0.67 100.00 100.00 +2 MATERIALIZED a ALL NULL NULL NULL NULL 32 32.00 100.00 100.00 +select * from t1; +c1 c2 c3 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete with EXISTS subquery over the updated table +# in WHERE + non-sargable condition +# +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +create table tmp as select * from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 = 3; +explain select * from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 = 3; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ALL NULL NULL NULL NULL 32 Using where +explain delete from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 = 3; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ALL NULL NULL NULL NULL 32 Using where +delete from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 = 3; +affected rows: 8 +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +11 1 11 +11 2 12 +12 1 14 +12 2 15 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 4 7 +2 5 8 +21 2 21 +21 4 23 +22 2 24 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 4 33 +32 2 34 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete with order by +# +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +create table tmp as select * from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 order by c2; +explain select * from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 order by c2; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where; Using filesort +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ALL NULL NULL NULL NULL 32 +explain delete from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 order by c2; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ALL NULL NULL NULL NULL 32 +analyze delete from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 order by c2; +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 32.00 62.50 62.50 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 1.00 100.00 100.00 +2 MATERIALIZED a ALL NULL NULL NULL NULL 32 32.00 62.50 100.00 +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +11 1 11 +11 2 12 +12 1 14 +12 2 15 +2 1 4 +2 2 5 +21 2 21 +22 2 24 +31 2 31 +32 2 34 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete with IN predicand over the updated table in WHERE +# +create table tmp as select * from t1 where c3 in (select distinct a.c1 from t1 a where t1.c2=a.c2); +explain select * from t1 where c3 in (select distinct a.c1 from t1 a where t1.c2=a.c2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY a ALL NULL NULL NULL NULL 32 Using where; Start temporary +1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.a.c1 1 Using where; End temporary +explain delete from t1 where c3 in (select distinct a.c1 from t1 a where t1.c2=a.c2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY a ALL NULL NULL NULL NULL 32 Using where; Start temporary +1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.a.c1 1 Using where; End temporary +delete from t1 where c3 in (select distinct a.c1 from t1 a where t1.c2=a.c2); +affected rows: 8 +select * from t1; +c1 c2 c3 +1 3 3 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete with a limit - can be deleted +# +create table tmp as select * from t1 where c1 in (select a.c2 from t1 a where a.c2 = t1.c3) limit 1; +explain select * from t1 where c1 in (select a.c2 from t1 a where a.c2 = t1.c3) limit 1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY a ALL NULL NULL NULL NULL 32 Using where; Start temporary +1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.a.c2 1 Using where; End temporary +explain delete from t1 where c1 in (select a.c2 from t1 a where a.c2 = t1.c3) limit 1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY a ALL NULL NULL NULL NULL 32 Using where; Start temporary +1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.a.c2 1 Using where; End temporary +analyze delete from t1 where c1 in (select a.c2 from t1 a where a.c2 = t1.c3) limit 1; +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 PRIMARY a ALL NULL NULL NULL NULL 32 1.00 100.00 100.00 Using where; Start temporary +1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.a.c2 1 1.00 100.00 100.00 Using where; End temporary +select * from t1; +c1 c2 c3 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete with a limit and an order by +# +create table tmp as select * from t1 where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +explain select * from t1 where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 index PRIMARY PRIMARY 4 NULL 1 +1 PRIMARY a eq_ref PRIMARY PRIMARY 4 test.t1.c3 1 Using where +explain delete from t1 where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 index NULL PRIMARY 4 NULL 1 Using where +2 DEPENDENT SUBQUERY a eq_ref PRIMARY PRIMARY 4 test.t1.c3 1 Using where +delete from t1 where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +affected rows: 1 +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete: 2 execution of PS +# +prepare create_tmp_stmt from +"create table tmp as select * from t1 + where c2=(select a.c3 from t1 a where a.c3 = ?)"; +prepare delete_t1_stmt from +"delete from t1 where c2=(select a.c3 from t1 a where a.c3 = ?)"; +set @a:=5; +execute create_tmp_stmt using @a; +execute delete_t1_stmt using @a; +execute delete_t1_stmt using @a; +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 6 38 +prepare insert_tmp_stmt from +"insert into tmp(c1,c2,c3) select * from t1 + where c2=(select a.c3 from t1 a where a.c3 = ?)"; +set @a:=2; +execute insert_tmp_stmt using @a; +execute delete_t1_stmt using @a; +select * from t1; +c1 c2 c3 +1 1 1 +1 3 3 +11 1 11 +11 3 13 +12 1 14 +12 3 16 +12 4 17 +2 1 4 +2 3 6 +2 4 7 +21 3 22 +21 4 23 +22 3 25 +22 4 26 +22 6 28 +31 3 32 +31 4 33 +32 3 35 +32 4 36 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +drop table tmp; +# +# Delete in stored procedure +# +create procedure sp() +begin +delete from t1 where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +end +// +create table tmp as select * from t1 +where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +CALL sp; +insert into tmp(c1,c2,c3) select * from t1 +where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +CALL sp; +insert into tmp(c1,c2,c3) select * from t1 +where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +CALL sp; +select * from t1; +c1 c2 c3 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop procedure sp; +drop table tmp; +# +# Delete in stored function +# +create function f1(IN a INT) returns int +begin +delete from t1 where c3 < a order by c3 limit 1; +return 1; +end;// +set @a:=7; +create table tmp as select * from t1 where c3 < @a +order by c3 limit 1; +select f1(@a); +f1(@a) +1 +insert into tmp(c1,c2,c3) select * from t1 where c3 < @a +order by c3 limit 1; +select f1(@a); +f1(@a) +1 +select * from t1; +c1 c2 c3 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop function f1; +drop table tmp; +# +# Delete in trigger +# +create table t2 (c1 integer); +insert into t2(c1) values (1), (2), (3), (4), (5), (6), (7), (8); +CREATE TABLE cnt(del integer); +INSERT INTO cnt VALUES(0); +CREATE TRIGGER tr1 AFTER DELETE ON t1 FOR EACH ROW +UPDATE cnt SET del=del+1; +CREATE TRIGGER tr2 AFTER DELETE ON t1 FOR EACH ROW +DELETE FROM t2 WHERE c1> (SELECT count(*)-1 FROM t2); +CREATE TABLE tmp as SELECT * FROM t1 WHERE c2>=3; +DELETE FROM t1 WHERE c2>=3; +affected rows: 20 +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +11 1 11 +11 2 12 +12 1 14 +12 2 15 +2 1 4 +2 2 5 +21 2 21 +22 2 24 +31 2 31 +32 2 34 +SELECT * FROM t2; +c1 +SELECT * FROM cnt; +del +20 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +DROP TRIGGER tr1; +DROP TRIGGER tr2; +drop table t2, cnt, tmp; +# +# Delete with a reference to view in subquery +# +create table tmp as select * from t1 where t1.c2 in ( select max(a.c2) from v1 a +where a.c1 = t1.c1); +explain select * from t1 where t1.c2 in ( select max(a.c2) from v1 a +where a.c1 = t1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 32 Using where +explain delete from t1 where t1.c2 in ( select max(a.c2) from v1 a +where a.c1 = t1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 32 Using where +analyze delete from t1 where t1.c2 in ( select max(a.c2) from v1 a +where a.c1 = t1.c1); +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 32.00 100.00 25.00 Using where +2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 32 32.00 25.00 3.12 Using where +select * from t1; +c1 c2 c3 +1 1 1 +1 3 3 +11 1 11 +11 3 13 +12 1 14 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 3 6 +2 4 7 +2 5 8 +21 3 22 +21 4 23 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 3 32 +31 4 33 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete from view +# +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +create table tmp as select * from v1 where v1.c1 in +(select max(a.c1) from t1 a where a.c2 = v1.c2) and c3 = 5; +explain select * from v1 where v1.c1 in +(select max(a.c1) from t1 a where a.c2 = v1.c2) and c3 = 5; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 const PRIMARY PRIMARY 4 const 1 +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 32 Using where +explain delete from v1 where v1.c1 in +(select max(a.c1) from t1 a where a.c2 = v1.c2) and c3 = 5; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 const PRIMARY PRIMARY 4 const 1 +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 32 Using where +delete from v1 where v1.c1 in +(select max(a.c1) from t1 a where a.c2 = v1.c2) and c3 = 5; +affected rows: 0 +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete from view using reference +# to the same view in subquery +# +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +create table tmp as select * from v1 where v1.c2 in (select max(a.c2) from t1 a where a.c3 = v1.c3) +and c1 = 2 +and exists (select 'X' from v1 a where a.c1 = v1.c1); +explain select * from v1 where v1.c2 in (select max(a.c2) from t1 a where a.c3 = v1.c3) +and c1 = 2 +and exists (select 'X' from v1 a where a.c1 = v1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL # Using where +1 PRIMARY <subquery3> eq_ref distinct_key distinct_key 4 func # +3 MATERIALIZED t1 ALL NULL NULL NULL NULL # Using where +2 DEPENDENT SUBQUERY a eq_ref PRIMARY PRIMARY 4 test.t1.c3 # +explain delete from v1 where v1.c2 in (select max(a.c2) from t1 a where a.c3 = v1.c3) +and c1 = 2 +and exists (select 'X' from v1 a where a.c1 = v1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL # Using where +3 MATERIALIZED t1 ALL NULL NULL NULL NULL # Using where +2 DEPENDENT SUBQUERY a eq_ref PRIMARY PRIMARY 4 test.t1.c3 # +analyze delete from v1 where v1.c2 in (select max(a.c2) from t1 a where a.c3 = v1.c3) +and c1 = 2 +and exists (select 'X' from v1 a where a.c1 = v1.c1); +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL # 32.00 3.91 3.12 Using where +3 MATERIALIZED t1 ALL NULL NULL NULL NULL # 32.00 25.00 25.00 Using where +2 DEPENDENT SUBQUERY a eq_ref PRIMARY PRIMARY 4 test.t1.c3 # 1.00 100.00 100.00 +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +drop view v1; +drop table t1; +# +# Test on dynamic columns (blob) +# +create table assets ( +item_name varchar(32) primary key, -- A common attribute for all items +dynamic_cols blob -- Dynamic columns will be stored here +); +INSERT INTO assets +VALUES ('MariaDB T-shirt', +COLUMN_CREATE('color', 'blue', 'size', 'XL')); +INSERT INTO assets +VALUES ('Thinkpad Laptop', +COLUMN_CREATE('color', 'black', 'price', 500)); +INSERT INTO assets +VALUES ('Fridge', +COLUMN_CREATE('color', 'white', 'warranty', '5 years')); +INSERT INTO assets +VALUES ('Microwave', +COLUMN_CREATE('warranty', '3 years')); +SELECT item_name, COLUMN_GET(dynamic_cols, 'color' as char) AS color +FROM assets ORDER BY item_name; +item_name color +Fridge white +MariaDB T-shirt blue +Microwave NULL +Thinkpad Laptop black +UPDATE assets SET dynamic_cols=COLUMN_DELETE(dynamic_cols, 'color') +WHERE item_name='Fridge'; +SELECT item_name, COLUMN_GET(dynamic_cols, 'color' as char) AS color +FROM assets ORDER BY item_name; +item_name color +Fridge NULL +MariaDB T-shirt blue +Microwave NULL +Thinkpad Laptop black +DELETE FROM assets +WHERE item_name in +(select b.item_name from assets b +where COLUMN_GET(b.dynamic_cols, 'color' as char) ='black'); +SELECT item_name, COLUMN_GET(dynamic_cols, 'color' as char) AS color +FROM assets ORDER BY item_name; +item_name color +Fridge NULL +MariaDB T-shirt blue +Microwave NULL +DELETE FROM assets WHERE item_name='Microwave'; +SELECT item_name, COLUMN_GET(dynamic_cols, 'color' as char) AS color +FROM assets ORDER BY item_name; +item_name color +Fridge NULL +MariaDB T-shirt blue +drop table assets ; +# +# Test on fulltext columns +# +CREATE TABLE ft2(copy TEXT,FULLTEXT(copy)); +INSERT INTO ft2(copy) VALUES +('MySQL vs MariaDB database'), +('Oracle vs MariaDB database'), +('PostgreSQL vs MariaDB database'), +('MariaDB overview'), +('Foreign keys'), +('Primary keys'), +('Indexes'), +('Transactions'), +('Triggers'); +SELECT * FROM ft2 WHERE MATCH(copy) AGAINST('database'); +copy +MySQL vs MariaDB database +Oracle vs MariaDB database +PostgreSQL vs MariaDB database +DELETE FROM ft2 WHERE MATCH(copy) AGAINST('database'); +SELECT * FROM ft2 WHERE MATCH(copy) AGAINST('database'); +copy +drop table ft2; +set default_storage_engine=Aria; +create table t1 (c1 integer, c2 integer, c3 integer); +insert into t1(c1,c2,c3) +values (1,1,1),(1,2,2),(1,3,3), +(2,1,4),(2,2,5),(2,3,6), +(2,4,7),(2,5,8); +insert into t1 select c1+10,c2,c3+10 from t1; +insert into t1 select c1+20,c2+1,c3+20 from t1; +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +create view v1 as select * from t1 where c2=2; +Test without any index +# +# Delete with value from subquery on the same table +# +create table tmp as select * from t1 where c1=(select a.c3 from t1 a where a.c3 = t1.c3); +explain select * from t1 where c1=(select a.c3 from t1 a where a.c3 = t1.c3); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 32 Using where +explain delete from t1 where c1=(select a.c3 from t1 a where a.c3 = t1.c3); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 32 Using where +delete from t1 where c1=(select a.c3 from t1 a where a.c3 = t1.c3); +affected rows: 4 +select * from t1; +c1 c2 c3 +1 2 2 +1 3 3 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete with EXISTS subquery over the updated table +# in WHERE + possibly sargable condition +# +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +create table tmp as select * from t1 where c1 = 1 and exists (select 'X' from t1 a where a.c1 = t1.c2); +explain select * from t1 where c1 = 1 and exists (select 'X' from t1 a where a.c1 = t1.c2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ALL NULL NULL NULL NULL 32 +explain delete from t1 where c1 = 1 and exists (select 'X' from t1 a where a.c1 = t1.c2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ALL NULL NULL NULL NULL 32 +analyze delete from t1 where c1 = 1 and exists (select 'X' from t1 a where a.c1 = t1.c2); +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 32.00 9.38 9.38 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 0.67 100.00 100.00 +2 MATERIALIZED a ALL NULL NULL NULL NULL 32 32.00 100.00 100.00 +select * from t1; +c1 c2 c3 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete with EXISTS subquery over the updated table +# in WHERE + non-sargable condition +# +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +create table tmp as select * from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 = 3; +explain select * from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 = 3; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ALL NULL NULL NULL NULL 32 Using where +explain delete from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 = 3; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ALL NULL NULL NULL NULL 32 Using where +delete from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 = 3; +affected rows: 8 +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +11 1 11 +11 2 12 +12 1 14 +12 2 15 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 4 7 +2 5 8 +21 2 21 +21 4 23 +22 2 24 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 4 33 +32 2 34 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete with order by +# +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +create table tmp as select * from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 order by c2; +explain select * from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 order by c2; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where; Using filesort +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ALL NULL NULL NULL NULL 32 +explain delete from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 order by c2; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ALL NULL NULL NULL NULL 32 +analyze delete from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 order by c2; +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 32.00 62.50 62.50 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 1.00 100.00 100.00 +2 MATERIALIZED a ALL NULL NULL NULL NULL 32 32.00 62.50 100.00 +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +11 1 11 +11 2 12 +12 1 14 +12 2 15 +2 1 4 +2 2 5 +21 2 21 +22 2 24 +31 2 31 +32 2 34 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete with IN predicand over the updated table in WHERE +# +create table tmp as select * from t1 where c3 in (select distinct a.c1 from t1 a where t1.c2=a.c2); +explain select * from t1 where c3 in (select distinct a.c1 from t1 a where t1.c2=a.c2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 +1 PRIMARY a ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) +explain delete from t1 where c3 in (select distinct a.c1 from t1 a where t1.c2=a.c2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 +1 PRIMARY a ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1) +delete from t1 where c3 in (select distinct a.c1 from t1 a where t1.c2=a.c2); +affected rows: 8 +select * from t1; +c1 c2 c3 +1 3 3 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete with a limit - can be deleted +# +create table tmp as select * from t1 where c1 in (select a.c2 from t1 a where a.c2 = t1.c3) limit 1; +explain select * from t1 where c1 in (select a.c2 from t1 a where a.c2 = t1.c3) limit 1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +1 PRIMARY a ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) +explain delete from t1 where c1 in (select a.c2 from t1 a where a.c2 = t1.c3) limit 1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +1 PRIMARY a ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1) +analyze delete from t1 where c1 in (select a.c2 from t1 a where a.c2 = t1.c3) limit 1; +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 21.00 100.00 14.29 Using where +1 PRIMARY a ALL NULL NULL NULL NULL 32 22.67 100.00 1.47 Using where; FirstMatch(t1) +select * from t1; +c1 c2 c3 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete with a limit and an order by +# +create table tmp as select * from t1 where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +explain select * from t1 where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using temporary; Using filesort +1 PRIMARY a ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) +explain delete from t1 where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where; Using filesort +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 32 Using where +delete from t1 where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +affected rows: 1 +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete: 2 execution of PS +# +prepare create_tmp_stmt from +"create table tmp as select * from t1 + where c2=(select a.c3 from t1 a where a.c3 = ?)"; +prepare delete_t1_stmt from +"delete from t1 where c2=(select a.c3 from t1 a where a.c3 = ?)"; +set @a:=5; +execute create_tmp_stmt using @a; +execute delete_t1_stmt using @a; +execute delete_t1_stmt using @a; +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 6 38 +prepare insert_tmp_stmt from +"insert into tmp(c1,c2,c3) select * from t1 + where c2=(select a.c3 from t1 a where a.c3 = ?)"; +set @a:=2; +execute insert_tmp_stmt using @a; +execute delete_t1_stmt using @a; +select * from t1; +c1 c2 c3 +1 1 1 +1 3 3 +11 1 11 +11 3 13 +12 1 14 +12 3 16 +12 4 17 +2 1 4 +2 3 6 +2 4 7 +21 3 22 +21 4 23 +22 3 25 +22 4 26 +22 6 28 +31 3 32 +31 4 33 +32 3 35 +32 4 36 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +drop table tmp; +# +# Delete in stored procedure +# +create procedure sp() +begin +delete from t1 where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +end +// +create table tmp as select * from t1 +where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +CALL sp; +insert into tmp(c1,c2,c3) select * from t1 +where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +CALL sp; +insert into tmp(c1,c2,c3) select * from t1 +where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +CALL sp; +select * from t1; +c1 c2 c3 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop procedure sp; +drop table tmp; +# +# Delete in stored function +# +create function f1(IN a INT) returns int +begin +delete from t1 where c3 < a order by c3 limit 1; +return 1; +end;// +set @a:=7; +create table tmp as select * from t1 where c3 < @a +order by c3 limit 1; +select f1(@a); +f1(@a) +1 +insert into tmp(c1,c2,c3) select * from t1 where c3 < @a +order by c3 limit 1; +select f1(@a); +f1(@a) +1 +select * from t1; +c1 c2 c3 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop function f1; +drop table tmp; +# +# Delete in trigger +# +create table t2 (c1 integer); +insert into t2(c1) values (1), (2), (3), (4), (5), (6), (7), (8); +CREATE TABLE cnt(del integer); +INSERT INTO cnt VALUES(0); +CREATE TRIGGER tr1 AFTER DELETE ON t1 FOR EACH ROW +UPDATE cnt SET del=del+1; +CREATE TRIGGER tr2 AFTER DELETE ON t1 FOR EACH ROW +DELETE FROM t2 WHERE c1> (SELECT count(*)-1 FROM t2); +CREATE TABLE tmp as SELECT * FROM t1 WHERE c2>=3; +DELETE FROM t1 WHERE c2>=3; +affected rows: 20 +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +11 1 11 +11 2 12 +12 1 14 +12 2 15 +2 1 4 +2 2 5 +21 2 21 +22 2 24 +31 2 31 +32 2 34 +SELECT * FROM t2; +c1 +SELECT * FROM cnt; +del +20 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +DROP TRIGGER tr1; +DROP TRIGGER tr2; +drop table t2, cnt, tmp; +# +# Delete with a reference to view in subquery +# +create table tmp as select * from t1 where t1.c2 in ( select max(a.c2) from v1 a +where a.c1 = t1.c1); +explain select * from t1 where t1.c2 in ( select max(a.c2) from v1 a +where a.c1 = t1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 32 Using where +explain delete from t1 where t1.c2 in ( select max(a.c2) from v1 a +where a.c1 = t1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 32 Using where +analyze delete from t1 where t1.c2 in ( select max(a.c2) from v1 a +where a.c1 = t1.c1); +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 32.00 100.00 25.00 Using where +2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 32 32.00 25.00 3.12 Using where +select * from t1; +c1 c2 c3 +1 1 1 +1 3 3 +11 1 11 +11 3 13 +12 1 14 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 3 6 +2 4 7 +2 5 8 +21 3 22 +21 4 23 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 3 32 +31 4 33 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete from view +# +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +create table tmp as select * from v1 where v1.c1 in +(select max(a.c1) from t1 a where a.c2 = v1.c2) and c3 = 5; +explain select * from v1 where v1.c1 in +(select max(a.c1) from t1 a where a.c2 = v1.c2) and c3 = 5; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 32 Using where +explain delete from v1 where v1.c1 in +(select max(a.c1) from t1 a where a.c2 = v1.c2) and c3 = 5; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 32 Using where +delete from v1 where v1.c1 in +(select max(a.c1) from t1 a where a.c2 = v1.c2) and c3 = 5; +affected rows: 0 +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete from view using reference +# to the same view in subquery +# +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status Table is already up to date +create table tmp as select * from v1 where v1.c2 in (select max(a.c2) from t1 a where a.c3 = v1.c3) +and c1 = 2 +and exists (select 'X' from v1 a where a.c1 = v1.c1); +explain select * from v1 where v1.c2 in (select max(a.c2) from t1 a where a.c3 = v1.c3) +and c1 = 2 +and exists (select 'X' from v1 a where a.c1 = v1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL # Using where +1 PRIMARY <subquery3> eq_ref distinct_key distinct_key 4 func # +3 MATERIALIZED t1 ALL NULL NULL NULL NULL # Using where +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL # Using where +explain delete from v1 where v1.c2 in (select max(a.c2) from t1 a where a.c3 = v1.c3) +and c1 = 2 +and exists (select 'X' from v1 a where a.c1 = v1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL # Using where +3 MATERIALIZED t1 ALL NULL NULL NULL NULL # Using where +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL # Using where +analyze delete from v1 where v1.c2 in (select max(a.c2) from t1 a where a.c3 = v1.c3) +and c1 = 2 +and exists (select 'X' from v1 a where a.c1 = v1.c1); +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL # 32.00 3.91 3.12 Using where +3 MATERIALIZED t1 ALL NULL NULL NULL NULL # 32.00 25.00 25.00 Using where +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL # 32.00 100.00 3.12 Using where +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +Test with an index +create index t1_c2 on t1 (c2,c1); +# +# Delete with value from subquery on the same table +# +create table tmp as select * from t1 where c1=(select a.c3 from t1 a where a.c3 = t1.c3); +explain select * from t1 where c1=(select a.c3 from t1 a where a.c3 = t1.c3); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 32 Using where +explain delete from t1 where c1=(select a.c3 from t1 a where a.c3 = t1.c3); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 32 Using where +delete from t1 where c1=(select a.c3 from t1 a where a.c3 = t1.c3); +affected rows: 4 +select * from t1; +c1 c2 c3 +1 2 2 +1 3 3 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete with EXISTS subquery over the updated table +# in WHERE + possibly sargable condition +# +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +create table tmp as select * from t1 where c1 = 1 and exists (select 'X' from t1 a where a.c1 = t1.c2); +explain select * from t1 where c1 = 1 and exists (select 'X' from t1 a where a.c1 = t1.c2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL t1_c2 NULL NULL NULL 32 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a index NULL t1_c2 10 NULL 32 Using index +explain delete from t1 where c1 = 1 and exists (select 'X' from t1 a where a.c1 = t1.c2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL t1_c2 NULL NULL NULL 32 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a index NULL t1_c2 10 NULL 32 Using index +analyze delete from t1 where c1 = 1 and exists (select 'X' from t1 a where a.c1 = t1.c2); +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 PRIMARY t1 ALL t1_c2 NULL NULL NULL 32 32.00 9.38 9.38 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 0.67 100.00 100.00 +2 MATERIALIZED a index NULL t1_c2 10 NULL 32 32.00 100.00 100.00 Using index +select * from t1; +c1 c2 c3 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete with EXISTS subquery over the updated table +# in WHERE + non-sargable condition +# +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +create table tmp as select * from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 = 3; +explain select * from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 = 3; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ref t1_c2 t1_c2 5 const 8 +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ref t1_c2 t1_c2 5 const 8 Using index +explain delete from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 = 3; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ref t1_c2 t1_c2 5 const 8 +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ref t1_c2 t1_c2 5 const 8 Using index +delete from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 = 3; +affected rows: 8 +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +11 1 11 +11 2 12 +12 1 14 +12 2 15 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 4 7 +2 5 8 +21 2 21 +21 4 23 +22 2 24 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 4 33 +32 2 34 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete with order by +# +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +create table tmp as select * from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 order by c2; +explain select * from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 order by c2; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL t1_c2 NULL NULL NULL 32 Using where; Using filesort +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a range t1_c2 t1_c2 5 NULL 21 Using where; Using index +explain delete from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 order by c2; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 range t1_c2 t1_c2 5 NULL 21 Using index condition +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a range t1_c2 t1_c2 5 NULL 21 Using where; Using index +analyze delete from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 order by c2; +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 PRIMARY t1 range t1_c2 t1_c2 5 NULL 21 20.00 100.00 100.00 Using index condition +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 1.00 100.00 100.00 +2 MATERIALIZED a range t1_c2 t1_c2 5 NULL 21 20.00 100.00 100.00 Using where; Using index +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +11 1 11 +11 2 12 +12 1 14 +12 2 15 +2 1 4 +2 2 5 +21 2 21 +22 2 24 +31 2 31 +32 2 34 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete with IN predicand over the updated table in WHERE +# +create table tmp as select * from t1 where c3 in (select distinct a.c1 from t1 a where t1.c2=a.c2); +explain select * from t1 where c3 in (select distinct a.c1 from t1 a where t1.c2=a.c2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL t1_c2 NULL NULL NULL 32 Using where +1 PRIMARY a ref t1_c2 t1_c2 10 test.t1.c2,test.t1.c3 1 Using index; FirstMatch(t1) +explain delete from t1 where c3 in (select distinct a.c1 from t1 a where t1.c2=a.c2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL t1_c2 NULL NULL NULL 32 Using where +1 PRIMARY a ref t1_c2 t1_c2 10 test.t1.c2,test.t1.c3 1 Using index; FirstMatch(t1) +delete from t1 where c3 in (select distinct a.c1 from t1 a where t1.c2=a.c2); +affected rows: 8 +select * from t1; +c1 c2 c3 +1 3 3 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete with a limit - can be deleted +# +create table tmp as select * from t1 where c1 in (select a.c2 from t1 a where a.c2 = t1.c3) limit 1; +explain select * from t1 where c1 in (select a.c2 from t1 a where a.c2 = t1.c3) limit 1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +1 PRIMARY a ref t1_c2 t1_c2 5 test.t1.c1 5 Using index; FirstMatch(t1) +explain delete from t1 where c1 in (select a.c2 from t1 a where a.c2 = t1.c3) limit 1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +1 PRIMARY a ref t1_c2 t1_c2 5 test.t1.c1 5 Using index; FirstMatch(t1) +analyze delete from t1 where c1 in (select a.c2 from t1 a where a.c2 = t1.c3) limit 1; +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 30.00 100.00 13.33 Using where +1 PRIMARY a ref t1_c2 t1_c2 5 test.t1.c1 5 0.25 100.00 100.00 Using index; FirstMatch(t1) +select * from t1; +c1 c2 c3 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete with a limit and an order by +# +create table tmp as select * from t1 where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +explain select * from t1 where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where; Using filesort +1 PRIMARY a ref t1_c2 t1_c2 5 test.t1.c1 5 Using where; FirstMatch(t1) +explain delete from t1 where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where; Using filesort +2 DEPENDENT SUBQUERY a index_subquery t1_c2 t1_c2 5 func 5 Using where +delete from t1 where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +affected rows: 1 +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete: 2 execution of PS +# +prepare create_tmp_stmt from +"create table tmp as select * from t1 + where c2=(select a.c3 from t1 a where a.c3 = ?)"; +prepare delete_t1_stmt from +"delete from t1 where c2=(select a.c3 from t1 a where a.c3 = ?)"; +set @a:=5; +execute create_tmp_stmt using @a; +execute delete_t1_stmt using @a; +execute delete_t1_stmt using @a; +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 6 38 +prepare insert_tmp_stmt from +"insert into tmp(c1,c2,c3) select * from t1 + where c2=(select a.c3 from t1 a where a.c3 = ?)"; +set @a:=2; +execute insert_tmp_stmt using @a; +execute delete_t1_stmt using @a; +select * from t1; +c1 c2 c3 +1 1 1 +1 3 3 +11 1 11 +11 3 13 +12 1 14 +12 3 16 +12 4 17 +2 1 4 +2 3 6 +2 4 7 +21 3 22 +21 4 23 +22 3 25 +22 4 26 +22 6 28 +31 3 32 +31 4 33 +32 3 35 +32 4 36 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +drop table tmp; +# +# Delete in stored procedure +# +create procedure sp() +begin +delete from t1 where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +end +// +create table tmp as select * from t1 +where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +CALL sp; +insert into tmp(c1,c2,c3) select * from t1 +where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +CALL sp; +insert into tmp(c1,c2,c3) select * from t1 +where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +CALL sp; +select * from t1; +c1 c2 c3 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop procedure sp; +drop table tmp; +# +# Delete in stored function +# +create function f1(IN a INT) returns int +begin +delete from t1 where c3 < a order by c3 limit 1; +return 1; +end;// +set @a:=7; +create table tmp as select * from t1 where c3 < @a +order by c3 limit 1; +select f1(@a); +f1(@a) +1 +insert into tmp(c1,c2,c3) select * from t1 where c3 < @a +order by c3 limit 1; +select f1(@a); +f1(@a) +1 +select * from t1; +c1 c2 c3 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop function f1; +drop table tmp; +# +# Delete in trigger +# +create table t2 (c1 integer); +insert into t2(c1) values (1), (2), (3), (4), (5), (6), (7), (8); +CREATE TABLE cnt(del integer); +INSERT INTO cnt VALUES(0); +CREATE TRIGGER tr1 AFTER DELETE ON t1 FOR EACH ROW +UPDATE cnt SET del=del+1; +CREATE TRIGGER tr2 AFTER DELETE ON t1 FOR EACH ROW +DELETE FROM t2 WHERE c1> (SELECT count(*)-1 FROM t2); +CREATE TABLE tmp as SELECT * FROM t1 WHERE c2>=3; +DELETE FROM t1 WHERE c2>=3; +affected rows: 20 +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +11 1 11 +11 2 12 +12 1 14 +12 2 15 +2 1 4 +2 2 5 +21 2 21 +22 2 24 +31 2 31 +32 2 34 +SELECT * FROM t2; +c1 +SELECT * FROM cnt; +del +20 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +DROP TRIGGER tr1; +DROP TRIGGER tr2; +drop table t2, cnt, tmp; +# +# Delete with a reference to view in subquery +# +create table tmp as select * from t1 where t1.c2 in ( select max(a.c2) from v1 a +where a.c1 = t1.c1); +explain select * from t1 where t1.c2 in ( select max(a.c2) from v1 a +where a.c1 = t1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +2 DEPENDENT SUBQUERY t1 ref t1_c2 t1_c2 10 const,test.t1.c1 1 Using index +explain delete from t1 where t1.c2 in ( select max(a.c2) from v1 a +where a.c1 = t1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +2 DEPENDENT SUBQUERY t1 ref t1_c2 t1_c2 10 const,test.t1.c1 1 Using index +analyze delete from t1 where t1.c2 in ( select max(a.c2) from v1 a +where a.c1 = t1.c1); +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 32.00 100.00 25.00 Using where +2 DEPENDENT SUBQUERY t1 ref t1_c2 t1_c2 10 const,test.t1.c1 1 1.00 100.00 100.00 Using index +select * from t1; +c1 c2 c3 +1 1 1 +1 3 3 +11 1 11 +11 3 13 +12 1 14 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 3 6 +2 4 7 +2 5 8 +21 3 22 +21 4 23 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 3 32 +31 4 33 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete from view +# +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +create table tmp as select * from v1 where v1.c1 in +(select max(a.c1) from t1 a where a.c2 = v1.c2) and c3 = 5; +explain select * from v1 where v1.c1 in +(select max(a.c1) from t1 a where a.c2 = v1.c2) and c3 = 5; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ref t1_c2 t1_c2 5 const 8 Using where +2 DEPENDENT SUBQUERY a ref t1_c2 t1_c2 5 test.t1.c2 5 Using index +explain delete from v1 where v1.c1 in +(select max(a.c1) from t1 a where a.c2 = v1.c2) and c3 = 5; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ref t1_c2 t1_c2 5 const 8 Using where +2 DEPENDENT SUBQUERY a ref t1_c2 t1_c2 5 test.t1.c2 5 Using index +delete from v1 where v1.c1 in +(select max(a.c1) from t1 a where a.c2 = v1.c2) and c3 = 5; +affected rows: 0 +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete from view using reference +# to the same view in subquery +# +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status Table is already up to date +create table tmp as select * from v1 where v1.c2 in (select max(a.c2) from t1 a where a.c3 = v1.c3) +and c1 = 2 +and exists (select 'X' from v1 a where a.c1 = v1.c1); +explain select * from v1 where v1.c2 in (select max(a.c2) from t1 a where a.c3 = v1.c3) +and c1 = 2 +and exists (select 'X' from v1 a where a.c1 = v1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ref t1_c2 t1_c2 10 const,const # Using where +1 PRIMARY <subquery3> eq_ref distinct_key distinct_key 4 func # +3 MATERIALIZED t1 ref t1_c2 t1_c2 10 const,const # Using index +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL # Using where +explain delete from v1 where v1.c2 in (select max(a.c2) from t1 a where a.c3 = v1.c3) +and c1 = 2 +and exists (select 'X' from v1 a where a.c1 = v1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ref t1_c2 t1_c2 10 const,const # Using where +3 DEPENDENT SUBQUERY t1 ref t1_c2 t1_c2 10 const,func # Using where; Using index +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL # Using where +analyze delete from v1 where v1.c2 in (select max(a.c2) from t1 a where a.c3 = v1.c3) +and c1 = 2 +and exists (select 'X' from v1 a where a.c1 = v1.c1); +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 PRIMARY t1 ref t1_c2 t1_c2 10 const,const # 1.00 100.00 100.00 Using where +3 DEPENDENT SUBQUERY t1 ref t1_c2 t1_c2 10 const,func # 1.00 100.00 100.00 Using where; Using index +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL # 32.00 100.00 3.12 Using where +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +Test with a primary key +drop index t1_c2 on t1; +alter table t1 add primary key (c3); +# +# Delete with value from subquery on the same table +# +create table tmp as select * from t1 where c1=(select a.c3 from t1 a where a.c3 = t1.c3); +explain select * from t1 where c1=(select a.c3 from t1 a where a.c3 = t1.c3); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +2 DEPENDENT SUBQUERY a eq_ref PRIMARY PRIMARY 4 test.t1.c3 1 Using index +explain delete from t1 where c1=(select a.c3 from t1 a where a.c3 = t1.c3); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +2 DEPENDENT SUBQUERY a eq_ref PRIMARY PRIMARY 4 test.t1.c3 1 Using index +delete from t1 where c1=(select a.c3 from t1 a where a.c3 = t1.c3); +affected rows: 4 +select * from t1; +c1 c2 c3 +1 2 2 +1 3 3 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete with EXISTS subquery over the updated table +# in WHERE + possibly sargable condition +# +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +create table tmp as select * from t1 where c1 = 1 and exists (select 'X' from t1 a where a.c1 = t1.c2); +explain select * from t1 where c1 = 1 and exists (select 'X' from t1 a where a.c1 = t1.c2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ALL NULL NULL NULL NULL 32 +explain delete from t1 where c1 = 1 and exists (select 'X' from t1 a where a.c1 = t1.c2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ALL NULL NULL NULL NULL 32 +analyze delete from t1 where c1 = 1 and exists (select 'X' from t1 a where a.c1 = t1.c2); +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 32.00 9.38 9.38 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 0.67 100.00 100.00 +2 MATERIALIZED a ALL NULL NULL NULL NULL 32 32.00 100.00 100.00 +select * from t1; +c1 c2 c3 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete with EXISTS subquery over the updated table +# in WHERE + non-sargable condition +# +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +create table tmp as select * from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 = 3; +explain select * from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 = 3; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ALL NULL NULL NULL NULL 32 Using where +explain delete from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 = 3; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ALL NULL NULL NULL NULL 32 Using where +delete from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 = 3; +affected rows: 8 +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +11 1 11 +11 2 12 +12 1 14 +12 2 15 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 4 7 +2 5 8 +21 2 21 +21 4 23 +22 2 24 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 4 33 +32 2 34 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete with order by +# +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +create table tmp as select * from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 order by c2; +explain select * from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 order by c2; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where; Using filesort +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ALL NULL NULL NULL NULL 32 +explain delete from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 order by c2; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ALL NULL NULL NULL NULL 32 +analyze delete from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 order by c2; +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 32.00 62.50 62.50 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 1.00 100.00 100.00 +2 MATERIALIZED a ALL NULL NULL NULL NULL 32 32.00 62.50 100.00 +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +11 1 11 +11 2 12 +12 1 14 +12 2 15 +2 1 4 +2 2 5 +21 2 21 +22 2 24 +31 2 31 +32 2 34 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete with IN predicand over the updated table in WHERE +# +create table tmp as select * from t1 where c3 in (select distinct a.c1 from t1 a where t1.c2=a.c2); +explain select * from t1 where c3 in (select distinct a.c1 from t1 a where t1.c2=a.c2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY a ALL NULL NULL NULL NULL 32 Using where; Start temporary +1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.a.c1 1 Using where; End temporary +explain delete from t1 where c3 in (select distinct a.c1 from t1 a where t1.c2=a.c2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY a ALL NULL NULL NULL NULL 32 Using where; Start temporary +1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.a.c1 1 Using where; End temporary +delete from t1 where c3 in (select distinct a.c1 from t1 a where t1.c2=a.c2); +affected rows: 8 +select * from t1; +c1 c2 c3 +1 3 3 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete with a limit - can be deleted +# +create table tmp as select * from t1 where c1 in (select a.c2 from t1 a where a.c2 = t1.c3) limit 1; +explain select * from t1 where c1 in (select a.c2 from t1 a where a.c2 = t1.c3) limit 1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY a ALL NULL NULL NULL NULL 32 Using where; Start temporary +1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.a.c2 1 Using where; End temporary +explain delete from t1 where c1 in (select a.c2 from t1 a where a.c2 = t1.c3) limit 1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY a ALL NULL NULL NULL NULL 32 Using where; Start temporary +1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.a.c2 1 Using where; End temporary +analyze delete from t1 where c1 in (select a.c2 from t1 a where a.c2 = t1.c3) limit 1; +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 PRIMARY a ALL NULL NULL NULL NULL 32 4.00 100.00 100.00 Using where; Start temporary +1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.a.c2 1 1.00 100.00 25.00 Using where; End temporary +select * from t1; +c1 c2 c3 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete with a limit and an order by +# +create table tmp as select * from t1 where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +explain select * from t1 where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 index PRIMARY PRIMARY 4 NULL 1 +1 PRIMARY a eq_ref PRIMARY PRIMARY 4 test.t1.c3 1 Using where +explain delete from t1 where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 index NULL PRIMARY 4 NULL 1 Using where +2 DEPENDENT SUBQUERY a eq_ref PRIMARY PRIMARY 4 test.t1.c3 1 Using where +delete from t1 where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +affected rows: 1 +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete: 2 execution of PS +# +prepare create_tmp_stmt from +"create table tmp as select * from t1 + where c2=(select a.c3 from t1 a where a.c3 = ?)"; +prepare delete_t1_stmt from +"delete from t1 where c2=(select a.c3 from t1 a where a.c3 = ?)"; +set @a:=5; +execute create_tmp_stmt using @a; +execute delete_t1_stmt using @a; +execute delete_t1_stmt using @a; +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 6 38 +prepare insert_tmp_stmt from +"insert into tmp(c1,c2,c3) select * from t1 + where c2=(select a.c3 from t1 a where a.c3 = ?)"; +set @a:=2; +execute insert_tmp_stmt using @a; +execute delete_t1_stmt using @a; +select * from t1; +c1 c2 c3 +1 1 1 +1 3 3 +11 1 11 +11 3 13 +12 1 14 +12 3 16 +12 4 17 +2 1 4 +2 3 6 +2 4 7 +21 3 22 +21 4 23 +22 3 25 +22 4 26 +22 6 28 +31 3 32 +31 4 33 +32 3 35 +32 4 36 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +drop table tmp; +# +# Delete in stored procedure +# +create procedure sp() +begin +delete from t1 where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +end +// +create table tmp as select * from t1 +where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +CALL sp; +insert into tmp(c1,c2,c3) select * from t1 +where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +CALL sp; +insert into tmp(c1,c2,c3) select * from t1 +where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +CALL sp; +select * from t1; +c1 c2 c3 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop procedure sp; +drop table tmp; +# +# Delete in stored function +# +create function f1(IN a INT) returns int +begin +delete from t1 where c3 < a order by c3 limit 1; +return 1; +end;// +set @a:=7; +create table tmp as select * from t1 where c3 < @a +order by c3 limit 1; +select f1(@a); +f1(@a) +1 +insert into tmp(c1,c2,c3) select * from t1 where c3 < @a +order by c3 limit 1; +select f1(@a); +f1(@a) +1 +select * from t1; +c1 c2 c3 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop function f1; +drop table tmp; +# +# Delete in trigger +# +create table t2 (c1 integer); +insert into t2(c1) values (1), (2), (3), (4), (5), (6), (7), (8); +CREATE TABLE cnt(del integer); +INSERT INTO cnt VALUES(0); +CREATE TRIGGER tr1 AFTER DELETE ON t1 FOR EACH ROW +UPDATE cnt SET del=del+1; +CREATE TRIGGER tr2 AFTER DELETE ON t1 FOR EACH ROW +DELETE FROM t2 WHERE c1> (SELECT count(*)-1 FROM t2); +CREATE TABLE tmp as SELECT * FROM t1 WHERE c2>=3; +DELETE FROM t1 WHERE c2>=3; +affected rows: 20 +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +11 1 11 +11 2 12 +12 1 14 +12 2 15 +2 1 4 +2 2 5 +21 2 21 +22 2 24 +31 2 31 +32 2 34 +SELECT * FROM t2; +c1 +SELECT * FROM cnt; +del +20 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +DROP TRIGGER tr1; +DROP TRIGGER tr2; +drop table t2, cnt, tmp; +# +# Delete with a reference to view in subquery +# +create table tmp as select * from t1 where t1.c2 in ( select max(a.c2) from v1 a +where a.c1 = t1.c1); +explain select * from t1 where t1.c2 in ( select max(a.c2) from v1 a +where a.c1 = t1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 32 Using where +explain delete from t1 where t1.c2 in ( select max(a.c2) from v1 a +where a.c1 = t1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 32 Using where +analyze delete from t1 where t1.c2 in ( select max(a.c2) from v1 a +where a.c1 = t1.c1); +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 32.00 100.00 25.00 Using where +2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 32 32.00 25.00 3.12 Using where +select * from t1; +c1 c2 c3 +1 1 1 +1 3 3 +11 1 11 +11 3 13 +12 1 14 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 3 6 +2 4 7 +2 5 8 +21 3 22 +21 4 23 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 3 32 +31 4 33 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete from view +# +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +create table tmp as select * from v1 where v1.c1 in +(select max(a.c1) from t1 a where a.c2 = v1.c2) and c3 = 5; +explain select * from v1 where v1.c1 in +(select max(a.c1) from t1 a where a.c2 = v1.c2) and c3 = 5; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 const PRIMARY PRIMARY 4 const 1 +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 32 Using where +explain delete from v1 where v1.c1 in +(select max(a.c1) from t1 a where a.c2 = v1.c2) and c3 = 5; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 const PRIMARY PRIMARY 4 const 1 +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 32 Using where +delete from v1 where v1.c1 in +(select max(a.c1) from t1 a where a.c2 = v1.c2) and c3 = 5; +affected rows: 0 +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete from view using reference +# to the same view in subquery +# +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status Table is already up to date +create table tmp as select * from v1 where v1.c2 in (select max(a.c2) from t1 a where a.c3 = v1.c3) +and c1 = 2 +and exists (select 'X' from v1 a where a.c1 = v1.c1); +explain select * from v1 where v1.c2 in (select max(a.c2) from t1 a where a.c3 = v1.c3) +and c1 = 2 +and exists (select 'X' from v1 a where a.c1 = v1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL # Using where +1 PRIMARY <subquery3> eq_ref distinct_key distinct_key 4 func # +3 MATERIALIZED t1 ALL NULL NULL NULL NULL # Using where +2 DEPENDENT SUBQUERY a eq_ref PRIMARY PRIMARY 4 test.t1.c3 # +explain delete from v1 where v1.c2 in (select max(a.c2) from t1 a where a.c3 = v1.c3) +and c1 = 2 +and exists (select 'X' from v1 a where a.c1 = v1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL # Using where +3 MATERIALIZED t1 ALL NULL NULL NULL NULL # Using where +2 DEPENDENT SUBQUERY a eq_ref PRIMARY PRIMARY 4 test.t1.c3 # +analyze delete from v1 where v1.c2 in (select max(a.c2) from t1 a where a.c3 = v1.c3) +and c1 = 2 +and exists (select 'X' from v1 a where a.c1 = v1.c1); +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL # 32.00 3.91 3.12 Using where +3 MATERIALIZED t1 ALL NULL NULL NULL NULL # 32.00 25.00 25.00 Using where +2 DEPENDENT SUBQUERY a eq_ref PRIMARY PRIMARY 4 test.t1.c3 # 1.00 100.00 100.00 +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +drop view v1; +drop table t1; +# +# Test on dynamic columns (blob) +# +create table assets ( +item_name varchar(32) primary key, -- A common attribute for all items +dynamic_cols blob -- Dynamic columns will be stored here +); +INSERT INTO assets +VALUES ('MariaDB T-shirt', +COLUMN_CREATE('color', 'blue', 'size', 'XL')); +INSERT INTO assets +VALUES ('Thinkpad Laptop', +COLUMN_CREATE('color', 'black', 'price', 500)); +INSERT INTO assets +VALUES ('Fridge', +COLUMN_CREATE('color', 'white', 'warranty', '5 years')); +INSERT INTO assets +VALUES ('Microwave', +COLUMN_CREATE('warranty', '3 years')); +SELECT item_name, COLUMN_GET(dynamic_cols, 'color' as char) AS color +FROM assets ORDER BY item_name; +item_name color +Fridge white +MariaDB T-shirt blue +Microwave NULL +Thinkpad Laptop black +UPDATE assets SET dynamic_cols=COLUMN_DELETE(dynamic_cols, 'color') +WHERE item_name='Fridge'; +SELECT item_name, COLUMN_GET(dynamic_cols, 'color' as char) AS color +FROM assets ORDER BY item_name; +item_name color +Fridge NULL +MariaDB T-shirt blue +Microwave NULL +Thinkpad Laptop black +DELETE FROM assets +WHERE item_name in +(select b.item_name from assets b +where COLUMN_GET(b.dynamic_cols, 'color' as char) ='black'); +SELECT item_name, COLUMN_GET(dynamic_cols, 'color' as char) AS color +FROM assets ORDER BY item_name; +item_name color +Fridge NULL +MariaDB T-shirt blue +Microwave NULL +DELETE FROM assets WHERE item_name='Microwave'; +SELECT item_name, COLUMN_GET(dynamic_cols, 'color' as char) AS color +FROM assets ORDER BY item_name; +item_name color +Fridge NULL +MariaDB T-shirt blue +drop table assets ; +# +# Test on fulltext columns +# +CREATE TABLE ft2(copy TEXT,FULLTEXT(copy)); +INSERT INTO ft2(copy) VALUES +('MySQL vs MariaDB database'), +('Oracle vs MariaDB database'), +('PostgreSQL vs MariaDB database'), +('MariaDB overview'), +('Foreign keys'), +('Primary keys'), +('Indexes'), +('Transactions'), +('Triggers'); +SELECT * FROM ft2 WHERE MATCH(copy) AGAINST('database'); +copy +MySQL vs MariaDB database +Oracle vs MariaDB database +PostgreSQL vs MariaDB database +DELETE FROM ft2 WHERE MATCH(copy) AGAINST('database'); +SELECT * FROM ft2 WHERE MATCH(copy) AGAINST('database'); +copy +drop table ft2; +set default_storage_engine=MyISAM; +create table t1 (c1 integer, c2 integer, c3 integer); +insert into t1(c1,c2,c3) +values (1,1,1),(1,2,2),(1,3,3), +(2,1,4),(2,2,5),(2,3,6), +(2,4,7),(2,5,8); +insert into t1 select c1+10,c2,c3+10 from t1; +insert into t1 select c1+20,c2+1,c3+20 from t1; +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +create view v1 as select * from t1 where c2=2; +Test without any index +# +# Delete with value from subquery on the same table +# +create table tmp as select * from t1 where c1=(select a.c3 from t1 a where a.c3 = t1.c3); +explain select * from t1 where c1=(select a.c3 from t1 a where a.c3 = t1.c3); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 32 Using where +explain delete from t1 where c1=(select a.c3 from t1 a where a.c3 = t1.c3); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 32 Using where +delete from t1 where c1=(select a.c3 from t1 a where a.c3 = t1.c3); +affected rows: 4 +select * from t1; +c1 c2 c3 +1 2 2 +1 3 3 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete with EXISTS subquery over the updated table +# in WHERE + possibly sargable condition +# +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +create table tmp as select * from t1 where c1 = 1 and exists (select 'X' from t1 a where a.c1 = t1.c2); +explain select * from t1 where c1 = 1 and exists (select 'X' from t1 a where a.c1 = t1.c2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ALL NULL NULL NULL NULL 32 +explain delete from t1 where c1 = 1 and exists (select 'X' from t1 a where a.c1 = t1.c2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ALL NULL NULL NULL NULL 32 +analyze delete from t1 where c1 = 1 and exists (select 'X' from t1 a where a.c1 = t1.c2); +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 32.00 9.38 9.38 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 0.67 100.00 100.00 +2 MATERIALIZED a ALL NULL NULL NULL NULL 32 32.00 100.00 100.00 +select * from t1; +c1 c2 c3 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete with EXISTS subquery over the updated table +# in WHERE + non-sargable condition +# +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +create table tmp as select * from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 = 3; +explain select * from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 = 3; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ALL NULL NULL NULL NULL 32 Using where +explain delete from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 = 3; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ALL NULL NULL NULL NULL 32 Using where +delete from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 = 3; +affected rows: 8 +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +11 1 11 +11 2 12 +12 1 14 +12 2 15 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 4 7 +2 5 8 +21 2 21 +21 4 23 +22 2 24 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 4 33 +32 2 34 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete with order by +# +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +create table tmp as select * from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 order by c2; +explain select * from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 order by c2; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where; Using filesort +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ALL NULL NULL NULL NULL 32 +explain delete from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 order by c2; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ALL NULL NULL NULL NULL 32 +analyze delete from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 order by c2; +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 32.00 62.50 62.50 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 1.00 100.00 100.00 +2 MATERIALIZED a ALL NULL NULL NULL NULL 32 32.00 62.50 100.00 +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +11 1 11 +11 2 12 +12 1 14 +12 2 15 +2 1 4 +2 2 5 +21 2 21 +22 2 24 +31 2 31 +32 2 34 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete with IN predicand over the updated table in WHERE +# +create table tmp as select * from t1 where c3 in (select distinct a.c1 from t1 a where t1.c2=a.c2); +explain select * from t1 where c3 in (select distinct a.c1 from t1 a where t1.c2=a.c2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 +1 PRIMARY a ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) +explain delete from t1 where c3 in (select distinct a.c1 from t1 a where t1.c2=a.c2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 +1 PRIMARY a ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1) +delete from t1 where c3 in (select distinct a.c1 from t1 a where t1.c2=a.c2); +affected rows: 8 +select * from t1; +c1 c2 c3 +1 3 3 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete with a limit - can be deleted +# +create table tmp as select * from t1 where c1 in (select a.c2 from t1 a where a.c2 = t1.c3) limit 1; +explain select * from t1 where c1 in (select a.c2 from t1 a where a.c2 = t1.c3) limit 1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +1 PRIMARY a ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) +explain delete from t1 where c1 in (select a.c2 from t1 a where a.c2 = t1.c3) limit 1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +1 PRIMARY a ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1) +analyze delete from t1 where c1 in (select a.c2 from t1 a where a.c2 = t1.c3) limit 1; +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 25.00 100.00 12.00 Using where +1 PRIMARY a ALL NULL NULL NULL NULL 32 22.67 100.00 1.47 Using where; FirstMatch(t1) +select * from t1; +c1 c2 c3 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete with a limit and an order by +# +create table tmp as select * from t1 where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +explain select * from t1 where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using temporary; Using filesort +1 PRIMARY a ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) +explain delete from t1 where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where; Using filesort +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 32 Using where +delete from t1 where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +affected rows: 1 +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete: 2 execution of PS +# +prepare create_tmp_stmt from +"create table tmp as select * from t1 + where c2=(select a.c3 from t1 a where a.c3 = ?)"; +prepare delete_t1_stmt from +"delete from t1 where c2=(select a.c3 from t1 a where a.c3 = ?)"; +set @a:=5; +execute create_tmp_stmt using @a; +execute delete_t1_stmt using @a; +execute delete_t1_stmt using @a; +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 6 38 +prepare insert_tmp_stmt from +"insert into tmp(c1,c2,c3) select * from t1 + where c2=(select a.c3 from t1 a where a.c3 = ?)"; +set @a:=2; +execute insert_tmp_stmt using @a; +execute delete_t1_stmt using @a; +select * from t1; +c1 c2 c3 +1 1 1 +1 3 3 +11 1 11 +11 3 13 +12 1 14 +12 3 16 +12 4 17 +2 1 4 +2 3 6 +2 4 7 +21 3 22 +21 4 23 +22 3 25 +22 4 26 +22 6 28 +31 3 32 +31 4 33 +32 3 35 +32 4 36 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +drop table tmp; +# +# Delete in stored procedure +# +create procedure sp() +begin +delete from t1 where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +end +// +create table tmp as select * from t1 +where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +CALL sp; +insert into tmp(c1,c2,c3) select * from t1 +where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +CALL sp; +insert into tmp(c1,c2,c3) select * from t1 +where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +CALL sp; +select * from t1; +c1 c2 c3 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop procedure sp; +drop table tmp; +# +# Delete in stored function +# +create function f1(IN a INT) returns int +begin +delete from t1 where c3 < a order by c3 limit 1; +return 1; +end;// +set @a:=7; +create table tmp as select * from t1 where c3 < @a +order by c3 limit 1; +select f1(@a); +f1(@a) +1 +insert into tmp(c1,c2,c3) select * from t1 where c3 < @a +order by c3 limit 1; +select f1(@a); +f1(@a) +1 +select * from t1; +c1 c2 c3 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop function f1; +drop table tmp; +# +# Delete in trigger +# +create table t2 (c1 integer); +insert into t2(c1) values (1), (2), (3), (4), (5), (6), (7), (8); +CREATE TABLE cnt(del integer); +INSERT INTO cnt VALUES(0); +CREATE TRIGGER tr1 AFTER DELETE ON t1 FOR EACH ROW +UPDATE cnt SET del=del+1; +CREATE TRIGGER tr2 AFTER DELETE ON t1 FOR EACH ROW +DELETE FROM t2 WHERE c1> (SELECT count(*)-1 FROM t2); +CREATE TABLE tmp as SELECT * FROM t1 WHERE c2>=3; +DELETE FROM t1 WHERE c2>=3; +affected rows: 20 +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +11 1 11 +11 2 12 +12 1 14 +12 2 15 +2 1 4 +2 2 5 +21 2 21 +22 2 24 +31 2 31 +32 2 34 +SELECT * FROM t2; +c1 +SELECT * FROM cnt; +del +20 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +DROP TRIGGER tr1; +DROP TRIGGER tr2; +drop table t2, cnt, tmp; +# +# Delete with a reference to view in subquery +# +create table tmp as select * from t1 where t1.c2 in ( select max(a.c2) from v1 a +where a.c1 = t1.c1); +explain select * from t1 where t1.c2 in ( select max(a.c2) from v1 a +where a.c1 = t1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 32 Using where +explain delete from t1 where t1.c2 in ( select max(a.c2) from v1 a +where a.c1 = t1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 32 Using where +analyze delete from t1 where t1.c2 in ( select max(a.c2) from v1 a +where a.c1 = t1.c1); +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 32.00 100.00 25.00 Using where +2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 32 32.00 25.00 3.12 Using where +select * from t1; +c1 c2 c3 +1 1 1 +1 3 3 +11 1 11 +11 3 13 +12 1 14 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 3 6 +2 4 7 +2 5 8 +21 3 22 +21 4 23 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 3 32 +31 4 33 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete from view +# +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +create table tmp as select * from v1 where v1.c1 in +(select max(a.c1) from t1 a where a.c2 = v1.c2) and c3 = 5; +explain select * from v1 where v1.c1 in +(select max(a.c1) from t1 a where a.c2 = v1.c2) and c3 = 5; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 32 Using where +explain delete from v1 where v1.c1 in +(select max(a.c1) from t1 a where a.c2 = v1.c2) and c3 = 5; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 32 Using where +delete from v1 where v1.c1 in +(select max(a.c1) from t1 a where a.c2 = v1.c2) and c3 = 5; +affected rows: 0 +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete from view using reference +# to the same view in subquery +# +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status Table is already up to date +create table tmp as select * from v1 where v1.c2 in (select max(a.c2) from t1 a where a.c3 = v1.c3) +and c1 = 2 +and exists (select 'X' from v1 a where a.c1 = v1.c1); +explain select * from v1 where v1.c2 in (select max(a.c2) from t1 a where a.c3 = v1.c3) +and c1 = 2 +and exists (select 'X' from v1 a where a.c1 = v1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL # Using where +1 PRIMARY <subquery3> eq_ref distinct_key distinct_key 4 func # +3 MATERIALIZED t1 ALL NULL NULL NULL NULL # Using where +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL # Using where +explain delete from v1 where v1.c2 in (select max(a.c2) from t1 a where a.c3 = v1.c3) +and c1 = 2 +and exists (select 'X' from v1 a where a.c1 = v1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL # Using where +3 MATERIALIZED t1 ALL NULL NULL NULL NULL # Using where +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL # Using where +analyze delete from v1 where v1.c2 in (select max(a.c2) from t1 a where a.c3 = v1.c3) +and c1 = 2 +and exists (select 'X' from v1 a where a.c1 = v1.c1); +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL # 32.00 3.91 3.12 Using where +3 MATERIALIZED t1 ALL NULL NULL NULL NULL # 32.00 25.00 25.00 Using where +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL # 32.00 100.00 3.12 Using where +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +Test with an index +create index t1_c2 on t1 (c2,c1); +# +# Delete with value from subquery on the same table +# +create table tmp as select * from t1 where c1=(select a.c3 from t1 a where a.c3 = t1.c3); +explain select * from t1 where c1=(select a.c3 from t1 a where a.c3 = t1.c3); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 32 Using where +explain delete from t1 where c1=(select a.c3 from t1 a where a.c3 = t1.c3); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 32 Using where +delete from t1 where c1=(select a.c3 from t1 a where a.c3 = t1.c3); +affected rows: 4 +select * from t1; +c1 c2 c3 +1 2 2 +1 3 3 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete with EXISTS subquery over the updated table +# in WHERE + possibly sargable condition +# +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +create table tmp as select * from t1 where c1 = 1 and exists (select 'X' from t1 a where a.c1 = t1.c2); +explain select * from t1 where c1 = 1 and exists (select 'X' from t1 a where a.c1 = t1.c2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL t1_c2 NULL NULL NULL 32 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a index NULL t1_c2 10 NULL 32 Using index +explain delete from t1 where c1 = 1 and exists (select 'X' from t1 a where a.c1 = t1.c2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL t1_c2 NULL NULL NULL 32 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a index NULL t1_c2 10 NULL 32 Using index +analyze delete from t1 where c1 = 1 and exists (select 'X' from t1 a where a.c1 = t1.c2); +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 PRIMARY t1 ALL t1_c2 NULL NULL NULL 32 32.00 9.38 9.38 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 0.67 100.00 100.00 +2 MATERIALIZED a index NULL t1_c2 10 NULL 32 32.00 100.00 100.00 Using index +select * from t1; +c1 c2 c3 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete with EXISTS subquery over the updated table +# in WHERE + non-sargable condition +# +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +create table tmp as select * from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 = 3; +explain select * from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 = 3; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ref t1_c2 t1_c2 5 const 8 +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ref t1_c2 t1_c2 5 const 8 Using index +explain delete from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 = 3; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ref t1_c2 t1_c2 5 const 8 +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ref t1_c2 t1_c2 5 const 8 Using index +delete from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 = 3; +affected rows: 8 +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +11 1 11 +11 2 12 +12 1 14 +12 2 15 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 4 7 +2 5 8 +21 2 21 +21 4 23 +22 2 24 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 4 33 +32 2 34 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete with order by +# +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +create table tmp as select * from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 order by c2; +explain select * from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 order by c2; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL t1_c2 NULL NULL NULL 32 Using where; Using filesort +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a range t1_c2 t1_c2 5 NULL 20 Using where; Using index +explain delete from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 order by c2; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 range t1_c2 t1_c2 5 NULL 20 Using index condition +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a range t1_c2 t1_c2 5 NULL 20 Using where; Using index +analyze delete from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 order by c2; +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 PRIMARY t1 range t1_c2 t1_c2 5 NULL 20 20.00 100.00 100.00 Using index condition +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 1.00 100.00 100.00 +2 MATERIALIZED a range t1_c2 t1_c2 5 NULL 20 20.00 100.00 100.00 Using where; Using index +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +11 1 11 +11 2 12 +12 1 14 +12 2 15 +2 1 4 +2 2 5 +21 2 21 +22 2 24 +31 2 31 +32 2 34 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete with IN predicand over the updated table in WHERE +# +create table tmp as select * from t1 where c3 in (select distinct a.c1 from t1 a where t1.c2=a.c2); +explain select * from t1 where c3 in (select distinct a.c1 from t1 a where t1.c2=a.c2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL t1_c2 NULL NULL NULL 32 Using where +1 PRIMARY a ref t1_c2 t1_c2 10 test.t1.c2,test.t1.c3 1 Using index; FirstMatch(t1) +explain delete from t1 where c3 in (select distinct a.c1 from t1 a where t1.c2=a.c2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL t1_c2 NULL NULL NULL 32 Using where +1 PRIMARY a ref t1_c2 t1_c2 10 test.t1.c2,test.t1.c3 1 Using index; FirstMatch(t1) +delete from t1 where c3 in (select distinct a.c1 from t1 a where t1.c2=a.c2); +affected rows: 8 +select * from t1; +c1 c2 c3 +1 3 3 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete with a limit - can be deleted +# +create table tmp as select * from t1 where c1 in (select a.c2 from t1 a where a.c2 = t1.c3) limit 1; +explain select * from t1 where c1 in (select a.c2 from t1 a where a.c2 = t1.c3) limit 1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +1 PRIMARY a ref t1_c2 t1_c2 5 test.t1.c1 5 Using index; FirstMatch(t1) +explain delete from t1 where c1 in (select a.c2 from t1 a where a.c2 = t1.c3) limit 1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +1 PRIMARY a ref t1_c2 t1_c2 5 test.t1.c1 5 Using index; FirstMatch(t1) +analyze delete from t1 where c1 in (select a.c2 from t1 a where a.c2 = t1.c3) limit 1; +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 27.00 100.00 14.81 Using where +1 PRIMARY a ref t1_c2 t1_c2 5 test.t1.c1 5 0.25 100.00 100.00 Using index; FirstMatch(t1) +select * from t1; +c1 c2 c3 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete with a limit and an order by +# +create table tmp as select * from t1 where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +explain select * from t1 where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where; Using filesort +1 PRIMARY a ref t1_c2 t1_c2 5 test.t1.c1 5 Using where; FirstMatch(t1) +explain delete from t1 where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where; Using filesort +2 DEPENDENT SUBQUERY a index_subquery t1_c2 t1_c2 5 func 5 Using where +delete from t1 where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +affected rows: 1 +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete: 2 execution of PS +# +prepare create_tmp_stmt from +"create table tmp as select * from t1 + where c2=(select a.c3 from t1 a where a.c3 = ?)"; +prepare delete_t1_stmt from +"delete from t1 where c2=(select a.c3 from t1 a where a.c3 = ?)"; +set @a:=5; +execute create_tmp_stmt using @a; +execute delete_t1_stmt using @a; +execute delete_t1_stmt using @a; +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 6 38 +prepare insert_tmp_stmt from +"insert into tmp(c1,c2,c3) select * from t1 + where c2=(select a.c3 from t1 a where a.c3 = ?)"; +set @a:=2; +execute insert_tmp_stmt using @a; +execute delete_t1_stmt using @a; +select * from t1; +c1 c2 c3 +1 1 1 +1 3 3 +11 1 11 +11 3 13 +12 1 14 +12 3 16 +12 4 17 +2 1 4 +2 3 6 +2 4 7 +21 3 22 +21 4 23 +22 3 25 +22 4 26 +22 6 28 +31 3 32 +31 4 33 +32 3 35 +32 4 36 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +drop table tmp; +# +# Delete in stored procedure +# +create procedure sp() +begin +delete from t1 where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +end +// +create table tmp as select * from t1 +where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +CALL sp; +insert into tmp(c1,c2,c3) select * from t1 +where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +CALL sp; +insert into tmp(c1,c2,c3) select * from t1 +where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +CALL sp; +select * from t1; +c1 c2 c3 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop procedure sp; +drop table tmp; +# +# Delete in stored function +# +create function f1(IN a INT) returns int +begin +delete from t1 where c3 < a order by c3 limit 1; +return 1; +end;// +set @a:=7; +create table tmp as select * from t1 where c3 < @a +order by c3 limit 1; +select f1(@a); +f1(@a) +1 +insert into tmp(c1,c2,c3) select * from t1 where c3 < @a +order by c3 limit 1; +select f1(@a); +f1(@a) +1 +select * from t1; +c1 c2 c3 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop function f1; +drop table tmp; +# +# Delete in trigger +# +create table t2 (c1 integer); +insert into t2(c1) values (1), (2), (3), (4), (5), (6), (7), (8); +CREATE TABLE cnt(del integer); +INSERT INTO cnt VALUES(0); +CREATE TRIGGER tr1 AFTER DELETE ON t1 FOR EACH ROW +UPDATE cnt SET del=del+1; +CREATE TRIGGER tr2 AFTER DELETE ON t1 FOR EACH ROW +DELETE FROM t2 WHERE c1> (SELECT count(*)-1 FROM t2); +CREATE TABLE tmp as SELECT * FROM t1 WHERE c2>=3; +DELETE FROM t1 WHERE c2>=3; +affected rows: 20 +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +11 1 11 +11 2 12 +12 1 14 +12 2 15 +2 1 4 +2 2 5 +21 2 21 +22 2 24 +31 2 31 +32 2 34 +SELECT * FROM t2; +c1 +SELECT * FROM cnt; +del +20 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +DROP TRIGGER tr1; +DROP TRIGGER tr2; +drop table t2, cnt, tmp; +# +# Delete with a reference to view in subquery +# +create table tmp as select * from t1 where t1.c2 in ( select max(a.c2) from v1 a +where a.c1 = t1.c1); +explain select * from t1 where t1.c2 in ( select max(a.c2) from v1 a +where a.c1 = t1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +2 DEPENDENT SUBQUERY t1 ref t1_c2 t1_c2 10 const,test.t1.c1 1 Using index +explain delete from t1 where t1.c2 in ( select max(a.c2) from v1 a +where a.c1 = t1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +2 DEPENDENT SUBQUERY t1 ref t1_c2 t1_c2 10 const,test.t1.c1 1 Using index +analyze delete from t1 where t1.c2 in ( select max(a.c2) from v1 a +where a.c1 = t1.c1); +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 32.00 100.00 25.00 Using where +2 DEPENDENT SUBQUERY t1 ref t1_c2 t1_c2 10 const,test.t1.c1 1 1.00 100.00 100.00 Using index +select * from t1; +c1 c2 c3 +1 1 1 +1 3 3 +11 1 11 +11 3 13 +12 1 14 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 3 6 +2 4 7 +2 5 8 +21 3 22 +21 4 23 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 3 32 +31 4 33 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete from view +# +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +create table tmp as select * from v1 where v1.c1 in +(select max(a.c1) from t1 a where a.c2 = v1.c2) and c3 = 5; +explain select * from v1 where v1.c1 in +(select max(a.c1) from t1 a where a.c2 = v1.c2) and c3 = 5; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ref t1_c2 t1_c2 5 const 8 Using where +2 DEPENDENT SUBQUERY a ref t1_c2 t1_c2 5 test.t1.c2 5 Using index +explain delete from v1 where v1.c1 in +(select max(a.c1) from t1 a where a.c2 = v1.c2) and c3 = 5; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ref t1_c2 t1_c2 5 const 8 Using where +2 DEPENDENT SUBQUERY a ref t1_c2 t1_c2 5 test.t1.c2 5 Using index +delete from v1 where v1.c1 in +(select max(a.c1) from t1 a where a.c2 = v1.c2) and c3 = 5; +affected rows: 0 +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete from view using reference +# to the same view in subquery +# +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status Table is already up to date +create table tmp as select * from v1 where v1.c2 in (select max(a.c2) from t1 a where a.c3 = v1.c3) +and c1 = 2 +and exists (select 'X' from v1 a where a.c1 = v1.c1); +explain select * from v1 where v1.c2 in (select max(a.c2) from t1 a where a.c3 = v1.c3) +and c1 = 2 +and exists (select 'X' from v1 a where a.c1 = v1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ref t1_c2 t1_c2 10 const,const # Using where +1 PRIMARY <subquery3> eq_ref distinct_key distinct_key 4 func # +3 MATERIALIZED t1 ref t1_c2 t1_c2 10 const,const # Using index +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL # Using where +explain delete from v1 where v1.c2 in (select max(a.c2) from t1 a where a.c3 = v1.c3) +and c1 = 2 +and exists (select 'X' from v1 a where a.c1 = v1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ref t1_c2 t1_c2 10 const,const # Using where +3 DEPENDENT SUBQUERY t1 ref t1_c2 t1_c2 10 const,func # Using where; Using index +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL # Using where +analyze delete from v1 where v1.c2 in (select max(a.c2) from t1 a where a.c3 = v1.c3) +and c1 = 2 +and exists (select 'X' from v1 a where a.c1 = v1.c1); +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 PRIMARY t1 ref t1_c2 t1_c2 10 const,const # 1.00 100.00 100.00 Using where +3 DEPENDENT SUBQUERY t1 ref t1_c2 t1_c2 10 const,func # 1.00 100.00 100.00 Using where; Using index +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL # 32.00 100.00 3.12 Using where +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +Test with a primary key +drop index t1_c2 on t1; +alter table t1 add primary key (c3); +# +# Delete with value from subquery on the same table +# +create table tmp as select * from t1 where c1=(select a.c3 from t1 a where a.c3 = t1.c3); +explain select * from t1 where c1=(select a.c3 from t1 a where a.c3 = t1.c3); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +2 DEPENDENT SUBQUERY a eq_ref PRIMARY PRIMARY 4 test.t1.c3 1 Using index +explain delete from t1 where c1=(select a.c3 from t1 a where a.c3 = t1.c3); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +2 DEPENDENT SUBQUERY a eq_ref PRIMARY PRIMARY 4 test.t1.c3 1 Using index +delete from t1 where c1=(select a.c3 from t1 a where a.c3 = t1.c3); +affected rows: 4 +select * from t1; +c1 c2 c3 +1 2 2 +1 3 3 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete with EXISTS subquery over the updated table +# in WHERE + possibly sargable condition +# +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +create table tmp as select * from t1 where c1 = 1 and exists (select 'X' from t1 a where a.c1 = t1.c2); +explain select * from t1 where c1 = 1 and exists (select 'X' from t1 a where a.c1 = t1.c2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ALL NULL NULL NULL NULL 32 +explain delete from t1 where c1 = 1 and exists (select 'X' from t1 a where a.c1 = t1.c2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ALL NULL NULL NULL NULL 32 +analyze delete from t1 where c1 = 1 and exists (select 'X' from t1 a where a.c1 = t1.c2); +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 32.00 9.38 9.38 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 0.67 100.00 100.00 +2 MATERIALIZED a ALL NULL NULL NULL NULL 32 32.00 100.00 100.00 +select * from t1; +c1 c2 c3 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete with EXISTS subquery over the updated table +# in WHERE + non-sargable condition +# +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +create table tmp as select * from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 = 3; +explain select * from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 = 3; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ALL NULL NULL NULL NULL 32 Using where +explain delete from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 = 3; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ALL NULL NULL NULL NULL 32 Using where +delete from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 = 3; +affected rows: 8 +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +11 1 11 +11 2 12 +12 1 14 +12 2 15 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 4 7 +2 5 8 +21 2 21 +21 4 23 +22 2 24 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 4 33 +32 2 34 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete with order by +# +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +create table tmp as select * from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 order by c2; +explain select * from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 order by c2; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where; Using filesort +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ALL NULL NULL NULL NULL 32 +explain delete from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 order by c2; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ALL NULL NULL NULL NULL 32 +analyze delete from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 order by c2; +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 32.00 62.50 62.50 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 1.00 100.00 100.00 +2 MATERIALIZED a ALL NULL NULL NULL NULL 32 32.00 62.50 100.00 +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +11 1 11 +11 2 12 +12 1 14 +12 2 15 +2 1 4 +2 2 5 +21 2 21 +22 2 24 +31 2 31 +32 2 34 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete with IN predicand over the updated table in WHERE +# +create table tmp as select * from t1 where c3 in (select distinct a.c1 from t1 a where t1.c2=a.c2); +explain select * from t1 where c3 in (select distinct a.c1 from t1 a where t1.c2=a.c2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY a ALL NULL NULL NULL NULL 32 Using where; Start temporary +1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.a.c1 1 Using where; End temporary +explain delete from t1 where c3 in (select distinct a.c1 from t1 a where t1.c2=a.c2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY a ALL NULL NULL NULL NULL 32 Using where; Start temporary +1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.a.c1 1 Using where; End temporary +delete from t1 where c3 in (select distinct a.c1 from t1 a where t1.c2=a.c2); +affected rows: 8 +select * from t1; +c1 c2 c3 +1 3 3 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete with a limit - can be deleted +# +create table tmp as select * from t1 where c1 in (select a.c2 from t1 a where a.c2 = t1.c3) limit 1; +explain select * from t1 where c1 in (select a.c2 from t1 a where a.c2 = t1.c3) limit 1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY a ALL NULL NULL NULL NULL 32 Using where; Start temporary +1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.a.c2 1 Using where; End temporary +explain delete from t1 where c1 in (select a.c2 from t1 a where a.c2 = t1.c3) limit 1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY a ALL NULL NULL NULL NULL 32 Using where; Start temporary +1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.a.c2 1 Using where; End temporary +analyze delete from t1 where c1 in (select a.c2 from t1 a where a.c2 = t1.c3) limit 1; +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 PRIMARY a ALL NULL NULL NULL NULL 32 4.00 100.00 100.00 Using where; Start temporary +1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.a.c2 1 1.00 100.00 25.00 Using where; End temporary +select * from t1; +c1 c2 c3 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete with a limit and an order by +# +create table tmp as select * from t1 where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +explain select * from t1 where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 index PRIMARY PRIMARY 4 NULL 1 +1 PRIMARY a eq_ref PRIMARY PRIMARY 4 test.t1.c3 1 Using where +explain delete from t1 where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 index NULL PRIMARY 4 NULL 1 Using where +2 DEPENDENT SUBQUERY a eq_ref PRIMARY PRIMARY 4 test.t1.c3 1 Using where +delete from t1 where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +affected rows: 1 +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete: 2 execution of PS +# +prepare create_tmp_stmt from +"create table tmp as select * from t1 + where c2=(select a.c3 from t1 a where a.c3 = ?)"; +prepare delete_t1_stmt from +"delete from t1 where c2=(select a.c3 from t1 a where a.c3 = ?)"; +set @a:=5; +execute create_tmp_stmt using @a; +execute delete_t1_stmt using @a; +execute delete_t1_stmt using @a; +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 6 38 +prepare insert_tmp_stmt from +"insert into tmp(c1,c2,c3) select * from t1 + where c2=(select a.c3 from t1 a where a.c3 = ?)"; +set @a:=2; +execute insert_tmp_stmt using @a; +execute delete_t1_stmt using @a; +select * from t1; +c1 c2 c3 +1 1 1 +1 3 3 +11 1 11 +11 3 13 +12 1 14 +12 3 16 +12 4 17 +2 1 4 +2 3 6 +2 4 7 +21 3 22 +21 4 23 +22 3 25 +22 4 26 +22 6 28 +31 3 32 +31 4 33 +32 3 35 +32 4 36 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +drop table tmp; +# +# Delete in stored procedure +# +create procedure sp() +begin +delete from t1 where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +end +// +create table tmp as select * from t1 +where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +CALL sp; +insert into tmp(c1,c2,c3) select * from t1 +where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +CALL sp; +insert into tmp(c1,c2,c3) select * from t1 +where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +CALL sp; +select * from t1; +c1 c2 c3 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop procedure sp; +drop table tmp; +# +# Delete in stored function +# +create function f1(IN a INT) returns int +begin +delete from t1 where c3 < a order by c3 limit 1; +return 1; +end;// +set @a:=7; +create table tmp as select * from t1 where c3 < @a +order by c3 limit 1; +select f1(@a); +f1(@a) +1 +insert into tmp(c1,c2,c3) select * from t1 where c3 < @a +order by c3 limit 1; +select f1(@a); +f1(@a) +1 +select * from t1; +c1 c2 c3 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop function f1; +drop table tmp; +# +# Delete in trigger +# +create table t2 (c1 integer); +insert into t2(c1) values (1), (2), (3), (4), (5), (6), (7), (8); +CREATE TABLE cnt(del integer); +INSERT INTO cnt VALUES(0); +CREATE TRIGGER tr1 AFTER DELETE ON t1 FOR EACH ROW +UPDATE cnt SET del=del+1; +CREATE TRIGGER tr2 AFTER DELETE ON t1 FOR EACH ROW +DELETE FROM t2 WHERE c1> (SELECT count(*)-1 FROM t2); +CREATE TABLE tmp as SELECT * FROM t1 WHERE c2>=3; +DELETE FROM t1 WHERE c2>=3; +affected rows: 20 +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +11 1 11 +11 2 12 +12 1 14 +12 2 15 +2 1 4 +2 2 5 +21 2 21 +22 2 24 +31 2 31 +32 2 34 +SELECT * FROM t2; +c1 +SELECT * FROM cnt; +del +20 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +DROP TRIGGER tr1; +DROP TRIGGER tr2; +drop table t2, cnt, tmp; +# +# Delete with a reference to view in subquery +# +create table tmp as select * from t1 where t1.c2 in ( select max(a.c2) from v1 a +where a.c1 = t1.c1); +explain select * from t1 where t1.c2 in ( select max(a.c2) from v1 a +where a.c1 = t1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 32 Using where +explain delete from t1 where t1.c2 in ( select max(a.c2) from v1 a +where a.c1 = t1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 32 Using where +analyze delete from t1 where t1.c2 in ( select max(a.c2) from v1 a +where a.c1 = t1.c1); +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 32.00 100.00 25.00 Using where +2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 32 32.00 25.00 3.12 Using where +select * from t1; +c1 c2 c3 +1 1 1 +1 3 3 +11 1 11 +11 3 13 +12 1 14 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 3 6 +2 4 7 +2 5 8 +21 3 22 +21 4 23 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 3 32 +31 4 33 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete from view +# +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +create table tmp as select * from v1 where v1.c1 in +(select max(a.c1) from t1 a where a.c2 = v1.c2) and c3 = 5; +explain select * from v1 where v1.c1 in +(select max(a.c1) from t1 a where a.c2 = v1.c2) and c3 = 5; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 const PRIMARY PRIMARY 4 const 1 +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 32 Using where +explain delete from v1 where v1.c1 in +(select max(a.c1) from t1 a where a.c2 = v1.c2) and c3 = 5; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 const PRIMARY PRIMARY 4 const 1 +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 32 Using where +delete from v1 where v1.c1 in +(select max(a.c1) from t1 a where a.c2 = v1.c2) and c3 = 5; +affected rows: 0 +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete from view using reference +# to the same view in subquery +# +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status Table is already up to date +create table tmp as select * from v1 where v1.c2 in (select max(a.c2) from t1 a where a.c3 = v1.c3) +and c1 = 2 +and exists (select 'X' from v1 a where a.c1 = v1.c1); +explain select * from v1 where v1.c2 in (select max(a.c2) from t1 a where a.c3 = v1.c3) +and c1 = 2 +and exists (select 'X' from v1 a where a.c1 = v1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL # Using where +1 PRIMARY <subquery3> eq_ref distinct_key distinct_key 4 func # +3 MATERIALIZED t1 ALL NULL NULL NULL NULL # Using where +2 DEPENDENT SUBQUERY a eq_ref PRIMARY PRIMARY 4 test.t1.c3 # +explain delete from v1 where v1.c2 in (select max(a.c2) from t1 a where a.c3 = v1.c3) +and c1 = 2 +and exists (select 'X' from v1 a where a.c1 = v1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL # Using where +3 MATERIALIZED t1 ALL NULL NULL NULL NULL # Using where +2 DEPENDENT SUBQUERY a eq_ref PRIMARY PRIMARY 4 test.t1.c3 # +analyze delete from v1 where v1.c2 in (select max(a.c2) from t1 a where a.c3 = v1.c3) +and c1 = 2 +and exists (select 'X' from v1 a where a.c1 = v1.c1); +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL # 32.00 3.91 3.12 Using where +3 MATERIALIZED t1 ALL NULL NULL NULL NULL # 32.00 25.00 25.00 Using where +2 DEPENDENT SUBQUERY a eq_ref PRIMARY PRIMARY 4 test.t1.c3 # 1.00 100.00 100.00 +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +drop view v1; +drop table t1; +# +# Test on dynamic columns (blob) +# +create table assets ( +item_name varchar(32) primary key, -- A common attribute for all items +dynamic_cols blob -- Dynamic columns will be stored here +); +INSERT INTO assets +VALUES ('MariaDB T-shirt', +COLUMN_CREATE('color', 'blue', 'size', 'XL')); +INSERT INTO assets +VALUES ('Thinkpad Laptop', +COLUMN_CREATE('color', 'black', 'price', 500)); +INSERT INTO assets +VALUES ('Fridge', +COLUMN_CREATE('color', 'white', 'warranty', '5 years')); +INSERT INTO assets +VALUES ('Microwave', +COLUMN_CREATE('warranty', '3 years')); +SELECT item_name, COLUMN_GET(dynamic_cols, 'color' as char) AS color +FROM assets ORDER BY item_name; +item_name color +Fridge white +MariaDB T-shirt blue +Microwave NULL +Thinkpad Laptop black +UPDATE assets SET dynamic_cols=COLUMN_DELETE(dynamic_cols, 'color') +WHERE item_name='Fridge'; +SELECT item_name, COLUMN_GET(dynamic_cols, 'color' as char) AS color +FROM assets ORDER BY item_name; +item_name color +Fridge NULL +MariaDB T-shirt blue +Microwave NULL +Thinkpad Laptop black +DELETE FROM assets +WHERE item_name in +(select b.item_name from assets b +where COLUMN_GET(b.dynamic_cols, 'color' as char) ='black'); +SELECT item_name, COLUMN_GET(dynamic_cols, 'color' as char) AS color +FROM assets ORDER BY item_name; +item_name color +Fridge NULL +MariaDB T-shirt blue +Microwave NULL +DELETE FROM assets WHERE item_name='Microwave'; +SELECT item_name, COLUMN_GET(dynamic_cols, 'color' as char) AS color +FROM assets ORDER BY item_name; +item_name color +Fridge NULL +MariaDB T-shirt blue +drop table assets ; +# +# Test on fulltext columns +# +CREATE TABLE ft2(copy TEXT,FULLTEXT(copy)); +INSERT INTO ft2(copy) VALUES +('MySQL vs MariaDB database'), +('Oracle vs MariaDB database'), +('PostgreSQL vs MariaDB database'), +('MariaDB overview'), +('Foreign keys'), +('Primary keys'), +('Indexes'), +('Transactions'), +('Triggers'); +SELECT * FROM ft2 WHERE MATCH(copy) AGAINST('database'); +copy +MySQL vs MariaDB database +Oracle vs MariaDB database +PostgreSQL vs MariaDB database +DELETE FROM ft2 WHERE MATCH(copy) AGAINST('database'); +SELECT * FROM ft2 WHERE MATCH(copy) AGAINST('database'); +copy +drop table ft2; +set default_storage_engine=MEMORY; +create table t1 (c1 integer, c2 integer, c3 integer); +insert into t1(c1,c2,c3) +values (1,1,1),(1,2,2),(1,3,3), +(2,1,4),(2,2,5),(2,3,6), +(2,4,7),(2,5,8); +insert into t1 select c1+10,c2,c3+10 from t1; +insert into t1 select c1+20,c2+1,c3+20 from t1; +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze note The storage engine for the table doesn't support analyze +create view v1 as select * from t1 where c2=2; +Test without any index +# +# Delete with value from subquery on the same table +# +create table tmp as select * from t1 where c1=(select a.c3 from t1 a where a.c3 = t1.c3); +explain select * from t1 where c1=(select a.c3 from t1 a where a.c3 = t1.c3); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 32 Using where +explain delete from t1 where c1=(select a.c3 from t1 a where a.c3 = t1.c3); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 32 Using where +delete from t1 where c1=(select a.c3 from t1 a where a.c3 = t1.c3); +affected rows: 4 +select * from t1; +c1 c2 c3 +1 2 2 +1 3 3 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete with EXISTS subquery over the updated table +# in WHERE + possibly sargable condition +# +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze note The storage engine for the table doesn't support analyze +create table tmp as select * from t1 where c1 = 1 and exists (select 'X' from t1 a where a.c1 = t1.c2); +explain select * from t1 where c1 = 1 and exists (select 'X' from t1 a where a.c1 = t1.c2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ALL NULL NULL NULL NULL 32 +explain delete from t1 where c1 = 1 and exists (select 'X' from t1 a where a.c1 = t1.c2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ALL NULL NULL NULL NULL 32 +delete from t1 where c1 = 1 and exists (select 'X' from t1 a where a.c1 = t1.c2); +affected rows: 2 +select * from t1; +c1 c2 c3 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete with EXISTS subquery over the updated table +# in WHERE + non-sargable condition +# +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze note The storage engine for the table doesn't support analyze +create table tmp as select * from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 = 3; +explain select * from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 = 3; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ALL NULL NULL NULL NULL 32 Using where +explain delete from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 = 3; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ALL NULL NULL NULL NULL 32 Using where +delete from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 = 3; +affected rows: 8 +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +11 1 11 +11 2 12 +12 1 14 +12 2 15 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 4 7 +2 5 8 +21 2 21 +21 4 23 +22 2 24 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 4 33 +32 2 34 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete with order by +# +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze note The storage engine for the table doesn't support analyze +create table tmp as select * from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 order by c2; +explain select * from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 order by c2; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where; Using filesort +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ALL NULL NULL NULL NULL 32 +explain delete from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 order by c2; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ALL NULL NULL NULL NULL 32 +delete from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 order by c2; +affected rows: 20 +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +11 1 11 +11 2 12 +12 1 14 +12 2 15 +2 1 4 +2 2 5 +21 2 21 +22 2 24 +31 2 31 +32 2 34 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete with IN predicand over the updated table in WHERE +# +create table tmp as select * from t1 where c3 in (select distinct a.c1 from t1 a where t1.c2=a.c2); +explain select * from t1 where c3 in (select distinct a.c1 from t1 a where t1.c2=a.c2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 +1 PRIMARY a ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) +explain delete from t1 where c3 in (select distinct a.c1 from t1 a where t1.c2=a.c2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 +1 PRIMARY a ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1) +delete from t1 where c3 in (select distinct a.c1 from t1 a where t1.c2=a.c2); +affected rows: 8 +select * from t1; +c1 c2 c3 +1 3 3 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete with a limit - can be deleted +# +create table tmp as select * from t1 where c1 in (select a.c2 from t1 a where a.c2 = t1.c3) limit 1; +explain select * from t1 where c1 in (select a.c2 from t1 a where a.c2 = t1.c3) limit 1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +1 PRIMARY a ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) +explain delete from t1 where c1 in (select a.c2 from t1 a where a.c2 = t1.c3) limit 1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +1 PRIMARY a ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1) +delete from t1 where c1 in (select a.c2 from t1 a where a.c2 = t1.c3) limit 1; +affected rows: 1 +select * from t1; +c1 c2 c3 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete with a limit and an order by +# +create table tmp as select * from t1 where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +explain select * from t1 where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using temporary; Using filesort +1 PRIMARY a ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) +explain delete from t1 where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where; Using filesort +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 32 Using where +delete from t1 where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +affected rows: 1 +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete: 2 execution of PS +# +prepare create_tmp_stmt from +"create table tmp as select * from t1 + where c2=(select a.c3 from t1 a where a.c3 = ?)"; +prepare delete_t1_stmt from +"delete from t1 where c2=(select a.c3 from t1 a where a.c3 = ?)"; +set @a:=5; +execute create_tmp_stmt using @a; +execute delete_t1_stmt using @a; +execute delete_t1_stmt using @a; +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 6 38 +prepare insert_tmp_stmt from +"insert into tmp(c1,c2,c3) select * from t1 + where c2=(select a.c3 from t1 a where a.c3 = ?)"; +set @a:=2; +execute insert_tmp_stmt using @a; +execute delete_t1_stmt using @a; +select * from t1; +c1 c2 c3 +1 1 1 +1 3 3 +11 1 11 +11 3 13 +12 1 14 +12 3 16 +12 4 17 +2 1 4 +2 3 6 +2 4 7 +21 3 22 +21 4 23 +22 3 25 +22 4 26 +22 6 28 +31 3 32 +31 4 33 +32 3 35 +32 4 36 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +drop table tmp; +# +# Delete in stored procedure +# +create procedure sp() +begin +delete from t1 where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +end +// +create table tmp as select * from t1 +where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +CALL sp; +insert into tmp(c1,c2,c3) select * from t1 +where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +CALL sp; +insert into tmp(c1,c2,c3) select * from t1 +where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +CALL sp; +select * from t1; +c1 c2 c3 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop procedure sp; +drop table tmp; +# +# Delete in stored function +# +create function f1(IN a INT) returns int +begin +delete from t1 where c3 < a order by c3 limit 1; +return 1; +end;// +set @a:=7; +create table tmp as select * from t1 where c3 < @a +order by c3 limit 1; +select f1(@a); +f1(@a) +1 +insert into tmp(c1,c2,c3) select * from t1 where c3 < @a +order by c3 limit 1; +select f1(@a); +f1(@a) +1 +select * from t1; +c1 c2 c3 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop function f1; +drop table tmp; +# +# Delete in trigger +# +create table t2 (c1 integer); +insert into t2(c1) values (1), (2), (3), (4), (5), (6), (7), (8); +CREATE TABLE cnt(del integer); +INSERT INTO cnt VALUES(0); +CREATE TRIGGER tr1 AFTER DELETE ON t1 FOR EACH ROW +UPDATE cnt SET del=del+1; +CREATE TRIGGER tr2 AFTER DELETE ON t1 FOR EACH ROW +DELETE FROM t2 WHERE c1> (SELECT count(*)-1 FROM t2); +CREATE TABLE tmp as SELECT * FROM t1 WHERE c2>=3; +DELETE FROM t1 WHERE c2>=3; +affected rows: 20 +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +11 1 11 +11 2 12 +12 1 14 +12 2 15 +2 1 4 +2 2 5 +21 2 21 +22 2 24 +31 2 31 +32 2 34 +SELECT * FROM t2; +c1 +SELECT * FROM cnt; +del +20 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +DROP TRIGGER tr1; +DROP TRIGGER tr2; +drop table t2, cnt, tmp; +# +Delete with a reference to view in subquery +# +create table tmp as select * from t1 where t1.c2 in ( select max(a.c2) from v1 a +where a.c1 = t1.c1); +explain select * from t1 where t1.c2 in ( select max(a.c2) from v1 a +where a.c1 = t1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 32 Using where +explain delete from t1 where t1.c2 in ( select max(a.c2) from v1 a +where a.c1 = t1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 32 Using where +delete from t1 where t1.c2 in ( select max(a.c2) from v1 a +where a.c1 = t1.c1); +affected rows: 8 +select * from t1; +c1 c2 c3 +1 1 1 +1 3 3 +11 1 11 +11 3 13 +12 1 14 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 3 6 +2 4 7 +2 5 8 +21 3 22 +21 4 23 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 3 32 +31 4 33 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete from view +# +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze note The storage engine for the table doesn't support analyze +create table tmp as select * from v1 where v1.c1 in +(select max(a.c1) from t1 a where a.c2 = v1.c2) and c3 = 5; +explain select * from v1 where v1.c1 in +(select max(a.c1) from t1 a where a.c2 = v1.c2) and c3 = 5; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 32 Using where +explain delete from v1 where v1.c1 in +(select max(a.c1) from t1 a where a.c2 = v1.c2) and c3 = 5; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 32 Using where +delete from v1 where v1.c1 in +(select max(a.c1) from t1 a where a.c2 = v1.c2) and c3 = 5; +affected rows: 0 +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete from view using reference +# to the same view in subquery +# +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze note The storage engine for the table doesn't support analyze +create table tmp as select * from v1 where v1.c2 in (select max(a.c2) from t1 a where a.c3 = v1.c3) +and c1 = 2 +and exists (select 'X' from v1 a where a.c1 = v1.c1); +explain select * from v1 where v1.c2 in (select max(a.c2) from t1 a where a.c3 = v1.c3) +and c1 = 2 +and exists (select 'X' from v1 a where a.c1 = v1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL # Using where +1 PRIMARY <subquery3> eq_ref distinct_key distinct_key 4 func # +3 MATERIALIZED t1 ALL NULL NULL NULL NULL # Using where +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL # Using where +explain delete from v1 where v1.c2 in (select max(a.c2) from t1 a where a.c3 = v1.c3) +and c1 = 2 +and exists (select 'X' from v1 a where a.c1 = v1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL # Using where +3 MATERIALIZED t1 ALL NULL NULL NULL NULL # Using where +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL # Using where +delete from v1 where v1.c2 in (select max(a.c2) from t1 a where a.c3 = v1.c3) +and c1 = 2 +and exists (select 'X' from v1 a where a.c1 = v1.c1); +affected rows: 1 +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +Test with an index +create index t1_c2 on t1 (c2,c1); +# +# Delete with value from subquery on the same table +# +create table tmp as select * from t1 where c1=(select a.c3 from t1 a where a.c3 = t1.c3); +explain select * from t1 where c1=(select a.c3 from t1 a where a.c3 = t1.c3); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 32 Using where +explain delete from t1 where c1=(select a.c3 from t1 a where a.c3 = t1.c3); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 32 Using where +delete from t1 where c1=(select a.c3 from t1 a where a.c3 = t1.c3); +affected rows: 4 +select * from t1; +c1 c2 c3 +1 2 2 +1 3 3 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete with EXISTS subquery over the updated table +# in WHERE + possibly sargable condition +# +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Operation failed +create table tmp as select * from t1 where c1 = 1 and exists (select 'X' from t1 a where a.c1 = t1.c2); +explain select * from t1 where c1 = 1 and exists (select 'X' from t1 a where a.c1 = t1.c2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL t1_c2 NULL NULL NULL 32 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ALL NULL NULL NULL NULL 32 +explain delete from t1 where c1 = 1 and exists (select 'X' from t1 a where a.c1 = t1.c2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL t1_c2 NULL NULL NULL 32 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ALL NULL NULL NULL NULL 32 +delete from t1 where c1 = 1 and exists (select 'X' from t1 a where a.c1 = t1.c2); +affected rows: 2 +select * from t1; +c1 c2 c3 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete with EXISTS subquery over the updated table +# in WHERE + non-sargable condition +# +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Operation failed +create table tmp as select * from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 = 3; +explain select * from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 = 3; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL t1_c2 NULL NULL NULL 32 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ALL t1_c2 NULL NULL NULL 32 Using where +explain delete from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 = 3; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL t1_c2 NULL NULL NULL 32 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ALL t1_c2 NULL NULL NULL 32 Using where +delete from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 = 3; +affected rows: 8 +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +11 1 11 +11 2 12 +12 1 14 +12 2 15 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 4 7 +2 5 8 +21 2 21 +21 4 23 +22 2 24 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 4 33 +32 2 34 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete with order by +# +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Operation failed +create table tmp as select * from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 order by c2; +explain select * from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 order by c2; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL t1_c2 NULL NULL NULL 32 Using where; Using filesort +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ALL t1_c2 NULL NULL NULL 32 +explain delete from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 order by c2; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL t1_c2 NULL NULL NULL 32 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ALL t1_c2 NULL NULL NULL 32 +delete from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 order by c2; +affected rows: 20 +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +11 1 11 +11 2 12 +12 1 14 +12 2 15 +2 1 4 +2 2 5 +21 2 21 +22 2 24 +31 2 31 +32 2 34 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete with IN predicand over the updated table in WHERE +# +create table tmp as select * from t1 where c3 in (select distinct a.c1 from t1 a where t1.c2=a.c2); +explain select * from t1 where c3 in (select distinct a.c1 from t1 a where t1.c2=a.c2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL t1_c2 NULL NULL NULL 32 Using where +1 PRIMARY a ref t1_c2 t1_c2 10 test.t1.c2,test.t1.c3 2 FirstMatch(t1) +explain delete from t1 where c3 in (select distinct a.c1 from t1 a where t1.c2=a.c2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL t1_c2 NULL NULL NULL 32 Using where +1 PRIMARY a ref t1_c2 t1_c2 10 test.t1.c2,test.t1.c3 2 FirstMatch(t1) +delete from t1 where c3 in (select distinct a.c1 from t1 a where t1.c2=a.c2); +affected rows: 8 +select * from t1; +c1 c2 c3 +1 3 3 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete with a limit - can be deleted +# +create table tmp as select * from t1 where c1 in (select a.c2 from t1 a where a.c2 = t1.c3) limit 1; +explain select * from t1 where c1 in (select a.c2 from t1 a where a.c2 = t1.c3) limit 1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +1 PRIMARY a ALL t1_c2 NULL NULL NULL 32 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) +explain delete from t1 where c1 in (select a.c2 from t1 a where a.c2 = t1.c3) limit 1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +1 PRIMARY a ALL t1_c2 NULL NULL NULL 32 Using where; FirstMatch(t1) +delete from t1 where c1 in (select a.c2 from t1 a where a.c2 = t1.c3) limit 1; +affected rows: 1 +select * from t1; +c1 c2 c3 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete with a limit and an order by +# +create table tmp as select * from t1 where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +explain select * from t1 where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using temporary; Using filesort +1 PRIMARY a ALL t1_c2 NULL NULL NULL 32 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) +explain delete from t1 where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where; Using filesort +2 DEPENDENT SUBQUERY a ALL t1_c2 NULL NULL NULL 32 Using where +delete from t1 where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +affected rows: 1 +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete: 2 execution of PS +# +prepare create_tmp_stmt from +"create table tmp as select * from t1 + where c2=(select a.c3 from t1 a where a.c3 = ?)"; +prepare delete_t1_stmt from +"delete from t1 where c2=(select a.c3 from t1 a where a.c3 = ?)"; +set @a:=5; +execute create_tmp_stmt using @a; +execute delete_t1_stmt using @a; +execute delete_t1_stmt using @a; +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 6 38 +prepare insert_tmp_stmt from +"insert into tmp(c1,c2,c3) select * from t1 + where c2=(select a.c3 from t1 a where a.c3 = ?)"; +set @a:=2; +execute insert_tmp_stmt using @a; +execute delete_t1_stmt using @a; +select * from t1; +c1 c2 c3 +1 1 1 +1 3 3 +11 1 11 +11 3 13 +12 1 14 +12 3 16 +12 4 17 +2 1 4 +2 3 6 +2 4 7 +21 3 22 +21 4 23 +22 3 25 +22 4 26 +22 6 28 +31 3 32 +31 4 33 +32 3 35 +32 4 36 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +drop table tmp; +# +# Delete in stored procedure +# +create procedure sp() +begin +delete from t1 where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +end +// +create table tmp as select * from t1 +where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +CALL sp; +insert into tmp(c1,c2,c3) select * from t1 +where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +CALL sp; +insert into tmp(c1,c2,c3) select * from t1 +where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +CALL sp; +select * from t1; +c1 c2 c3 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop procedure sp; +drop table tmp; +# +# Delete in stored function +# +create function f1(IN a INT) returns int +begin +delete from t1 where c3 < a order by c3 limit 1; +return 1; +end;// +set @a:=7; +create table tmp as select * from t1 where c3 < @a +order by c3 limit 1; +select f1(@a); +f1(@a) +1 +insert into tmp(c1,c2,c3) select * from t1 where c3 < @a +order by c3 limit 1; +select f1(@a); +f1(@a) +1 +select * from t1; +c1 c2 c3 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop function f1; +drop table tmp; +# +# Delete in trigger +# +create table t2 (c1 integer); +insert into t2(c1) values (1), (2), (3), (4), (5), (6), (7), (8); +CREATE TABLE cnt(del integer); +INSERT INTO cnt VALUES(0); +CREATE TRIGGER tr1 AFTER DELETE ON t1 FOR EACH ROW +UPDATE cnt SET del=del+1; +CREATE TRIGGER tr2 AFTER DELETE ON t1 FOR EACH ROW +DELETE FROM t2 WHERE c1> (SELECT count(*)-1 FROM t2); +CREATE TABLE tmp as SELECT * FROM t1 WHERE c2>=3; +DELETE FROM t1 WHERE c2>=3; +affected rows: 20 +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +11 1 11 +11 2 12 +12 1 14 +12 2 15 +2 1 4 +2 2 5 +21 2 21 +22 2 24 +31 2 31 +32 2 34 +SELECT * FROM t2; +c1 +SELECT * FROM cnt; +del +20 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +DROP TRIGGER tr1; +DROP TRIGGER tr2; +drop table t2, cnt, tmp; +# +Delete with a reference to view in subquery +# +create table tmp as select * from t1 where t1.c2 in ( select max(a.c2) from v1 a +where a.c1 = t1.c1); +explain select * from t1 where t1.c2 in ( select max(a.c2) from v1 a +where a.c1 = t1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +2 DEPENDENT SUBQUERY t1 ref t1_c2 t1_c2 10 const,test.t1.c1 2 +explain delete from t1 where t1.c2 in ( select max(a.c2) from v1 a +where a.c1 = t1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +2 DEPENDENT SUBQUERY t1 ref t1_c2 t1_c2 10 const,test.t1.c1 2 +delete from t1 where t1.c2 in ( select max(a.c2) from v1 a +where a.c1 = t1.c1); +affected rows: 8 +select * from t1; +c1 c2 c3 +1 1 1 +1 3 3 +11 1 11 +11 3 13 +12 1 14 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 3 6 +2 4 7 +2 5 8 +21 3 22 +21 4 23 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 3 32 +31 4 33 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete from view +# +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Operation failed +create table tmp as select * from v1 where v1.c1 in +(select max(a.c1) from t1 a where a.c2 = v1.c2) and c3 = 5; +explain select * from v1 where v1.c1 in +(select max(a.c1) from t1 a where a.c2 = v1.c2) and c3 = 5; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL t1_c2 NULL NULL NULL 32 Using where +2 DEPENDENT SUBQUERY a ALL t1_c2 NULL NULL NULL 32 Using where +explain delete from v1 where v1.c1 in +(select max(a.c1) from t1 a where a.c2 = v1.c2) and c3 = 5; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL t1_c2 NULL NULL NULL 32 Using where +2 DEPENDENT SUBQUERY a ALL t1_c2 NULL NULL NULL 32 Using where +delete from v1 where v1.c1 in +(select max(a.c1) from t1 a where a.c2 = v1.c2) and c3 = 5; +affected rows: 0 +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete from view using reference +# to the same view in subquery +# +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Operation failed +create table tmp as select * from v1 where v1.c2 in (select max(a.c2) from t1 a where a.c3 = v1.c3) +and c1 = 2 +and exists (select 'X' from v1 a where a.c1 = v1.c1); +explain select * from v1 where v1.c2 in (select max(a.c2) from t1 a where a.c3 = v1.c3) +and c1 = 2 +and exists (select 'X' from v1 a where a.c1 = v1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ref t1_c2 t1_c2 10 const,const # Using where +1 PRIMARY <subquery3> eq_ref distinct_key distinct_key 4 func # +3 MATERIALIZED t1 ref t1_c2 t1_c2 10 const,const # +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL # Using where +explain delete from v1 where v1.c2 in (select max(a.c2) from t1 a where a.c3 = v1.c3) +and c1 = 2 +and exists (select 'X' from v1 a where a.c1 = v1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ref t1_c2 t1_c2 10 const,const # Using where +3 DEPENDENT SUBQUERY t1 ref t1_c2 t1_c2 10 const,func # Using where +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL # Using where +delete from v1 where v1.c2 in (select max(a.c2) from t1 a where a.c3 = v1.c3) +and c1 = 2 +and exists (select 'X' from v1 a where a.c1 = v1.c1); +affected rows: 1 +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +Test with a primary key +drop index t1_c2 on t1; +alter table t1 add primary key (c3); +# +# Delete with value from subquery on the same table +# +create table tmp as select * from t1 where c1=(select a.c3 from t1 a where a.c3 = t1.c3); +explain select * from t1 where c1=(select a.c3 from t1 a where a.c3 = t1.c3); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +2 DEPENDENT SUBQUERY a eq_ref PRIMARY PRIMARY 4 test.t1.c3 1 +explain delete from t1 where c1=(select a.c3 from t1 a where a.c3 = t1.c3); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +2 DEPENDENT SUBQUERY a eq_ref PRIMARY PRIMARY 4 test.t1.c3 1 +delete from t1 where c1=(select a.c3 from t1 a where a.c3 = t1.c3); +affected rows: 4 +select * from t1; +c1 c2 c3 +1 2 2 +1 3 3 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete with EXISTS subquery over the updated table +# in WHERE + possibly sargable condition +# +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze note The storage engine for the table doesn't support analyze +create table tmp as select * from t1 where c1 = 1 and exists (select 'X' from t1 a where a.c1 = t1.c2); +explain select * from t1 where c1 = 1 and exists (select 'X' from t1 a where a.c1 = t1.c2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ALL NULL NULL NULL NULL 32 +explain delete from t1 where c1 = 1 and exists (select 'X' from t1 a where a.c1 = t1.c2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ALL NULL NULL NULL NULL 32 +delete from t1 where c1 = 1 and exists (select 'X' from t1 a where a.c1 = t1.c2); +affected rows: 2 +select * from t1; +c1 c2 c3 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete with EXISTS subquery over the updated table +# in WHERE + non-sargable condition +# +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze note The storage engine for the table doesn't support analyze +create table tmp as select * from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 = 3; +explain select * from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 = 3; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ALL NULL NULL NULL NULL 32 Using where +explain delete from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 = 3; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ALL NULL NULL NULL NULL 32 Using where +delete from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 = 3; +affected rows: 8 +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +11 1 11 +11 2 12 +12 1 14 +12 2 15 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 4 7 +2 5 8 +21 2 21 +21 4 23 +22 2 24 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 4 33 +32 2 34 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete with order by +# +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze note The storage engine for the table doesn't support analyze +create table tmp as select * from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 order by c2; +explain select * from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 order by c2; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where; Using filesort +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ALL NULL NULL NULL NULL 32 +explain delete from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 order by c2; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ALL NULL NULL NULL NULL 32 +delete from t1 where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 order by c2; +affected rows: 20 +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +11 1 11 +11 2 12 +12 1 14 +12 2 15 +2 1 4 +2 2 5 +21 2 21 +22 2 24 +31 2 31 +32 2 34 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete with IN predicand over the updated table in WHERE +# +create table tmp as select * from t1 where c3 in (select distinct a.c1 from t1 a where t1.c2=a.c2); +explain select * from t1 where c3 in (select distinct a.c1 from t1 a where t1.c2=a.c2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY a ALL NULL NULL NULL NULL 32 Using where; Start temporary +1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.a.c1 1 Using where; End temporary +explain delete from t1 where c3 in (select distinct a.c1 from t1 a where t1.c2=a.c2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY a ALL NULL NULL NULL NULL 32 Using where; Start temporary +1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.a.c1 1 Using where; End temporary +delete from t1 where c3 in (select distinct a.c1 from t1 a where t1.c2=a.c2); +affected rows: 8 +select * from t1; +c1 c2 c3 +1 3 3 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete with a limit - can be deleted +# +create table tmp as select * from t1 where c1 in (select a.c2 from t1 a where a.c2 = t1.c3) limit 1; +explain select * from t1 where c1 in (select a.c2 from t1 a where a.c2 = t1.c3) limit 1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY a ALL NULL NULL NULL NULL 32 Using where; Start temporary +1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.a.c2 1 Using where; End temporary +explain delete from t1 where c1 in (select a.c2 from t1 a where a.c2 = t1.c3) limit 1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY a ALL NULL NULL NULL NULL 32 Using where; Start temporary +1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.a.c2 1 Using where; End temporary +delete from t1 where c1 in (select a.c2 from t1 a where a.c2 = t1.c3) limit 1; +affected rows: 1 +select * from t1; +c1 c2 c3 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete with a limit and an order by +# +create table tmp as select * from t1 where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +explain select * from t1 where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 32 Using filesort +1 PRIMARY a eq_ref PRIMARY PRIMARY 4 test.t1.c3 1 Using where +explain delete from t1 where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where; Using filesort +2 DEPENDENT SUBQUERY a eq_ref PRIMARY PRIMARY 4 test.t1.c3 1 Using where +delete from t1 where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +affected rows: 1 +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete: 2 execution of PS +# +prepare create_tmp_stmt from +"create table tmp as select * from t1 + where c2=(select a.c3 from t1 a where a.c3 = ?)"; +prepare delete_t1_stmt from +"delete from t1 where c2=(select a.c3 from t1 a where a.c3 = ?)"; +set @a:=5; +execute create_tmp_stmt using @a; +execute delete_t1_stmt using @a; +execute delete_t1_stmt using @a; +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 6 38 +prepare insert_tmp_stmt from +"insert into tmp(c1,c2,c3) select * from t1 + where c2=(select a.c3 from t1 a where a.c3 = ?)"; +set @a:=2; +execute insert_tmp_stmt using @a; +execute delete_t1_stmt using @a; +select * from t1; +c1 c2 c3 +1 1 1 +1 3 3 +11 1 11 +11 3 13 +12 1 14 +12 3 16 +12 4 17 +2 1 4 +2 3 6 +2 4 7 +21 3 22 +21 4 23 +22 3 25 +22 4 26 +22 6 28 +31 3 32 +31 4 33 +32 3 35 +32 4 36 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +drop table tmp; +# +# Delete in stored procedure +# +create procedure sp() +begin +delete from t1 where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +end +// +create table tmp as select * from t1 +where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +CALL sp; +insert into tmp(c1,c2,c3) select * from t1 +where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +CALL sp; +insert into tmp(c1,c2,c3) select * from t1 +where c1 in (select a.c2 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 1; +CALL sp; +select * from t1; +c1 c2 c3 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop procedure sp; +drop table tmp; +# +# Delete in stored function +# +create function f1(IN a INT) returns int +begin +delete from t1 where c3 < a order by c3 limit 1; +return 1; +end;// +set @a:=7; +create table tmp as select * from t1 where c3 < @a +order by c3 limit 1; +select f1(@a); +f1(@a) +1 +insert into tmp(c1,c2,c3) select * from t1 where c3 < @a +order by c3 limit 1; +select f1(@a); +f1(@a) +1 +select * from t1; +c1 c2 c3 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop function f1; +drop table tmp; +# +# Delete in trigger +# +create table t2 (c1 integer); +insert into t2(c1) values (1), (2), (3), (4), (5), (6), (7), (8); +CREATE TABLE cnt(del integer); +INSERT INTO cnt VALUES(0); +CREATE TRIGGER tr1 AFTER DELETE ON t1 FOR EACH ROW +UPDATE cnt SET del=del+1; +CREATE TRIGGER tr2 AFTER DELETE ON t1 FOR EACH ROW +DELETE FROM t2 WHERE c1> (SELECT count(*)-1 FROM t2); +CREATE TABLE tmp as SELECT * FROM t1 WHERE c2>=3; +DELETE FROM t1 WHERE c2>=3; +affected rows: 20 +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +11 1 11 +11 2 12 +12 1 14 +12 2 15 +2 1 4 +2 2 5 +21 2 21 +22 2 24 +31 2 31 +32 2 34 +SELECT * FROM t2; +c1 +SELECT * FROM cnt; +del +20 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +DROP TRIGGER tr1; +DROP TRIGGER tr2; +drop table t2, cnt, tmp; +# +Delete with a reference to view in subquery +# +create table tmp as select * from t1 where t1.c2 in ( select max(a.c2) from v1 a +where a.c1 = t1.c1); +explain select * from t1 where t1.c2 in ( select max(a.c2) from v1 a +where a.c1 = t1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 32 Using where +explain delete from t1 where t1.c2 in ( select max(a.c2) from v1 a +where a.c1 = t1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where +2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 32 Using where +delete from t1 where t1.c2 in ( select max(a.c2) from v1 a +where a.c1 = t1.c1); +affected rows: 8 +select * from t1; +c1 c2 c3 +1 1 1 +1 3 3 +11 1 11 +11 3 13 +12 1 14 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 3 6 +2 4 7 +2 5 8 +21 3 22 +21 4 23 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 3 32 +31 4 33 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete from view +# +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze note The storage engine for the table doesn't support analyze +create table tmp as select * from v1 where v1.c1 in +(select max(a.c1) from t1 a where a.c2 = v1.c2) and c3 = 5; +explain select * from v1 where v1.c1 in +(select max(a.c1) from t1 a where a.c2 = v1.c2) and c3 = 5; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 const PRIMARY PRIMARY 4 const 1 +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 32 Using where +explain delete from v1 where v1.c1 in +(select max(a.c1) from t1 a where a.c2 = v1.c2) and c3 = 5; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 const PRIMARY PRIMARY 4 const 1 +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 32 Using where +delete from v1 where v1.c1 in +(select max(a.c1) from t1 a where a.c2 = v1.c2) and c3 = 5; +affected rows: 0 +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +# +# Delete from view using reference +# to the same view in subquery +# +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze note The storage engine for the table doesn't support analyze +create table tmp as select * from v1 where v1.c2 in (select max(a.c2) from t1 a where a.c3 = v1.c3) +and c1 = 2 +and exists (select 'X' from v1 a where a.c1 = v1.c1); +explain select * from v1 where v1.c2 in (select max(a.c2) from t1 a where a.c3 = v1.c3) +and c1 = 2 +and exists (select 'X' from v1 a where a.c1 = v1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL # Using where +1 PRIMARY <subquery3> eq_ref distinct_key distinct_key 4 func # +3 MATERIALIZED t1 ALL NULL NULL NULL NULL # Using where +2 DEPENDENT SUBQUERY a eq_ref PRIMARY PRIMARY 4 test.t1.c3 # +explain delete from v1 where v1.c2 in (select max(a.c2) from t1 a where a.c3 = v1.c3) +and c1 = 2 +and exists (select 'X' from v1 a where a.c1 = v1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL # Using where +3 MATERIALIZED t1 ALL NULL NULL NULL NULL # Using where +2 DEPENDENT SUBQUERY a eq_ref PRIMARY PRIMARY 4 test.t1.c3 # +delete from v1 where v1.c2 in (select max(a.c2) from t1 a where a.c3 = v1.c3) +and c1 = 2 +and exists (select 'X' from v1 a where a.c1 = v1.c1); +affected rows: 1 +select * from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +11 1 11 +11 2 12 +11 3 13 +12 1 14 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 4 +2 3 6 +2 4 7 +2 5 8 +21 2 21 +21 3 22 +21 4 23 +22 2 24 +22 3 25 +22 4 26 +22 5 27 +22 6 28 +31 2 31 +31 3 32 +31 4 33 +32 2 34 +32 3 35 +32 4 36 +32 5 37 +32 6 38 +insert into t1(c1,c2,c3) select c1,c2,c3 from tmp; +drop table tmp; +drop view v1; +drop table t1; +set @@default_storage_engine=@save_default_engine; +# +# End of 11.0 tests +# diff --git a/mysql-test/main/delete_use_source_engines.test b/mysql-test/main/delete_use_source_engines.test new file mode 100644 index 0000000..4938523 --- /dev/null +++ b/mysql-test/main/delete_use_source_engines.test @@ -0,0 +1,22 @@ +--source include/have_innodb.inc + +set @save_default_engine=@@default_storage_engine; + +set global innodb_stats_persistent=1; +set default_storage_engine=InnoDB; +--source include/delete_use_source.inc + +set default_storage_engine=Aria; +--source include/delete_use_source.inc + +set default_storage_engine=MyISAM; +--source include/delete_use_source.inc + +set default_storage_engine=MEMORY; +--source include/delete_use_source_memory.inc + +set @@default_storage_engine=@save_default_engine; + +--echo # +--echo # End of 11.0 tests +--echo # diff --git a/mysql-test/main/update_single_to_multi.result b/mysql-test/main/update_single_to_multi.result index d020fd1..bc988b5 100644 --- a/mysql-test/main/update_single_to_multi.result +++ b/mysql-test/main/update_single_to_multi.result @@ -2351,4 +2351,543 @@ o_orderkey o_totalprice 3139 40975.96 4903 34363.63 5607 24660.06 +# LooseScan +# ========= +set @tmp_optimizer_switch= @@optimizer_switch; +set optimizer_switch='materialization=off'; +create index i_l_sup_part on lineitem(l_suppkey, l_partkey); +create index i_ps_sup_part on partsupp(ps_suppkey, ps_partkey); +analyze table lineitem; +Table Op Msg_type Msg_text +dbt3_s001.lineitem analyze status Engine-independent statistics collected +dbt3_s001.lineitem analyze status Table is already up to date +analyze table partsupp; +Table Op Msg_type Msg_text +dbt3_s001.partsupp analyze status Engine-independent statistics collected +dbt3_s001.partsupp analyze status Table is already up to date +explain +select count(*) from lineitem where l_suppkey in +(select ps_suppkey from partsupp where ps_partkey in (1,2,3)); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY partsupp index PRIMARY,i_ps_partkey,i_ps_suppkey,i_ps_sup_part i_ps_sup_part 8 NULL 700 Using where; Using index; LooseScan +1 PRIMARY lineitem ref i_l_suppkey,i_l_sup_part i_l_suppkey 5 dbt3_s001.partsupp.ps_suppkey 600 Using index +explain format=json +select count(*) from lineitem where l_suppkey in +(select ps_suppkey from partsupp where ps_partkey in (1,2,3)); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "nested_loop": [ + { + "table": { + "table_name": "partsupp", + "access_type": "index", + "possible_keys": [ + "PRIMARY", + "i_ps_partkey", + "i_ps_suppkey", + "i_ps_sup_part" + ], + "key": "i_ps_sup_part", + "key_length": "8", + "used_key_parts": ["ps_suppkey", "ps_partkey"], + "rows": 700, + "filtered": 1.428571463, + "attached_condition": "partsupp.ps_partkey in (1,2,3)", + "using_index": true, + "loose_scan": true + } + }, + { + "table": { + "table_name": "lineitem", + "access_type": "ref", + "possible_keys": ["i_l_suppkey", "i_l_sup_part"], + "key": "i_l_suppkey", + "key_length": "5", + "used_key_parts": ["l_suppkey"], + "ref": ["dbt3_s001.partsupp.ps_suppkey"], + "rows": 600, + "filtered": 100, + "using_index": true + } + } + ] + } +} +select count(*) from lineitem where l_suppkey in +(select ps_suppkey from partsupp where ps_partkey in (1,2,3)); +count(*) +5373 +select 5373 as count, 136458704.22 as old_sum; +count old_sum +5373 136458704.22 +explain +update lineitem set l_extendedprice=l_extendedprice+10 where l_suppkey in +(select ps_suppkey from partsupp where ps_partkey in (1,2,3)); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY partsupp index PRIMARY,i_ps_partkey,i_ps_suppkey,i_ps_sup_part i_ps_sup_part 8 NULL 700 Using where; Using index; LooseScan +1 PRIMARY lineitem ref i_l_suppkey,i_l_sup_part i_l_suppkey 5 dbt3_s001.partsupp.ps_suppkey 600 +explain format=json +update lineitem set l_extendedprice=l_extendedprice+10 where l_suppkey in +(select ps_suppkey from partsupp where ps_partkey in (1,2,3)); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "nested_loop": [ + { + "table": { + "table_name": "partsupp", + "access_type": "index", + "possible_keys": [ + "PRIMARY", + "i_ps_partkey", + "i_ps_suppkey", + "i_ps_sup_part" + ], + "key": "i_ps_sup_part", + "key_length": "8", + "used_key_parts": ["ps_suppkey", "ps_partkey"], + "rows": 700, + "filtered": 1.428571463, + "attached_condition": "partsupp.ps_partkey in (1,2,3)", + "using_index": true, + "loose_scan": true + } + }, + { + "table": { + "table_name": "lineitem", + "access_type": "ref", + "possible_keys": ["i_l_suppkey", "i_l_sup_part"], + "key": "i_l_suppkey", + "key_length": "5", + "used_key_parts": ["l_suppkey"], + "ref": ["dbt3_s001.partsupp.ps_suppkey"], + "rows": 600, + "filtered": 100 + } + } + ] + } +} +update lineitem set l_extendedprice=l_extendedprice+10 where l_suppkey in +(select ps_suppkey from partsupp where ps_partkey in (1,2,3)); +select ROUND(sum(l_extendedprice),2), 5373 as count, +(136458704.22+10*5373) as 'old_sum+10*count' + from lineitem where l_suppkey in +(select ps_suppkey from partsupp where ps_partkey in (1,2,3)); +ROUND(sum(l_extendedprice),2) count old_sum+10*count +136512434.22 5373 136512434.22 +update lineitem set l_extendedprice=l_extendedprice-10 where l_suppkey in +(select ps_suppkey from partsupp where ps_partkey in (1,2,3)); +select ROUND(sum(l_extendedprice),2), 5373 as count, +136458704.22 as old_sum from lineitem where l_suppkey in +(select ps_suppkey from partsupp where ps_partkey in (1,2,3)); +ROUND(sum(l_extendedprice),2) count old_sum +136458704.22 5373 136458704.22 +# LooseScan PS +# ============ +prepare stmt from " +update lineitem set l_extendedprice=l_extendedprice+? where l_suppkey in +(select ps_suppkey from partsupp where ps_partkey in (1,2,3)); +"; +select 5373 as count, 136458704.22 as old_sum; +count old_sum +5373 136458704.22 +set @a1=20; +execute stmt using @a1; +select ROUND(sum(l_extendedprice),2), 5373 as count, +(136458704.22+20*5373) as 'old_sum+20*count' + from lineitem where l_suppkey in +(select ps_suppkey from partsupp where ps_partkey in (1,2,3)); +ROUND(sum(l_extendedprice),2) count old_sum+20*count +136566164.22 5373 136566164.22 +set @a2=10; +execute stmt using @a2; +select ROUND(sum(l_extendedprice),2), 5373 as count, +(136458704.22+30*5373) as 'old_sum+30*count' + from lineitem where l_suppkey in +(select ps_suppkey from partsupp where ps_partkey in (1,2,3)); +ROUND(sum(l_extendedprice),2) count old_sum+30*count +136619894.22 5373 136619894.22 +execute stmt using -(@a1+@a2); +select ROUND(sum(l_extendedprice),2), 5373 as count, +136458704.22 as old_sum from lineitem where l_suppkey in +(select ps_suppkey from partsupp where ps_partkey in (1,2,3)); +ROUND(sum(l_extendedprice),2) count old_sum +136458704.22 5373 136458704.22 +deallocate prepare stmt; +# LooseScan SP +# ============ +create procedure p(d int) +update lineitem set l_extendedprice=l_extendedprice+d where l_suppkey in +(select ps_suppkey from partsupp where ps_partkey in (1,2,3)); +select 5373 as count, 136458704.22 as old_sum; +count old_sum +5373 136458704.22 +call p(10); +select ROUND(sum(l_extendedprice),2), 5373 as count, +(136458704.22+10*5373) as 'old_sum+10*count' + from lineitem where l_suppkey in +(select ps_suppkey from partsupp where ps_partkey in (1,2,3)); +ROUND(sum(l_extendedprice),2) count old_sum+10*count +136512434.22 5373 136512434.22 +call p(20); +select ROUND(sum(l_extendedprice),2), 5373 as count, +(136458704.22+30*5373) as 'old_sum+30*count' + from lineitem where l_suppkey in +(select ps_suppkey from partsupp where ps_partkey in (1,2,3)); +ROUND(sum(l_extendedprice),2) count old_sum+30*count +136619894.22 5373 136619894.22 +call p(-(10+20)); +select ROUND(sum(l_extendedprice),2), 5373 as count, +136458704.22 as old_sum from lineitem where l_suppkey in +(select ps_suppkey from partsupp where ps_partkey in (1,2,3)); +ROUND(sum(l_extendedprice),2) count old_sum +136458704.22 5373 136458704.22 +drop procedure p; +set @@optimizer_switch=@tmp_optimizer_switch; +drop index i_l_sup_part on lineitem; +drop index i_ps_sup_part on partsupp; +# DuplicateWeedout +# ================ +set @tmp_optimizer_switch= @@optimizer_switch; +set optimizer_switch='materialization=off'; +analyze table lineitem; +Table Op Msg_type Msg_text +dbt3_s001.lineitem analyze status Engine-independent statistics collected +dbt3_s001.lineitem analyze status Table is already up to date +analyze table orders; +Table Op Msg_type Msg_text +dbt3_s001.orders analyze status Engine-independent statistics collected +dbt3_s001.orders analyze status OK +explain +select count(*) from lineitem where l_partkey in ( +select ps_partkey +from partsupp join lineitem on ps_partkey=l_partkey +where ps_suppkey in ( +select s_suppkey from supplier where s_suppkey < 2 +) +); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY supplier range PRIMARY PRIMARY 4 NULL 1 Using where; Using index; Start temporary +1 PRIMARY partsupp ref PRIMARY,i_ps_partkey,i_ps_suppkey i_ps_suppkey 4 dbt3_s001.supplier.s_suppkey 70 Using where +1 PRIMARY lineitem ref i_l_suppkey_partkey,i_l_partkey i_l_partkey 5 dbt3_s001.partsupp.ps_partkey 30 Using index +1 PRIMARY lineitem ref i_l_suppkey_partkey,i_l_partkey i_l_partkey 5 dbt3_s001.partsupp.ps_partkey 30 Using index; End temporary +explain format=json +select count(*) from lineitem where l_partkey in ( +select ps_partkey +from partsupp join lineitem on ps_partkey=l_partkey +where ps_suppkey in ( +select s_suppkey from supplier where s_suppkey < 2 +) +); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "nested_loop": [ + { + "duplicates_removal": [ + { + "table": { + "table_name": "supplier", + "access_type": "range", + "possible_keys": ["PRIMARY"], + "key": "PRIMARY", + "key_length": "4", + "used_key_parts": ["s_suppkey"], + "rows": 1, + "filtered": 100, + "attached_condition": "supplier.s_suppkey < 2", + "using_index": true + } + }, + { + "table": { + "table_name": "partsupp", + "access_type": "ref", + "possible_keys": ["PRIMARY", "i_ps_partkey", "i_ps_suppkey"], + "key": "i_ps_suppkey", + "key_length": "4", + "used_key_parts": ["ps_suppkey"], + "ref": ["dbt3_s001.supplier.s_suppkey"], + "rows": 70, + "filtered": 100, + "attached_condition": "partsupp.ps_partkey is not null" + } + }, + { + "table": { + "table_name": "lineitem", + "access_type": "ref", + "possible_keys": ["i_l_suppkey_partkey", "i_l_partkey"], + "key": "i_l_partkey", + "key_length": "5", + "used_key_parts": ["l_partkey"], + "ref": ["dbt3_s001.partsupp.ps_partkey"], + "rows": 30, + "filtered": 100, + "using_index": true + } + }, + { + "table": { + "table_name": "lineitem", + "access_type": "ref", + "possible_keys": ["i_l_suppkey_partkey", "i_l_partkey"], + "key": "i_l_partkey", + "key_length": "5", + "used_key_parts": ["l_partkey"], + "ref": ["dbt3_s001.partsupp.ps_partkey"], + "rows": 30, + "filtered": 100, + "using_index": true + } + } + ] + } + ] + } +} +select count(*) from lineitem where l_partkey in ( +select ps_partkey +from partsupp join lineitem on ps_partkey=l_partkey +where ps_suppkey in ( +select s_suppkey from supplier where s_suppkey < 2 +) +); +count(*) +2126 +select 2126 as count, 53473218.20 as old_sum; +count old_sum +2126 53473218.20 +explain +update lineitem set l_extendedprice=l_extendedprice+10 where l_partkey in ( +select ps_partkey +from partsupp join lineitem on ps_partkey=l_partkey +where ps_suppkey in ( +select s_suppkey from supplier where s_suppkey < 2 +) +); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY supplier range PRIMARY PRIMARY 4 NULL 1 Using where; Using index; Start temporary +1 PRIMARY partsupp ref PRIMARY,i_ps_partkey,i_ps_suppkey i_ps_suppkey 4 dbt3_s001.supplier.s_suppkey 70 Using where +1 PRIMARY lineitem ref i_l_suppkey_partkey,i_l_partkey i_l_partkey 5 dbt3_s001.partsupp.ps_partkey 30 +1 PRIMARY lineitem ref i_l_suppkey_partkey,i_l_partkey i_l_partkey 5 dbt3_s001.partsupp.ps_partkey 30 Using index; End temporary +explain format=json +update lineitem set l_extendedprice=l_extendedprice+10 where l_partkey in ( +select ps_partkey +from partsupp join lineitem on ps_partkey=l_partkey +where ps_suppkey in ( +select s_suppkey from supplier where s_suppkey < 2 +) +); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "nested_loop": [ + { + "duplicates_removal": [ + { + "table": { + "table_name": "supplier", + "access_type": "range", + "possible_keys": ["PRIMARY"], + "key": "PRIMARY", + "key_length": "4", + "used_key_parts": ["s_suppkey"], + "rows": 1, + "filtered": 100, + "attached_condition": "supplier.s_suppkey < 2", + "using_index": true + } + }, + { + "table": { + "table_name": "partsupp", + "access_type": "ref", + "possible_keys": ["PRIMARY", "i_ps_partkey", "i_ps_suppkey"], + "key": "i_ps_suppkey", + "key_length": "4", + "used_key_parts": ["ps_suppkey"], + "ref": ["dbt3_s001.supplier.s_suppkey"], + "rows": 70, + "filtered": 100, + "attached_condition": "partsupp.ps_partkey is not null" + } + }, + { + "table": { + "table_name": "lineitem", + "access_type": "ref", + "possible_keys": ["i_l_suppkey_partkey", "i_l_partkey"], + "key": "i_l_partkey", + "key_length": "5", + "used_key_parts": ["l_partkey"], + "ref": ["dbt3_s001.partsupp.ps_partkey"], + "rows": 30, + "filtered": 100 + } + }, + { + "table": { + "table_name": "lineitem", + "access_type": "ref", + "possible_keys": ["i_l_suppkey_partkey", "i_l_partkey"], + "key": "i_l_partkey", + "key_length": "5", + "used_key_parts": ["l_partkey"], + "ref": ["dbt3_s001.partsupp.ps_partkey"], + "rows": 30, + "filtered": 100, + "using_index": true + } + } + ] + } + ] + } +} +update lineitem set l_extendedprice=l_extendedprice+10 where l_partkey in ( +select ps_partkey +from partsupp join lineitem on ps_partkey=l_partkey +where ps_suppkey in ( +select s_suppkey from supplier where s_suppkey < 2 +) +); +select ROUND(sum(l_extendedprice),2), 2126 as count, +(53473218.20+10*2126) as 'old_sum+10*count' + from lineitem where l_partkey in ( +select ps_partkey +from partsupp join lineitem on ps_partkey=l_partkey +where ps_suppkey in ( +select s_suppkey from supplier where s_suppkey < 2 +) +); +ROUND(sum(l_extendedprice),2) count old_sum+10*count +53494478.20 2126 53494478.20 +update lineitem set l_extendedprice=l_extendedprice-10 where l_partkey in ( +select ps_partkey +from partsupp join lineitem on ps_partkey=l_partkey +where ps_suppkey in ( +select s_suppkey from supplier where s_suppkey < 2 +) +); +select ROUND(sum(l_extendedprice),2), 2126 as count, +53473218.20 as old_sum from lineitem where l_partkey in ( +select ps_partkey +from partsupp join lineitem on ps_partkey=l_partkey +where ps_suppkey in ( +select s_suppkey from supplier where s_suppkey < 2 +) +); +ROUND(sum(l_extendedprice),2) count old_sum +53473218.20 2126 53473218.20 +# DuplicateWeedout PS +# =================== +prepare stmt from " +update lineitem set l_extendedprice=l_extendedprice+? where l_partkey in ( +select ps_partkey +from partsupp join lineitem on ps_partkey=l_partkey +where ps_suppkey in ( +select s_suppkey from supplier where s_suppkey < 2 +) +); +"; +select 2126 as count, 53473218.20 as old_sum; +count old_sum +2126 53473218.20 +set @a1=20; +execute stmt using @a1; +select ROUND(sum(l_extendedprice),2), 2126 as count, +(53473218.20+20*2126) as 'old_sum+20*count' + from lineitem where l_partkey in ( +select ps_partkey +from partsupp join lineitem on ps_partkey=l_partkey +where ps_suppkey in ( +select s_suppkey from supplier where s_suppkey < 2 +) +); +ROUND(sum(l_extendedprice),2) count old_sum+20*count +53515738.20 2126 53515738.20 +set @a2=10; +execute stmt using @a2; +select ROUND(sum(l_extendedprice),2), 2126 as count, +(53473218.20+30*2126) as 'old_sum+30*count' + from lineitem where l_partkey in ( +select ps_partkey +from partsupp join lineitem on ps_partkey=l_partkey +where ps_suppkey in ( +select s_suppkey from supplier where s_suppkey < 2 +) +); +ROUND(sum(l_extendedprice),2) count old_sum+30*count +53536998.20 2126 53536998.20 +execute stmt using -(@a1+@a2); +select ROUND(sum(l_extendedprice),2), 2126 as count, +53473218.20 as old_sum from lineitem where l_partkey in ( +select ps_partkey +from partsupp join lineitem on ps_partkey=l_partkey +where ps_suppkey in ( +select s_suppkey from supplier where s_suppkey < 2 +) +); +ROUND(sum(l_extendedprice),2) count old_sum +53473218.20 2126 53473218.20 +deallocate prepare stmt; +# DuplicateWeedout SP +# =================== +create procedure p(d int) +update lineitem set l_extendedprice=l_extendedprice+d where l_partkey in ( +select ps_partkey +from partsupp join lineitem on ps_partkey=l_partkey +where ps_suppkey in ( +select s_suppkey from supplier where s_suppkey < 2 +) +); +select 2126 as count, 53473218.20 as old_sum; +count old_sum +2126 53473218.20 +call p(10); +select ROUND(sum(l_extendedprice),2), 2126 as count, +(53473218.20+10*2126) as 'old_sum+10*count' + from lineitem where l_partkey in ( +select ps_partkey +from partsupp join lineitem on ps_partkey=l_partkey +where ps_suppkey in ( +select s_suppkey from supplier where s_suppkey < 2 +) +); +ROUND(sum(l_extendedprice),2) count old_sum+10*count +53494478.20 2126 53494478.20 +call p(20); +select ROUND(sum(l_extendedprice),2), 2126 as count, +(53473218.20+30*2126) as 'old_sum+30*count' + from lineitem where l_partkey in ( +select ps_partkey +from partsupp join lineitem on ps_partkey=l_partkey +where ps_suppkey in ( +select s_suppkey from supplier where s_suppkey < 2 +) +); +ROUND(sum(l_extendedprice),2) count old_sum+30*count +53536998.20 2126 53536998.20 +call p(-(10+20)); +select ROUND(sum(l_extendedprice),2), 2126 as count, +53473218.20 as old_sum from lineitem where l_partkey in ( +select ps_partkey +from partsupp join lineitem on ps_partkey=l_partkey +where ps_suppkey in ( +select s_suppkey from supplier where s_suppkey < 2 +) +); +ROUND(sum(l_extendedprice),2) count old_sum +53473218.20 2126 53473218.20 +drop procedure p; +set @@optimizer_switch=@tmp_optimizer_switch; DROP DATABASE dbt3_s001; diff --git a/mysql-test/main/update_single_to_multi.test b/mysql-test/main/update_single_to_multi.test index bf89a6c..53c01bd 100644 --- a/mysql-test/main/update_single_to_multi.test +++ b/mysql-test/main/update_single_to_multi.test @@ -548,4 +548,242 @@ update orders set o_totalprice = o_totalprice+50 where $c11; eval select o_orderkey, o_totalprice from orders where $c11; +--echo # LooseScan +--echo # ========= + +set @tmp_optimizer_switch= @@optimizer_switch; +set optimizer_switch='materialization=off'; + +create index i_l_sup_part on lineitem(l_suppkey, l_partkey); +create index i_ps_sup_part on partsupp(ps_suppkey, ps_partkey); + +analyze table lineitem; +analyze table partsupp; + +let $c12 = l_suppkey in + (select ps_suppkey from partsupp where ps_partkey in (1,2,3)); + +eval +explain +select count(*) from lineitem where $c12; +eval +explain format=json +select count(*) from lineitem where $c12; +eval +select count(*) from lineitem where $c12; +let $l_count = + query_get_value('select count(*) as a from lineitem where $c12;', a, 1); +let $l_old_sum = + query_get_value('select ROUND(sum(l_extendedprice),2) as a + from lineitem where $c12;', a, 1 + ); +eval select $l_count as count, $l_old_sum as old_sum; + +eval +explain +update lineitem set l_extendedprice=l_extendedprice+10 where $c12; +eval +explain format=json +update lineitem set l_extendedprice=l_extendedprice+10 where $c12; +eval +update lineitem set l_extendedprice=l_extendedprice+10 where $c12; +eval +select ROUND(sum(l_extendedprice),2), $l_count as count, + ($l_old_sum+10*$l_count) as 'old_sum+10*count' + from lineitem where $c12; + +eval +update lineitem set l_extendedprice=l_extendedprice-10 where $c12; +eval +select ROUND(sum(l_extendedprice),2), $l_count as count, + $l_old_sum as old_sum from lineitem where $c12; + + +--echo # LooseScan PS +--echo # ============ + +eval +prepare stmt from " +update lineitem set l_extendedprice=l_extendedprice+? where $c12; +"; + +let $l_count = query_get_value('select count(*) as a + from lineitem where $c12;', a, 1 ); +let $l_old_sum = query_get_value('select ROUND(sum(l_extendedprice),2) as a + from lineitem where $c12;', a, 1 ); +eval select $l_count as count, $l_old_sum as old_sum; +eval +set @a1=20; +execute stmt using @a1; +eval +select ROUND(sum(l_extendedprice),2), $l_count as count, + ($l_old_sum+20*$l_count) as 'old_sum+20*count' + from lineitem where $c12; +set @a2=10; +execute stmt using @a2; +eval +select ROUND(sum(l_extendedprice),2), $l_count as count, + ($l_old_sum+30*$l_count) as 'old_sum+30*count' + from lineitem where $c12; +execute stmt using -(@a1+@a2); +eval +select ROUND(sum(l_extendedprice),2), $l_count as count, + $l_old_sum as old_sum from lineitem where $c12; + +deallocate prepare stmt; + +--echo # LooseScan SP +--echo # ============ + +eval +create procedure p(d int) +update lineitem set l_extendedprice=l_extendedprice+d where $c12; + +let $l_count = query_get_value('select count(*) as a + from lineitem where $c12;', a, 1 ); +let $l_old_sum = query_get_value('select ROUND(sum(l_extendedprice),2) as a + from lineitem where $c12;', a, 1 ); +eval select $l_count as count, $l_old_sum as old_sum; +eval +call p(10); +eval +select ROUND(sum(l_extendedprice),2), $l_count as count, + ($l_old_sum+10*$l_count) as 'old_sum+10*count' + from lineitem where $c12; +call p(20); +eval +select ROUND(sum(l_extendedprice),2), $l_count as count, + ($l_old_sum+30*$l_count) as 'old_sum+30*count' + from lineitem where $c12; +call p(-(10+20)); +eval +select ROUND(sum(l_extendedprice),2), $l_count as count, + $l_old_sum as old_sum from lineitem where $c12; + +drop procedure p; +set @@optimizer_switch=@tmp_optimizer_switch; + +drop index i_l_sup_part on lineitem; +drop index i_ps_sup_part on partsupp; + + +--echo # DuplicateWeedout +--echo # ================ + +set @tmp_optimizer_switch= @@optimizer_switch; +set optimizer_switch='materialization=off'; + +analyze table lineitem; +analyze table orders; + +let $c13 = l_partkey in ( + select ps_partkey + from partsupp join lineitem on ps_partkey=l_partkey + where ps_suppkey in ( + select s_suppkey from supplier where s_suppkey < 2 + ) +); + +eval +explain +select count(*) from lineitem where $c13; +eval +explain format=json +select count(*) from lineitem where $c13; +eval +select count(*) from lineitem where $c13; + +let $l_count = query_get_value('select count(*) as a + from lineitem where $c13;', a, 1 ); +let $l_old_sum = query_get_value('select ROUND(sum(l_extendedprice),2) as a + from lineitem where $c13;', a, 1 ); +eval select $l_count as count, $l_old_sum as old_sum; + +eval +explain +update lineitem set l_extendedprice=l_extendedprice+10 where $c13; +eval +explain format=json +update lineitem set l_extendedprice=l_extendedprice+10 where $c13; +eval +update lineitem set l_extendedprice=l_extendedprice+10 where $c13; +eval +select ROUND(sum(l_extendedprice),2), $l_count as count, + ($l_old_sum+10*$l_count) as 'old_sum+10*count' + from lineitem where $c13; + +eval +update lineitem set l_extendedprice=l_extendedprice-10 where $c13; +eval +select ROUND(sum(l_extendedprice),2), $l_count as count, + $l_old_sum as old_sum from lineitem where $c13; + + +--echo # DuplicateWeedout PS +--echo # =================== + +eval +prepare stmt from " +update lineitem set l_extendedprice=l_extendedprice+? where $c13; +"; + +let $l_count = + query_get_value('select count(*) as a + from lineitem where $c13;', a, 1 ); +let $l_old_sum = + query_get_value('select ROUND(sum(l_extendedprice),2) as a + from lineitem where $c13;', a, 1); +eval select $l_count as count, $l_old_sum as old_sum; +eval +set @a1=20; +execute stmt using @a1; +eval +select ROUND(sum(l_extendedprice),2), $l_count as count, + ($l_old_sum+20*$l_count) as 'old_sum+20*count' + from lineitem where $c13; +set @a2=10; +execute stmt using @a2; +eval +select ROUND(sum(l_extendedprice),2), $l_count as count, + ($l_old_sum+30*$l_count) as 'old_sum+30*count' + from lineitem where $c13; +execute stmt using -(@a1+@a2); +eval +select ROUND(sum(l_extendedprice),2), $l_count as count, + $l_old_sum as old_sum from lineitem where $c13; + +deallocate prepare stmt; + +--echo # DuplicateWeedout SP +--echo # =================== + +eval +create procedure p(d int) +update lineitem set l_extendedprice=l_extendedprice+d where $c13; + +let $l_count = query_get_value('select count(*) as a + from lineitem where $c13;', a, 1 ); +let $l_old_sum = query_get_value('select ROUND(sum(l_extendedprice),2) as a + from lineitem where $c13;', a, 1 ); +eval select $l_count as count, $l_old_sum as old_sum; +eval +call p(10); + +eval +select ROUND(sum(l_extendedprice),2), $l_count as count, + ($l_old_sum+10*$l_count) as 'old_sum+10*count' + from lineitem where $c13; +call p(20); +eval +select ROUND(sum(l_extendedprice),2), $l_count as count, + ($l_old_sum+30*$l_count) as 'old_sum+30*count' + from lineitem where $c13; +call p(-(10+20)); +eval +select ROUND(sum(l_extendedprice),2), $l_count as count, + $l_old_sum as old_sum from lineitem where $c13; + +drop procedure p; +set @@optimizer_switch=@tmp_optimizer_switch; + DROP DATABASE dbt3_s001; diff --git a/mysql-test/main/update_use_source.result b/mysql-test/main/update_use_source.result index e4ba0e9..1e9c839 100644 --- a/mysql-test/main/update_use_source.result +++ b/mysql-test/main/update_use_source.result @@ -1,4 +1,17 @@ -create table t1 (old_c1 integer, old_c2 integer,c1 integer, c2 integer, c3 integer) engine=InnoDB STATS_PERSISTENT=0; +set @save_default_engine=@@default_storage_engine; +set global innodb_stats_persistent=1; +set default_storage_engine=InnoDB; +create table t1 (old_c1 integer, +old_c2 integer, +c1 integer, +c2 integer, +c3 integer); +insert into t1 select c1+10,c2,c3+10, NULL, NULL from t1; +insert into t1 select c1+20,c2+1,c3+20, NULL, NULL from t1; +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK create view v1 as select * from t1 where c2=2; create trigger trg_t1 before update on t1 for each row begin @@ -6,15 +19,14 @@ set new.old_c1=old.c1; set new.old_c2=old.c2; end; / -insert into t1(c1,c2,c3) values (1,1,1); -insert into t1(c1,c2,c3) values (1,2,2); -insert into t1(c1,c2,c3) values (1,3,3); -insert into t1(c1,c2,c3) values (2,1,4); -insert into t1(c1,c2,c3) values (2,2,5); -insert into t1(c1,c2,c3) values (2,3,6); -insert into t1(c1,c2,c3) values (2,4,7); -insert into t1(c1,c2,c3) values (2,5,8); -commit; +insert into t1(c1,c2,c3) +values (1,1,1), (1,2,2), (1,3,3), +(2,1,4), (2,2,5), (2,3,6), +(2,4,7), (2,5,8); +analyze table t1; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK select * from t1; old_c1 old_c2 c1 c2 c3 NULL NULL 1 1 1 @@ -25,18 +37,20 @@ NULL NULL 2 2 5 NULL NULL 2 3 6 NULL NULL 2 4 7 NULL NULL 2 5 8 -Test without any index +create table tmp as select * from t1; +# Test without any index # -# Update a with value from subquery on the same table, no search clause. ALL access +# Update with value from subquery on the same table # -start transaction; -update t1 -set c1=(select a.c3 -from t1 a -where a.c3 = t1.c3); +explain update t1 set c1=(select a.c3 from t1 a where a.c3 = t1.c3); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 8 Using where +update t1 set c1=(select a.c3 from t1 a where a.c3 = t1.c3); affected rows: 8 info: Rows matched: 8 Changed: 8 Warnings: 0 -select concat(old_c1,'->',c1),c3, case when c1 != old_c1 then '*' else ' ' end "Changed" from t1 ; +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; concat(old_c1,'->',c1) c3 Changed 1->1 1 1->2 2 * @@ -46,20 +60,26 @@ concat(old_c1,'->',c1) c3 Changed 2->6 6 * 2->7 7 * 2->8 8 * -rollback; +truncate table t1; +insert into t1 select * from tmp; # -# Update with search clause on the same table +# Update with EXISTS subquery over the updated table +# in WHERE + possibly sargable condition # -start transaction; -update t1 -set c1=10 +explain update t1 set c1=10 where c1 <2 -and exists (select 'X' - from t1 a -where a.c1 = t1.c1); +and exists (select 'X' from t1 a where a.c1 = t1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ALL NULL NULL NULL NULL 8 +update t1 set c1=10 +where c1 <2 +and exists (select 'X' from t1 a where a.c1 = t1.c1); affected rows: 3 info: Rows matched: 3 Changed: 3 Warnings: 0 -select concat(old_c1,'->',c1),c3, case when c1 != old_c1 then '*' else ' ' end "Changed" from t1 ; +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; concat(old_c1,'->',c1) c3 Changed 1->10 1 * 1->10 2 * @@ -69,20 +89,24 @@ NULL 5 NULL 6 NULL 7 NULL 8 -rollback; +truncate table t1; +insert into t1 select * from tmp; # -# Update via RANGE or INDEX access if an index or a primary key exists +# Update with EXISTS subquery over the updated table +# in WHERE + non-sargable condition # -explain update t1 set c1=0 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 > 3; +explain update t1 set c1=c1+10 +where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 >= 3; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where 1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 2 MATERIALIZED a ALL NULL NULL NULL NULL 8 -start transaction; -update t1 set c1=c1+10 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 >= 3; +update t1 set c1=c1+10 +where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 >= 3; affected rows: 4 info: Rows matched: 4 Changed: 4 Warnings: 0 -select concat(old_c1,'->',c1),c3, case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; concat(old_c1,'->',c1) c3 Changed NULL 1 NULL 2 @@ -92,13 +116,25 @@ NULL 5 2->12 6 * 2->12 7 * 2->12 8 * -rollback; +truncate table t1; +insert into t1 select * from tmp; # # Update with order by # -start transaction; -update t1 set c1=c1+10 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 >= 3 order by c2; -select concat(old_c1,'->',c1),c3, case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +explain update t1 set c1=c1+10 +where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 order by c2; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where; Using filesort +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ALL NULL NULL NULL NULL 8 +update t1 set c1=c1+10 +where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 order by c2; +affected rows: 4 +info: Rows matched: 4 Changed: 4 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; concat(old_c1,'->',c1) c3 Changed NULL 1 NULL 2 @@ -108,18 +144,22 @@ NULL 5 2->12 6 * 2->12 7 * 2->12 8 * -rollback; +truncate table t1; +insert into t1 select * from tmp; # -Update using a view in subquery +# Update with a reference to view in subquery # -start transaction; -update t1 -set c1=c1 +(select max(a.c2) -from v1 a -where a.c1 = t1.c1) ; +explain update t1 set c1=c1 +(select max(a.c2) from v1 a +where a.c1 = t1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 +2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 8 Using where +update t1 set c1=c1 +(select max(a.c2) from v1 a +where a.c1 = t1.c1); affected rows: 8 info: Rows matched: 8 Changed: 8 Warnings: 0 -select concat(old_c1,'->',c1),c3, case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; concat(old_c1,'->',c1) c3 Changed 1->3 1 * 1->3 2 * @@ -129,19 +169,22 @@ concat(old_c1,'->',c1) c3 Changed 2->4 6 * 2->4 7 * 2->4 8 * -rollback; +truncate table t1; +insert into t1 select * from tmp; # -# Update throw a view +# Update view # -start transaction; -update v1 -set c1=c1 + (select max(a.c2) -from t1 a -where a.c1 = v1.c1) +10 -where c3 > 3; +explain update v1 set c1=c1 + (select max(a.c2) from t1 a +where a.c1 = v1.c1) +10 where c3 > 3; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 8 Using where +update v1 set c1=c1 + (select max(a.c2) from t1 a +where a.c1 = v1.c1) +10 where c3 > 3; affected rows: 1 info: Rows matched: 1 Changed: 1 Warnings: 0 -select concat(old_c1,'->',c1),c3, case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; concat(old_c1,'->',c1) c3 Changed NULL 1 NULL 2 @@ -151,20 +194,24 @@ NULL 4 NULL 6 NULL 7 NULL 8 -rollback; +truncate table t1; +insert into t1 select * from tmp; # -# Update through a view and using the view in subquery +# Update view with reference to the same view in subquery # -start transaction; -update v1 -set c1=c1 + 1 +explain update v1 set c1=c1 + 1 +where c1 <2 +and exists (select 'X' from v1 a where a.c1 = v1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where +2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 8 Using where +update v1 set c1=c1 + 1 where c1 <2 -and exists (select 'X' - from v1 a -where a.c1 = v1.c1); +and exists (select 'X' from v1 a where a.c1 = v1.c1); affected rows: 1 info: Rows matched: 1 Changed: 1 Warnings: 0 -select concat(old_c1,'->',c1),c3, case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; concat(old_c1,'->',c1) c3 Changed NULL 1 1->2 2 * @@ -174,22 +221,25 @@ NULL 5 NULL 6 NULL 7 NULL 8 -rollback; +truncate table t1; +insert into t1 select * from tmp; # -# Update through a view and using the view in subquery +# Update view with EXISTS and reference to the same view in subquery # -start transaction; +explain update v1 +set c1=(select max(a.c1)+10 from v1 a where a.c1 = v1.c1) +where c1 <10 and exists (select 'X' from v1 a where a.c2 = v1.c2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where +3 MATERIALIZED t1 ALL NULL NULL NULL NULL 8 Using where +2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 8 Using where update v1 -set c1=(select max(a.c1)+10 -from v1 a -where a.c1 = v1.c1) -where c1 <10 -and exists (select 'X' - from v1 a -where a.c2 = v1.c2); +set c1=(select max(a.c1)+10 from v1 a where a.c1 = v1.c1) +where c1 <10 and exists (select 'X' from v1 a where a.c2 = v1.c2); affected rows: 2 info: Rows matched: 2 Changed: 2 Warnings: 0 -select concat(old_c1,'->',c1),c3, case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; concat(old_c1,'->',c1) c3 Changed NULL 1 1->11 2 * @@ -199,16 +249,18 @@ NULL 4 NULL 6 NULL 7 NULL 8 -rollback; +truncate table t1; +insert into t1 select * from tmp; # -# Update of the index or primary key (c3) +# Update with IN predicand over the updated table in WHERE # -start transaction; -explain update t1 set c3=c3+10 where c2 in (select distinct a.c2 from t1 a where t1.c1=a.c1); +explain update t1 set c3=c3+10 +where c2 in (select distinct a.c2 from t1 a where t1.c1=a.c1); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 8 1 PRIMARY a ALL NULL NULL NULL NULL 8 Using where; FirstMatch(t1) -update t1 set c3=c3+10 where c2 in (select distinct a.c2 from t1 a where t1.c1=a.c1); +update t1 set c3=c3+10 +where c2 in (select distinct a.c2 from t1 a where t1.c1=a.c1); affected rows: 8 info: Rows matched: 8 Changed: 8 Warnings: 0 select c3 from t1; @@ -221,19 +273,22 @@ c3 16 17 18 -rollback; +truncate table t1; +insert into t1 select * from tmp; # -# update with a limit +# Update with a limit # -start transaction; +explain update t1 +set c1=(select a.c3 from t1 a where a.c3 = t1.c3) limit 2; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 8 Using where update t1 -set c1=(select a.c3 -from t1 a -where a.c3 = t1.c3) -limit 2; +set c1=(select a.c3 from t1 a where a.c3 = t1.c3) limit 2; affected rows: 2 info: Rows matched: 2 Changed: 2 Warnings: 0 -select concat(old_c1,'->',c1),c3, case when c1 != old_c1 then '*' else ' ' end "Changed" from t1 ; +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; concat(old_c1,'->',c1) c3 Changed 1->1 1 1->2 2 * @@ -243,19 +298,18 @@ NULL 5 NULL 6 NULL 7 NULL 8 -rollback; +truncate table t1; +insert into t1 select * from tmp; # -# update with a limit and an order by +# Update with a limit and an order by # -start transaction; update t1 -set c1=(select a.c3 -from t1 a -where a.c3 = t1.c3) +set c1=(select a.c3 from t1 a where a.c3 = t1.c3) order by c3 desc limit 2; affected rows: 2 info: Rows matched: 2 Changed: 2 Warnings: 0 -select concat(old_c1,'->',c1),c3, case when c1 != old_c1 then '*' else ' ' end "Changed" from t1 ; +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; concat(old_c1,'->',c1) c3 Changed NULL 1 NULL 2 @@ -265,20 +319,26 @@ NULL 5 NULL 6 2->7 7 * 2->8 8 * -rollback; -Test with an index on updated columns +truncate table t1; +insert into t1 select * from tmp; +# Test with an index on updated columns create index t1_c2 on t1 (c2,c1); +analyze table t1; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK # -# Update a with value from subquery on the same table, no search clause. ALL access +# Update with value from subquery on the same table # -start transaction; -update t1 -set c1=(select a.c3 -from t1 a -where a.c3 = t1.c3); +explain update t1 set c1=(select a.c3 from t1 a where a.c3 = t1.c3); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 8 Using where +update t1 set c1=(select a.c3 from t1 a where a.c3 = t1.c3); affected rows: 8 info: Rows matched: 8 Changed: 8 Warnings: 0 -select concat(old_c1,'->',c1),c3, case when c1 != old_c1 then '*' else ' ' end "Changed" from t1 ; +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; concat(old_c1,'->',c1) c3 Changed 1->1 1 1->2 2 * @@ -288,20 +348,26 @@ concat(old_c1,'->',c1) c3 Changed 2->6 6 * 2->7 7 * 2->8 8 * -rollback; +truncate table t1; +insert into t1 select * from tmp; # -# Update with search clause on the same table +# Update with EXISTS subquery over the updated table +# in WHERE + possibly sargable condition # -start transaction; -update t1 -set c1=10 +explain update t1 set c1=10 where c1 <2 -and exists (select 'X' - from t1 a -where a.c1 = t1.c1); +and exists (select 'X' from t1 a where a.c1 = t1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a index NULL t1_c2 10 NULL 8 Using index +update t1 set c1=10 +where c1 <2 +and exists (select 'X' from t1 a where a.c1 = t1.c1); affected rows: 3 info: Rows matched: 3 Changed: 3 Warnings: 0 -select concat(old_c1,'->',c1),c3, case when c1 != old_c1 then '*' else ' ' end "Changed" from t1 ; +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; concat(old_c1,'->',c1) c3 Changed 1->10 1 * 1->10 2 * @@ -311,20 +377,24 @@ NULL 5 NULL 6 NULL 7 NULL 8 -rollback; +truncate table t1; +insert into t1 select * from tmp; # -# Update via RANGE or INDEX access if an index or a primary key exists +# Update with EXISTS subquery over the updated table +# in WHERE + non-sargable condition # -explain update t1 set c1=0 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 > 3; +explain update t1 set c1=c1+10 +where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 >= 3; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 range t1_c2 t1_c2 5 NULL 2 Using index condition +1 PRIMARY t1 ALL t1_c2 NULL NULL NULL 8 Using where 1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 -2 MATERIALIZED a range t1_c2 t1_c2 5 NULL 2 Using where; Using index -start transaction; -update t1 set c1=c1+10 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 >= 3; +2 MATERIALIZED a range t1_c2 t1_c2 5 NULL 4 Using where; Using index +update t1 set c1=c1+10 +where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 >= 3; affected rows: 4 info: Rows matched: 4 Changed: 4 Warnings: 0 -select concat(old_c1,'->',c1),c3, case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; concat(old_c1,'->',c1) c3 Changed NULL 1 NULL 2 @@ -334,13 +404,25 @@ NULL 5 2->12 6 * 2->12 7 * 2->12 8 * -rollback; +truncate table t1; +insert into t1 select * from tmp; # # Update with order by # -start transaction; -update t1 set c1=c1+10 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 >= 3 order by c2; -select concat(old_c1,'->',c1),c3, case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +explain update t1 set c1=c1+10 +where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 order by c2; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL t1_c2 NULL NULL NULL 8 Using where; Using filesort +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a range t1_c2 t1_c2 5 NULL 4 Using where; Using index +update t1 set c1=c1+10 +where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 order by c2; +affected rows: 4 +info: Rows matched: 4 Changed: 4 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; concat(old_c1,'->',c1) c3 Changed NULL 1 NULL 2 @@ -350,18 +432,22 @@ NULL 5 2->12 6 * 2->12 7 * 2->12 8 * -rollback; +truncate table t1; +insert into t1 select * from tmp; # -Update using a view in subquery +# Update with a reference to view in subquery # -start transaction; -update t1 -set c1=c1 +(select max(a.c2) -from v1 a -where a.c1 = t1.c1) ; +explain update t1 set c1=c1 +(select max(a.c2) from v1 a +where a.c1 = t1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 +2 DEPENDENT SUBQUERY t1 ref t1_c2 t1_c2 10 const,test.t1.c1 1 Using index +update t1 set c1=c1 +(select max(a.c2) from v1 a +where a.c1 = t1.c1); affected rows: 8 info: Rows matched: 8 Changed: 8 Warnings: 0 -select concat(old_c1,'->',c1),c3, case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; concat(old_c1,'->',c1) c3 Changed 1->3 1 * 1->3 2 * @@ -371,19 +457,22 @@ concat(old_c1,'->',c1) c3 Changed 2->4 6 * 2->4 7 * 2->4 8 * -rollback; +truncate table t1; +insert into t1 select * from tmp; # -# Update throw a view +# Update view # -start transaction; -update v1 -set c1=c1 + (select max(a.c2) -from t1 a -where a.c1 = v1.c1) +10 -where c3 > 3; +explain update v1 set c1=c1 + (select max(a.c2) from t1 a +where a.c1 = v1.c1) +10 where c3 > 3; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ref t1_c2 t1_c2 5 const 2 Using where +2 DEPENDENT SUBQUERY a index NULL t1_c2 10 NULL 8 Using where; Using index +update v1 set c1=c1 + (select max(a.c2) from t1 a +where a.c1 = v1.c1) +10 where c3 > 3; affected rows: 1 info: Rows matched: 1 Changed: 1 Warnings: 0 -select concat(old_c1,'->',c1),c3, case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; concat(old_c1,'->',c1) c3 Changed NULL 1 NULL 2 @@ -393,20 +482,24 @@ NULL 4 NULL 6 NULL 7 NULL 8 -rollback; +truncate table t1; +insert into t1 select * from tmp; # -# Update through a view and using the view in subquery +# Update view with reference to the same view in subquery # -start transaction; -update v1 -set c1=c1 + 1 +explain update v1 set c1=c1 + 1 +where c1 <2 +and exists (select 'X' from v1 a where a.c1 = v1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 range t1_c2 t1_c2 10 NULL 1 Using index condition; Using where +2 MATERIALIZED t1 ref t1_c2 t1_c2 5 const 2 Using index +update v1 set c1=c1 + 1 where c1 <2 -and exists (select 'X' - from v1 a -where a.c1 = v1.c1); +and exists (select 'X' from v1 a where a.c1 = v1.c1); affected rows: 1 info: Rows matched: 1 Changed: 1 Warnings: 0 -select concat(old_c1,'->',c1),c3, case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; concat(old_c1,'->',c1) c3 Changed NULL 1 1->2 2 * @@ -416,22 +509,25 @@ NULL 5 NULL 6 NULL 7 NULL 8 -rollback; +truncate table t1; +insert into t1 select * from tmp; # -# Update through a view and using the view in subquery +# Update view with EXISTS and reference to the same view in subquery # -start transaction; +explain update v1 +set c1=(select max(a.c1)+10 from v1 a where a.c1 = v1.c1) +where c1 <10 and exists (select 'X' from v1 a where a.c2 = v1.c2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 range t1_c2 t1_c2 10 NULL 2 Using index condition +3 MATERIALIZED t1 ref t1_c2 t1_c2 5 const 2 Using index +2 DEPENDENT SUBQUERY t1 ref t1_c2 t1_c2 10 const,test.t1.c1 1 Using index update v1 -set c1=(select max(a.c1)+10 -from v1 a -where a.c1 = v1.c1) -where c1 <10 -and exists (select 'X' - from v1 a -where a.c2 = v1.c2); +set c1=(select max(a.c1)+10 from v1 a where a.c1 = v1.c1) +where c1 <10 and exists (select 'X' from v1 a where a.c2 = v1.c2); affected rows: 2 info: Rows matched: 2 Changed: 2 Warnings: 0 -select concat(old_c1,'->',c1),c3, case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; concat(old_c1,'->',c1) c3 Changed NULL 1 1->11 2 * @@ -441,16 +537,18 @@ NULL 4 NULL 6 NULL 7 NULL 8 -rollback; +truncate table t1; +insert into t1 select * from tmp; # -# Update of the index or primary key (c3) +# Update with IN predicand over the updated table in WHERE # -start transaction; -explain update t1 set c3=c3+10 where c2 in (select distinct a.c2 from t1 a where t1.c1=a.c1); +explain update t1 set c3=c3+10 +where c2 in (select distinct a.c2 from t1 a where t1.c1=a.c1); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL t1_c2 NULL NULL NULL 8 Using where 1 PRIMARY a ref t1_c2 t1_c2 10 test.t1.c2,test.t1.c1 1 Using index; FirstMatch(t1) -update t1 set c3=c3+10 where c2 in (select distinct a.c2 from t1 a where t1.c1=a.c1); +update t1 set c3=c3+10 +where c2 in (select distinct a.c2 from t1 a where t1.c1=a.c1); affected rows: 8 info: Rows matched: 8 Changed: 8 Warnings: 0 select c3 from t1; @@ -463,19 +561,22 @@ c3 16 17 18 -rollback; +truncate table t1; +insert into t1 select * from tmp; # -# update with a limit +# Update with a limit # -start transaction; +explain update t1 +set c1=(select a.c3 from t1 a where a.c3 = t1.c3) limit 2; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 8 Using where update t1 -set c1=(select a.c3 -from t1 a -where a.c3 = t1.c3) -limit 2; +set c1=(select a.c3 from t1 a where a.c3 = t1.c3) limit 2; affected rows: 2 info: Rows matched: 2 Changed: 2 Warnings: 0 -select concat(old_c1,'->',c1),c3, case when c1 != old_c1 then '*' else ' ' end "Changed" from t1 ; +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; concat(old_c1,'->',c1) c3 Changed 1->1 1 1->2 2 * @@ -485,19 +586,18 @@ NULL 5 NULL 6 NULL 7 NULL 8 -rollback; +truncate table t1; +insert into t1 select * from tmp; # -# update with a limit and an order by +# Update with a limit and an order by # -start transaction; update t1 -set c1=(select a.c3 -from t1 a -where a.c3 = t1.c3) +set c1=(select a.c3 from t1 a where a.c3 = t1.c3) order by c3 desc limit 2; affected rows: 2 info: Rows matched: 2 Changed: 2 Warnings: 0 -select concat(old_c1,'->',c1),c3, case when c1 != old_c1 then '*' else ' ' end "Changed" from t1 ; +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; concat(old_c1,'->',c1) c3 Changed NULL 1 NULL 2 @@ -507,20 +607,26 @@ NULL 5 NULL 6 2->7 7 * 2->8 8 * -rollback; -Test with an index on updated columns +truncate table t1; +insert into t1 select * from tmp; +# Test with an index on updated columns create index t1_c3 on t1 (c3); +analyze table t1; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK # -# Update a with value from subquery on the same table, no search clause. ALL access +# Update with value from subquery on the same table # -start transaction; -update t1 -set c1=(select a.c3 -from t1 a -where a.c3 = t1.c3); +explain update t1 set c1=(select a.c3 from t1 a where a.c3 = t1.c3); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 +2 DEPENDENT SUBQUERY a ref t1_c3 t1_c3 5 test.t1.c3 1 Using index +update t1 set c1=(select a.c3 from t1 a where a.c3 = t1.c3); affected rows: 8 info: Rows matched: 8 Changed: 8 Warnings: 0 -select concat(old_c1,'->',c1),c3, case when c1 != old_c1 then '*' else ' ' end "Changed" from t1 ; +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; concat(old_c1,'->',c1) c3 Changed 1->1 1 1->2 2 * @@ -530,20 +636,26 @@ concat(old_c1,'->',c1) c3 Changed 2->6 6 * 2->7 7 * 2->8 8 * -rollback; +truncate table t1; +insert into t1 select * from tmp; # -# Update with search clause on the same table +# Update with EXISTS subquery over the updated table +# in WHERE + possibly sargable condition # -start transaction; -update t1 -set c1=10 +explain update t1 set c1=10 where c1 <2 -and exists (select 'X' - from t1 a -where a.c1 = t1.c1); +and exists (select 'X' from t1 a where a.c1 = t1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a index NULL t1_c2 10 NULL 8 Using index +update t1 set c1=10 +where c1 <2 +and exists (select 'X' from t1 a where a.c1 = t1.c1); affected rows: 3 info: Rows matched: 3 Changed: 3 Warnings: 0 -select concat(old_c1,'->',c1),c3, case when c1 != old_c1 then '*' else ' ' end "Changed" from t1 ; +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; concat(old_c1,'->',c1) c3 Changed 1->10 1 * 1->10 2 * @@ -553,20 +665,24 @@ NULL 5 NULL 6 NULL 7 NULL 8 -rollback; +truncate table t1; +insert into t1 select * from tmp; # -# Update via RANGE or INDEX access if an index or a primary key exists +# Update with EXISTS subquery over the updated table +# in WHERE + non-sargable condition # -explain update t1 set c1=0 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 > 3; +explain update t1 set c1=c1+10 +where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 >= 3; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 range t1_c2 t1_c2 5 NULL 2 Using index condition +1 PRIMARY t1 ALL t1_c2 NULL NULL NULL 8 Using where 1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 -2 MATERIALIZED a range t1_c2 t1_c2 5 NULL 2 Using where; Using index -start transaction; -update t1 set c1=c1+10 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 >= 3; +2 MATERIALIZED a range t1_c2 t1_c2 5 NULL 4 Using where; Using index +update t1 set c1=c1+10 +where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 >= 3; affected rows: 4 info: Rows matched: 4 Changed: 4 Warnings: 0 -select concat(old_c1,'->',c1),c3, case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; concat(old_c1,'->',c1) c3 Changed NULL 1 NULL 2 @@ -576,13 +692,25 @@ NULL 5 2->12 6 * 2->12 7 * 2->12 8 * -rollback; +truncate table t1; +insert into t1 select * from tmp; # # Update with order by # -start transaction; -update t1 set c1=c1+10 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 >= 3 order by c2; -select concat(old_c1,'->',c1),c3, case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +explain update t1 set c1=c1+10 +where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 order by c2; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL t1_c2 NULL NULL NULL 8 Using where; Using filesort +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a range t1_c2 t1_c2 5 NULL 4 Using where; Using index +update t1 set c1=c1+10 +where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 order by c2; +affected rows: 4 +info: Rows matched: 4 Changed: 4 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; concat(old_c1,'->',c1) c3 Changed NULL 1 NULL 2 @@ -592,18 +720,22 @@ NULL 5 2->12 6 * 2->12 7 * 2->12 8 * -rollback; +truncate table t1; +insert into t1 select * from tmp; # -Update using a view in subquery +# Update with a reference to view in subquery # -start transaction; -update t1 -set c1=c1 +(select max(a.c2) -from v1 a -where a.c1 = t1.c1) ; +explain update t1 set c1=c1 +(select max(a.c2) from v1 a +where a.c1 = t1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 +2 DEPENDENT SUBQUERY t1 ref t1_c2 t1_c2 10 const,test.t1.c1 1 Using index +update t1 set c1=c1 +(select max(a.c2) from v1 a +where a.c1 = t1.c1); affected rows: 8 info: Rows matched: 8 Changed: 8 Warnings: 0 -select concat(old_c1,'->',c1),c3, case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; concat(old_c1,'->',c1) c3 Changed 1->3 1 * 1->3 2 * @@ -613,19 +745,22 @@ concat(old_c1,'->',c1) c3 Changed 2->4 6 * 2->4 7 * 2->4 8 * -rollback; +truncate table t1; +insert into t1 select * from tmp; # -# Update throw a view +# Update view # -start transaction; -update v1 -set c1=c1 + (select max(a.c2) -from t1 a -where a.c1 = v1.c1) +10 -where c3 > 3; +explain update v1 set c1=c1 + (select max(a.c2) from t1 a +where a.c1 = v1.c1) +10 where c3 > 3; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ref t1_c2,t1_c3 t1_c2 5 const 2 Using where +2 DEPENDENT SUBQUERY a index NULL t1_c2 10 NULL 8 Using where; Using index +update v1 set c1=c1 + (select max(a.c2) from t1 a +where a.c1 = v1.c1) +10 where c3 > 3; affected rows: 1 info: Rows matched: 1 Changed: 1 Warnings: 0 -select concat(old_c1,'->',c1),c3, case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; concat(old_c1,'->',c1) c3 Changed NULL 1 NULL 2 @@ -635,20 +770,24 @@ NULL 4 NULL 6 NULL 7 NULL 8 -rollback; +truncate table t1; +insert into t1 select * from tmp; # -# Update through a view and using the view in subquery +# Update view with reference to the same view in subquery # -start transaction; -update v1 -set c1=c1 + 1 +explain update v1 set c1=c1 + 1 +where c1 <2 +and exists (select 'X' from v1 a where a.c1 = v1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 range t1_c2 t1_c2 10 NULL 1 Using index condition; Using where +2 MATERIALIZED t1 ref t1_c2 t1_c2 5 const 2 Using index +update v1 set c1=c1 + 1 where c1 <2 -and exists (select 'X' - from v1 a -where a.c1 = v1.c1); +and exists (select 'X' from v1 a where a.c1 = v1.c1); affected rows: 1 info: Rows matched: 1 Changed: 1 Warnings: 0 -select concat(old_c1,'->',c1),c3, case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; concat(old_c1,'->',c1) c3 Changed NULL 1 1->2 2 * @@ -658,22 +797,25 @@ NULL 5 NULL 6 NULL 7 NULL 8 -rollback; +truncate table t1; +insert into t1 select * from tmp; # -# Update through a view and using the view in subquery +# Update view with EXISTS and reference to the same view in subquery # -start transaction; +explain update v1 +set c1=(select max(a.c1)+10 from v1 a where a.c1 = v1.c1) +where c1 <10 and exists (select 'X' from v1 a where a.c2 = v1.c2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 range t1_c2 t1_c2 10 NULL 2 Using index condition +3 MATERIALIZED t1 ref t1_c2 t1_c2 5 const 2 Using index +2 DEPENDENT SUBQUERY t1 ref t1_c2 t1_c2 10 const,test.t1.c1 1 Using index update v1 -set c1=(select max(a.c1)+10 -from v1 a -where a.c1 = v1.c1) -where c1 <10 -and exists (select 'X' - from v1 a -where a.c2 = v1.c2); +set c1=(select max(a.c1)+10 from v1 a where a.c1 = v1.c1) +where c1 <10 and exists (select 'X' from v1 a where a.c2 = v1.c2); affected rows: 2 info: Rows matched: 2 Changed: 2 Warnings: 0 -select concat(old_c1,'->',c1),c3, case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; concat(old_c1,'->',c1) c3 Changed NULL 1 1->11 2 * @@ -683,16 +825,18 @@ NULL 4 NULL 6 NULL 7 NULL 8 -rollback; +truncate table t1; +insert into t1 select * from tmp; # -# Update of the index or primary key (c3) +# Update with IN predicand over the updated table in WHERE # -start transaction; -explain update t1 set c3=c3+10 where c2 in (select distinct a.c2 from t1 a where t1.c1=a.c1); +explain update t1 set c3=c3+10 +where c2 in (select distinct a.c2 from t1 a where t1.c1=a.c1); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL t1_c2 NULL NULL NULL 8 Using where 1 PRIMARY a ref t1_c2 t1_c2 10 test.t1.c2,test.t1.c1 1 Using index; FirstMatch(t1) -update t1 set c3=c3+10 where c2 in (select distinct a.c2 from t1 a where t1.c1=a.c1); +update t1 set c3=c3+10 +where c2 in (select distinct a.c2 from t1 a where t1.c1=a.c1); affected rows: 8 info: Rows matched: 8 Changed: 8 Warnings: 0 select c3 from t1; @@ -705,19 +849,22 @@ c3 16 17 18 -rollback; +truncate table t1; +insert into t1 select * from tmp; # -# update with a limit +# Update with a limit # -start transaction; +explain update t1 +set c1=(select a.c3 from t1 a where a.c3 = t1.c3) limit 2; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 +2 DEPENDENT SUBQUERY a ref t1_c3 t1_c3 5 test.t1.c3 1 Using index update t1 -set c1=(select a.c3 -from t1 a -where a.c3 = t1.c3) -limit 2; +set c1=(select a.c3 from t1 a where a.c3 = t1.c3) limit 2; affected rows: 2 info: Rows matched: 2 Changed: 2 Warnings: 0 -select concat(old_c1,'->',c1),c3, case when c1 != old_c1 then '*' else ' ' end "Changed" from t1 ; +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; concat(old_c1,'->',c1) c3 Changed 1->1 1 1->2 2 * @@ -727,19 +874,18 @@ NULL 5 NULL 6 NULL 7 NULL 8 -rollback; +truncate table t1; +insert into t1 select * from tmp; # -# update with a limit and an order by +# Update with a limit and an order by # -start transaction; update t1 -set c1=(select a.c3 -from t1 a -where a.c3 = t1.c3) +set c1=(select a.c3 from t1 a where a.c3 = t1.c3) order by c3 desc limit 2; affected rows: 2 info: Rows matched: 2 Changed: 2 Warnings: 0 -select concat(old_c1,'->',c1),c3, case when c1 != old_c1 then '*' else ' ' end "Changed" from t1 ; +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; concat(old_c1,'->',c1) c3 Changed NULL 1 NULL 2 @@ -749,21 +895,27 @@ NULL 5 NULL 6 2->7 7 * 2->8 8 * -rollback; -Test with a primary key on updated columns +truncate table t1; +insert into t1 select * from tmp; +# Test with a primary key on updated columns drop index t1_c3 on t1; alter table t1 add primary key (c3); +analyze table t1; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK # -# Update a with value from subquery on the same table, no search clause. ALL access +# Update with value from subquery on the same table # -start transaction; -update t1 -set c1=(select a.c3 -from t1 a -where a.c3 = t1.c3); +explain update t1 set c1=(select a.c3 from t1 a where a.c3 = t1.c3); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 +2 DEPENDENT SUBQUERY a eq_ref PRIMARY PRIMARY 4 test.t1.c3 1 Using index +update t1 set c1=(select a.c3 from t1 a where a.c3 = t1.c3); affected rows: 8 info: Rows matched: 8 Changed: 8 Warnings: 0 -select concat(old_c1,'->',c1),c3, case when c1 != old_c1 then '*' else ' ' end "Changed" from t1 ; +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; concat(old_c1,'->',c1) c3 Changed 1->1 1 1->2 2 * @@ -773,20 +925,26 @@ concat(old_c1,'->',c1) c3 Changed 2->6 6 * 2->7 7 * 2->8 8 * -rollback; +truncate table t1; +insert into t1 select * from tmp; # -# Update with search clause on the same table +# Update with EXISTS subquery over the updated table +# in WHERE + possibly sargable condition # -start transaction; -update t1 -set c1=10 +explain update t1 set c1=10 where c1 <2 -and exists (select 'X' - from t1 a -where a.c1 = t1.c1); +and exists (select 'X' from t1 a where a.c1 = t1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a index NULL t1_c2 10 NULL 8 Using index +update t1 set c1=10 +where c1 <2 +and exists (select 'X' from t1 a where a.c1 = t1.c1); affected rows: 3 info: Rows matched: 3 Changed: 3 Warnings: 0 -select concat(old_c1,'->',c1),c3, case when c1 != old_c1 then '*' else ' ' end "Changed" from t1 ; +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; concat(old_c1,'->',c1) c3 Changed 1->10 1 * 1->10 2 * @@ -796,20 +954,24 @@ NULL 5 NULL 6 NULL 7 NULL 8 -rollback; +truncate table t1; +insert into t1 select * from tmp; # -# Update via RANGE or INDEX access if an index or a primary key exists +# Update with EXISTS subquery over the updated table +# in WHERE + non-sargable condition # -explain update t1 set c1=0 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 > 3; +explain update t1 set c1=c1+10 +where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 >= 3; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 range t1_c2 t1_c2 5 NULL 2 Using index condition +1 PRIMARY t1 ALL t1_c2 NULL NULL NULL 8 Using where 1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 -2 MATERIALIZED a range t1_c2 t1_c2 5 NULL 2 Using where; Using index -start transaction; -update t1 set c1=c1+10 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 >= 3; +2 MATERIALIZED a range t1_c2 t1_c2 5 NULL 4 Using where; Using index +update t1 set c1=c1+10 +where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 >= 3; affected rows: 4 info: Rows matched: 4 Changed: 4 Warnings: 0 -select concat(old_c1,'->',c1),c3, case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; concat(old_c1,'->',c1) c3 Changed NULL 1 NULL 2 @@ -819,13 +981,25 @@ NULL 5 2->12 6 * 2->12 7 * 2->12 8 * -rollback; +truncate table t1; +insert into t1 select * from tmp; # # Update with order by # -start transaction; -update t1 set c1=c1+10 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 >= 3 order by c2; -select concat(old_c1,'->',c1),c3, case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +explain update t1 set c1=c1+10 +where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 order by c2; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL t1_c2 NULL NULL NULL 8 Using where; Using filesort +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a range t1_c2 t1_c2 5 NULL 4 Using where; Using index +update t1 set c1=c1+10 +where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 order by c2; +affected rows: 4 +info: Rows matched: 4 Changed: 4 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; concat(old_c1,'->',c1) c3 Changed NULL 1 NULL 2 @@ -835,18 +1009,22 @@ NULL 5 2->12 6 * 2->12 7 * 2->12 8 * -rollback; +truncate table t1; +insert into t1 select * from tmp; # -Update using a view in subquery +# Update with a reference to view in subquery # -start transaction; -update t1 -set c1=c1 +(select max(a.c2) -from v1 a -where a.c1 = t1.c1) ; +explain update t1 set c1=c1 +(select max(a.c2) from v1 a +where a.c1 = t1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 +2 DEPENDENT SUBQUERY t1 ref t1_c2 t1_c2 10 const,test.t1.c1 1 Using index +update t1 set c1=c1 +(select max(a.c2) from v1 a +where a.c1 = t1.c1); affected rows: 8 info: Rows matched: 8 Changed: 8 Warnings: 0 -select concat(old_c1,'->',c1),c3, case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; concat(old_c1,'->',c1) c3 Changed 1->3 1 * 1->3 2 * @@ -856,19 +1034,22 @@ concat(old_c1,'->',c1) c3 Changed 2->4 6 * 2->4 7 * 2->4 8 * -rollback; +truncate table t1; +insert into t1 select * from tmp; # -# Update throw a view +# Update view # -start transaction; -update v1 -set c1=c1 + (select max(a.c2) -from t1 a -where a.c1 = v1.c1) +10 -where c3 > 3; +explain update v1 set c1=c1 + (select max(a.c2) from t1 a +where a.c1 = v1.c1) +10 where c3 > 3; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 range PRIMARY,t1_c2 PRIMARY 4 NULL 5 Using where +2 DEPENDENT SUBQUERY a index NULL t1_c2 10 NULL 8 Using where; Using index +update v1 set c1=c1 + (select max(a.c2) from t1 a +where a.c1 = v1.c1) +10 where c3 > 3; affected rows: 1 info: Rows matched: 1 Changed: 1 Warnings: 0 -select concat(old_c1,'->',c1),c3, case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; concat(old_c1,'->',c1) c3 Changed NULL 1 NULL 2 @@ -878,20 +1059,24 @@ NULL 4 NULL 6 NULL 7 NULL 8 -rollback; +truncate table t1; +insert into t1 select * from tmp; # -# Update through a view and using the view in subquery +# Update view with reference to the same view in subquery # -start transaction; -update v1 -set c1=c1 + 1 +explain update v1 set c1=c1 + 1 +where c1 <2 +and exists (select 'X' from v1 a where a.c1 = v1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 range t1_c2 t1_c2 10 NULL 1 Using index condition; Using where +2 MATERIALIZED t1 ref t1_c2 t1_c2 5 const 2 Using index +update v1 set c1=c1 + 1 where c1 <2 -and exists (select 'X' - from v1 a -where a.c1 = v1.c1); +and exists (select 'X' from v1 a where a.c1 = v1.c1); affected rows: 1 info: Rows matched: 1 Changed: 1 Warnings: 0 -select concat(old_c1,'->',c1),c3, case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; concat(old_c1,'->',c1) c3 Changed NULL 1 1->2 2 * @@ -901,22 +1086,25 @@ NULL 5 NULL 6 NULL 7 NULL 8 -rollback; +truncate table t1; +insert into t1 select * from tmp; # -# Update through a view and using the view in subquery +# Update view with EXISTS and reference to the same view in subquery # -start transaction; +explain update v1 +set c1=(select max(a.c1)+10 from v1 a where a.c1 = v1.c1) +where c1 <10 and exists (select 'X' from v1 a where a.c2 = v1.c2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 range t1_c2 t1_c2 10 NULL 2 Using index condition +3 MATERIALIZED t1 ref t1_c2 t1_c2 5 const 2 Using index +2 DEPENDENT SUBQUERY t1 ref t1_c2 t1_c2 10 const,test.t1.c1 1 Using index update v1 -set c1=(select max(a.c1)+10 -from v1 a -where a.c1 = v1.c1) -where c1 <10 -and exists (select 'X' - from v1 a -where a.c2 = v1.c2); +set c1=(select max(a.c1)+10 from v1 a where a.c1 = v1.c1) +where c1 <10 and exists (select 'X' from v1 a where a.c2 = v1.c2); affected rows: 2 info: Rows matched: 2 Changed: 2 Warnings: 0 -select concat(old_c1,'->',c1),c3, case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; concat(old_c1,'->',c1) c3 Changed NULL 1 1->11 2 * @@ -926,41 +1114,46 @@ NULL 4 NULL 6 NULL 7 NULL 8 -rollback; +truncate table t1; +insert into t1 select * from tmp; # -# Update of the index or primary key (c3) +# Update with IN predicand over the updated table in WHERE # -start transaction; -explain update t1 set c3=c3+10 where c2 in (select distinct a.c2 from t1 a where t1.c1=a.c1); +explain update t1 set c3=c3+10 +where c2 in (select distinct a.c2 from t1 a where t1.c1=a.c1); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL t1_c2 NULL NULL NULL 8 Using where 1 PRIMARY a ref t1_c2 t1_c2 10 test.t1.c2,test.t1.c1 1 Using index; FirstMatch(t1) -update t1 set c3=c3+10 where c2 in (select distinct a.c2 from t1 a where t1.c1=a.c1); +update t1 set c3=c3+10 +where c2 in (select distinct a.c2 from t1 a where t1.c1=a.c1); affected rows: 8 info: Rows matched: 8 Changed: 8 Warnings: 0 select c3 from t1; c3 11 -14 12 -15 13 +14 +15 16 17 18 -rollback; +truncate table t1; +insert into t1 select * from tmp; # -# update with a limit +# Update with a limit # -start transaction; +explain update t1 +set c1=(select a.c3 from t1 a where a.c3 = t1.c3) limit 2; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 +2 DEPENDENT SUBQUERY a eq_ref PRIMARY PRIMARY 4 test.t1.c3 1 Using index update t1 -set c1=(select a.c3 -from t1 a -where a.c3 = t1.c3) -limit 2; +set c1=(select a.c3 from t1 a where a.c3 = t1.c3) limit 2; affected rows: 2 info: Rows matched: 2 Changed: 2 Warnings: 0 -select concat(old_c1,'->',c1),c3, case when c1 != old_c1 then '*' else ' ' end "Changed" from t1 ; +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; concat(old_c1,'->',c1) c3 Changed 1->1 1 1->2 2 * @@ -970,19 +1163,18 @@ NULL 5 NULL 6 NULL 7 NULL 8 -rollback; +truncate table t1; +insert into t1 select * from tmp; # -# update with a limit and an order by +# Update with a limit and an order by # -start transaction; update t1 -set c1=(select a.c3 -from t1 a -where a.c3 = t1.c3) +set c1=(select a.c3 from t1 a where a.c3 = t1.c3) order by c3 desc limit 2; affected rows: 2 info: Rows matched: 2 Changed: 2 Warnings: 0 -select concat(old_c1,'->',c1),c3, case when c1 != old_c1 then '*' else ' ' end "Changed" from t1 ; +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; concat(old_c1,'->',c1) c3 Changed NULL 1 NULL 2 @@ -992,56 +1184,139 @@ NULL 5 NULL 6 2->7 7 * 2->8 8 * -rollback; +truncate table t1; +insert into t1 select * from tmp; # Update with error "Subquery returns more than 1 row" update t1 set c2=(select c2 from t1); ERROR 21000: Subquery returns more than 1 row -# Update with error "Subquery returns more than 1 row" and order by +select c1,c2,c3 from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +# Update with error "Subquery returns more than 1 row" +# and order by update t1 set c2=(select c2 from t1) order by c3; ERROR 21000: Subquery returns more than 1 row -Duplicate value on update a primary key -start transaction; -update t1 set c3=0 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 >= 3; +select c1,c2,c3 from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +# Duplicate value on update a primary key +update t1 set c3=0 +where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 >= 3; ERROR 23000: Duplicate entry '0' for key 'PRIMARY' -rollback; -Duplicate value on update a primary key with ignore -start transaction; -update ignore t1 set c3=0 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 >= 3; +select c1,c2,c3 from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +truncate table t1; +insert into t1 select * from tmp; +# Duplicate value on update a primary key with ignore +update ignore t1 set c3=0 +where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 >= 3; affected rows: 4 info: Rows matched: 4 Changed: 4 Warnings: 0 -rollback; -Duplicate value on update a primary key and limit -start transaction; -update t1 set c3=0 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 >= 3 limit 2; +select c1,c2,c3 from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 0 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +truncate table t1; +insert into t1 select * from tmp; +# Duplicate value on update a primary key and limit +update t1 set c3=0 +where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 limit 2; ERROR 23000: Duplicate entry '0' for key 'PRIMARY' -rollback; -Duplicate value on update a primary key with ignore and limit -start transaction; -update ignore t1 set c3=0 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 >= 3 limit 2; +select c1,c2,c3 from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +truncate table t1; +insert into t1 select * from tmp; +# Duplicate value on update a primary key with ignore +# and limit +update ignore t1 set c3=0 +where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 limit 2; affected rows: 2 info: Rows matched: 2 Changed: 2 Warnings: 0 -rollback; +select c1,c2,c3 from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 0 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +truncate table t1; +insert into t1 select * from tmp; # Update no rows found -update t1 -set c1=10 -where c1 <2 -and exists (select 'X' - from t1 a -where a.c1 = t1.c1 + 10); +update t1 set c1=10 +where c1 <2 and exists (select 'X' from t1 a where a.c1 = t1.c1 + 10); affected rows: 0 info: Rows matched: 0 Changed: 0 Warnings: 0 +select c1,c2,c3 from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +truncate table t1; +insert into t1 select * from tmp; # Update no rows changed drop trigger trg_t1; -start transaction; -update t1 -set c1=c1 -where c1 <2 -and exists (select 'X' - from t1 a -where a.c1 = t1.c1); +update t1 set c1=c1 +where c1 <2 and exists (select 'X' from t1 a where a.c1 = t1.c1); affected rows: 0 info: Rows matched: 3 Changed: 0 Warnings: 0 -rollback; +select c1,c2,c3 from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +truncate table t1; +insert into t1 select * from tmp; # # Check call of after trigger # @@ -1054,61 +1329,88 @@ SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = msg; end if; end; / -update t1 set c1=2 where c3 in (select distinct a.c3 from t1 a where a.c1=t1.c1); +update t1 set c1=2 +where c3 in (select distinct a.c3 from t1 a where a.c1=t1.c1); ERROR 45000: in after update trigger on 5 +select c1,c2,c3 from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +truncate table t1; +insert into t1 select * from tmp; # # Check update with order by and after trigger # -update t1 set c1=2 where c3 in (select distinct a.c3 from t1 a where a.c1=t1.c1) order by t1.c2; +update t1 set c1=2 +where c3 in (select distinct a.c3 from t1 a where a.c1=t1.c1) +order by t1.c2, t1.c1; ERROR 45000: in after update trigger on 5 +select c1,c2,c3 from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +truncate table t1; +insert into t1 select * from tmp; drop view v1; # # Check update on view with check option # create view v1 as select * from t1 where c2=2 with check option; -start transaction; update v1 set c2=3 where c1=1; ERROR 44000: CHECK OPTION failed `test`.`v1` -rollback; -start transaction; +select c1,c2,c3 from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +truncate table t1; +insert into t1 select * from tmp; update v1 set c2=(select max(c3) from v1) where c1=1; ERROR 44000: CHECK OPTION failed `test`.`v1` -rollback; -start transaction; +select c1,c2,c3 from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +truncate table t1; +insert into t1 select * from tmp; update v1 set c2=(select min(va.c3) from v1 va), c1=0 where c1=1; -rollback; -drop view v1; -drop table t1; -# -# Test with a temporary table -# -create temporary table t1 (c1 integer, c2 integer, c3 integer) engine=InnoDb; -insert into t1(c1,c2,c3) values (1,1,1); -insert into t1(c1,c2,c3) values (1,2,2); -insert into t1(c1,c2,c3) values (1,3,3); -insert into t1(c1,c2,c3) values (2,1,4); -insert into t1(c1,c2,c3) values (2,2,5); -insert into t1(c1,c2,c3) values (2,3,6); -insert into t1(c1,c2,c3) values (2,4,7); -insert into t1(c1,c2,c3) values (2,5,8); -start transaction; -update t1 -set c1=(select a.c2 -from t1 a -where a.c3 = t1.c3) limit 3; -affected rows: 2 -info: Rows matched: 3 Changed: 2 Warnings: 0 -select * from t1 ; +select c1,c2,c3 from t1; c1 c2 c3 +0 2 2 1 1 1 -2 2 2 -3 3 3 +1 3 3 2 1 4 2 2 5 2 3 6 2 4 7 2 5 8 -rollback; +truncate table t1; +insert into t1 select * from tmp; +drop table tmp; +drop view v1; drop table t1; # # Test on dynamic columns (blob) @@ -1117,37 +1419,50 @@ create table assets ( item_name varchar(32) primary key, -- A common attribute for all items dynamic_cols blob -- Dynamic columns will be stored here ); -INSERT INTO assets VALUES ('MariaDB T-shirt', COLUMN_CREATE('color', 'blue', 'size', 'XL')); -INSERT INTO assets VALUES ('Thinkpad Laptop', COLUMN_CREATE('color', 'black', 'price', 500)); -SELECT item_name, COLUMN_GET(dynamic_cols, 'color' as char) AS color FROM assets; +INSERT INTO assets VALUES ('MariaDB T-shirt', +COLUMN_CREATE('color', 'blue', 'size', 'XL')); +INSERT INTO assets VALUES ('Thinkpad Laptop', +COLUMN_CREATE('color', 'black', 'price', 500)); +SELECT item_name, COLUMN_GET(dynamic_cols, 'color' as char) AS color +FROM assets; item_name color MariaDB T-shirt blue Thinkpad Laptop black -UPDATE assets SET dynamic_cols=COLUMN_ADD(dynamic_cols, 'warranty', '3 years') WHERE item_name='Thinkpad Laptop'; -SELECT item_name, COLUMN_GET(dynamic_cols, 'warranty' as char) AS color FROM assets; +UPDATE assets +SET dynamic_cols=COLUMN_ADD(dynamic_cols, 'warranty', '3 years') +WHERE item_name='Thinkpad Laptop'; +SELECT item_name, +COLUMN_GET(dynamic_cols, 'warranty' as char) AS color +FROM assets; item_name color MariaDB T-shirt NULL Thinkpad Laptop 3 years -UPDATE assets SET dynamic_cols=COLUMN_ADD(dynamic_cols, 'warranty', '4 years') -WHERE item_name in (select b.item_name -from assets b +UPDATE assets +SET dynamic_cols=COLUMN_ADD(dynamic_cols, 'warranty', '4 years') +WHERE item_name in +(select b.item_name from assets b where COLUMN_GET(b.dynamic_cols, 'color' as char) ='black'); -SELECT item_name, COLUMN_GET(dynamic_cols, 'warranty' as char) AS color FROM assets; +SELECT item_name, +COLUMN_GET(dynamic_cols, 'warranty' as char) AS color +FROM assets; item_name color MariaDB T-shirt NULL Thinkpad Laptop 4 years -UPDATE assets SET dynamic_cols=COLUMN_ADD(dynamic_cols, 'warranty', (select COLUMN_GET(b.dynamic_cols, 'color' as char) +UPDATE assets SET dynamic_cols=COLUMN_ADD(dynamic_cols, 'warranty', +(select COLUMN_GET(b.dynamic_cols, 'color' as char) from assets b where assets.item_name = item_name)); -SELECT item_name, COLUMN_GET(dynamic_cols, 'warranty' as char) AS color FROM assets; +SELECT item_name, +COLUMN_GET(dynamic_cols, 'warranty' as char) AS color +FROM assets; item_name color MariaDB T-shirt blue Thinkpad Laptop black -drop table assets ; +drop table assets; # # Test on fulltext columns # -CREATE TABLE ft2(copy TEXT,FULLTEXT(copy)) ENGINE=MyISAM; +CREATE TABLE ft2(copy TEXT,FULLTEXT(copy)); INSERT INTO ft2(copy) VALUES ('MySQL vs MariaDB database'), ('Oracle vs MariaDB database'), @@ -1163,17 +1478,4404 @@ copy MySQL vs MariaDB database Oracle vs MariaDB database PostgreSQL vs MariaDB database -update ft2 set copy = (select max(concat('mykeyword ',substr(b.copy,1,5))) from ft2 b WHERE MATCH(b.copy) AGAINST('database')) +update ft2 set copy = (select max(concat('mykeyword ',substr(b.copy,1,5))) +from ft2 b WHERE MATCH(b.copy) AGAINST('database')) where MATCH(copy) AGAINST('keys'); SELECT * FROM ft2 WHERE MATCH(copy) AGAINST('mykeyword'); copy mykeyword Postg mykeyword Postg drop table ft2; +set default_storage_engine=Aria; +create table t1 (old_c1 integer, +old_c2 integer, +c1 integer, +c2 integer, +c3 integer); +insert into t1 select c1+10,c2,c3+10, NULL, NULL from t1; +insert into t1 select c1+20,c2+1,c3+20, NULL, NULL from t1; +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status Table is already up to date +create view v1 as select * from t1 where c2=2; +create trigger trg_t1 before update on t1 for each row +begin +set new.old_c1=old.c1; +set new.old_c2=old.c2; +end; +/ +insert into t1(c1,c2,c3) +values (1,1,1), (1,2,2), (1,3,3), +(2,1,4), (2,2,5), (2,3,6), +(2,4,7), (2,5,8); +analyze table t1; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +select * from t1; +old_c1 old_c2 c1 c2 c3 +NULL NULL 1 1 1 +NULL NULL 1 2 2 +NULL NULL 1 3 3 +NULL NULL 2 1 4 +NULL NULL 2 2 5 +NULL NULL 2 3 6 +NULL NULL 2 4 7 +NULL NULL 2 5 8 +create table tmp as select * from t1; +# Test without any index +# +# Update with value from subquery on the same table +# +explain update t1 set c1=(select a.c3 from t1 a where a.c3 = t1.c3); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 8 Using where +update t1 set c1=(select a.c3 from t1 a where a.c3 = t1.c3); +affected rows: 8 +info: Rows matched: 8 Changed: 8 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +1->1 1 +1->2 2 * +1->3 3 * +2->4 4 * +2->5 5 * +2->6 6 * +2->7 7 * +2->8 8 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update with EXISTS subquery over the updated table +# in WHERE + possibly sargable condition +# +explain update t1 set c1=10 +where c1 <2 +and exists (select 'X' from t1 a where a.c1 = t1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ALL NULL NULL NULL NULL 8 +update t1 set c1=10 +where c1 <2 +and exists (select 'X' from t1 a where a.c1 = t1.c1); +affected rows: 3 +info: Rows matched: 3 Changed: 3 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +1->10 1 * +1->10 2 * +1->10 3 * +NULL 4 +NULL 5 +NULL 6 +NULL 7 +NULL 8 +truncate table t1; +insert into t1 select * from tmp; +# +# Update with EXISTS subquery over the updated table +# in WHERE + non-sargable condition +# +explain update t1 set c1=c1+10 +where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 >= 3; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ALL NULL NULL NULL NULL 8 +update t1 set c1=c1+10 +where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 >= 3; +affected rows: 4 +info: Rows matched: 4 Changed: 4 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +NULL 1 +NULL 2 +1->11 3 * +NULL 4 +NULL 5 +2->12 6 * +2->12 7 * +2->12 8 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update with order by +# +explain update t1 set c1=c1+10 +where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 order by c2; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where; Using filesort +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ALL NULL NULL NULL NULL 8 +update t1 set c1=c1+10 +where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 order by c2; +affected rows: 4 +info: Rows matched: 4 Changed: 4 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +NULL 1 +NULL 2 +1->11 3 * +NULL 4 +NULL 5 +2->12 6 * +2->12 7 * +2->12 8 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update with a reference to view in subquery +# +explain update t1 set c1=c1 +(select max(a.c2) from v1 a +where a.c1 = t1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 +2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 8 Using where +update t1 set c1=c1 +(select max(a.c2) from v1 a +where a.c1 = t1.c1); +affected rows: 8 +info: Rows matched: 8 Changed: 8 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +1->3 1 * +1->3 2 * +1->3 3 * +2->4 4 * +2->4 5 * +2->4 6 * +2->4 7 * +2->4 8 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update view +# +explain update v1 set c1=c1 + (select max(a.c2) from t1 a +where a.c1 = v1.c1) +10 where c3 > 3; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 8 Using where +update v1 set c1=c1 + (select max(a.c2) from t1 a +where a.c1 = v1.c1) +10 where c3 > 3; +affected rows: 1 +info: Rows matched: 1 Changed: 1 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +NULL 1 +NULL 2 +NULL 3 +NULL 4 +2->17 5 * +NULL 6 +NULL 7 +NULL 8 +truncate table t1; +insert into t1 select * from tmp; +# +# Update view with reference to the same view in subquery +# +explain update v1 set c1=c1 + 1 +where c1 <2 +and exists (select 'X' from v1 a where a.c1 = v1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where +2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 8 Using where +update v1 set c1=c1 + 1 +where c1 <2 +and exists (select 'X' from v1 a where a.c1 = v1.c1); +affected rows: 1 +info: Rows matched: 1 Changed: 1 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +NULL 1 +1->2 2 * +NULL 3 +NULL 4 +NULL 5 +NULL 6 +NULL 7 +NULL 8 +truncate table t1; +insert into t1 select * from tmp; +# +# Update view with EXISTS and reference to the same view in subquery +# +explain update v1 +set c1=(select max(a.c1)+10 from v1 a where a.c1 = v1.c1) +where c1 <10 and exists (select 'X' from v1 a where a.c2 = v1.c2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where +3 MATERIALIZED t1 ALL NULL NULL NULL NULL 8 Using where +2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 8 Using where +update v1 +set c1=(select max(a.c1)+10 from v1 a where a.c1 = v1.c1) +where c1 <10 and exists (select 'X' from v1 a where a.c2 = v1.c2); +affected rows: 2 +info: Rows matched: 2 Changed: 2 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +NULL 1 +1->11 2 * +NULL 3 +NULL 4 +2->12 5 * +NULL 6 +NULL 7 +NULL 8 +truncate table t1; +insert into t1 select * from tmp; +# +# Update with IN predicand over the updated table in WHERE +# +explain update t1 set c3=c3+10 +where c2 in (select distinct a.c2 from t1 a where t1.c1=a.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 +1 PRIMARY a ALL NULL NULL NULL NULL 8 Using where; FirstMatch(t1) +update t1 set c3=c3+10 +where c2 in (select distinct a.c2 from t1 a where t1.c1=a.c1); +affected rows: 8 +info: Rows matched: 8 Changed: 8 Warnings: 0 +select c3 from t1; +c3 +11 +12 +13 +14 +15 +16 +17 +18 +truncate table t1; +insert into t1 select * from tmp; +# +# Update with a limit +# +explain update t1 +set c1=(select a.c3 from t1 a where a.c3 = t1.c3) limit 2; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 8 Using where +update t1 +set c1=(select a.c3 from t1 a where a.c3 = t1.c3) limit 2; +affected rows: 2 +info: Rows matched: 2 Changed: 2 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +1->1 1 +1->2 2 * +NULL 3 +NULL 4 +NULL 5 +NULL 6 +NULL 7 +NULL 8 +truncate table t1; +insert into t1 select * from tmp; +# +# Update with a limit and an order by +# +update t1 +set c1=(select a.c3 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 2; +affected rows: 2 +info: Rows matched: 2 Changed: 2 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +NULL 1 +NULL 2 +NULL 3 +NULL 4 +NULL 5 +NULL 6 +2->7 7 * +2->8 8 * +truncate table t1; +insert into t1 select * from tmp; +# Test with an index on updated columns +create index t1_c2 on t1 (c2,c1); +analyze table t1; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +# +# Update with value from subquery on the same table +# +explain update t1 set c1=(select a.c3 from t1 a where a.c3 = t1.c3); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 8 Using where +update t1 set c1=(select a.c3 from t1 a where a.c3 = t1.c3); +affected rows: 8 +info: Rows matched: 8 Changed: 8 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +1->1 1 +1->2 2 * +1->3 3 * +2->4 4 * +2->5 5 * +2->6 6 * +2->7 7 * +2->8 8 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update with EXISTS subquery over the updated table +# in WHERE + possibly sargable condition +# +explain update t1 set c1=10 +where c1 <2 +and exists (select 'X' from t1 a where a.c1 = t1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a index NULL t1_c2 10 NULL 8 Using index +update t1 set c1=10 +where c1 <2 +and exists (select 'X' from t1 a where a.c1 = t1.c1); +affected rows: 3 +info: Rows matched: 3 Changed: 3 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +1->10 1 * +1->10 2 * +1->10 3 * +NULL 4 +NULL 5 +NULL 6 +NULL 7 +NULL 8 +truncate table t1; +insert into t1 select * from tmp; +# +# Update with EXISTS subquery over the updated table +# in WHERE + non-sargable condition +# +explain update t1 set c1=c1+10 +where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 >= 3; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 range t1_c2 t1_c2 5 NULL 5 Using index condition +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a range t1_c2 t1_c2 5 NULL 5 Using where; Using index +update t1 set c1=c1+10 +where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 >= 3; +affected rows: 4 +info: Rows matched: 4 Changed: 4 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +NULL 1 +NULL 2 +1->11 3 * +NULL 4 +NULL 5 +2->12 6 * +2->12 7 * +2->12 8 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update with order by +# +explain update t1 set c1=c1+10 +where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 order by c2; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 range t1_c2 t1_c2 5 NULL 5 Using index condition +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a range t1_c2 t1_c2 5 NULL 5 Using where; Using index +update t1 set c1=c1+10 +where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 order by c2; +affected rows: 4 +info: Rows matched: 4 Changed: 4 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +NULL 1 +NULL 2 +1->11 3 * +NULL 4 +NULL 5 +2->12 6 * +2->12 7 * +2->12 8 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update with a reference to view in subquery +# +explain update t1 set c1=c1 +(select max(a.c2) from v1 a +where a.c1 = t1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 +2 DEPENDENT SUBQUERY t1 ref t1_c2 t1_c2 10 const,test.t1.c1 1 Using index +update t1 set c1=c1 +(select max(a.c2) from v1 a +where a.c1 = t1.c1); +affected rows: 8 +info: Rows matched: 8 Changed: 8 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +1->3 1 * +1->3 2 * +1->3 3 * +2->4 4 * +2->4 5 * +2->4 6 * +2->4 7 * +2->4 8 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update view +# +explain update v1 set c1=c1 + (select max(a.c2) from t1 a +where a.c1 = v1.c1) +10 where c3 > 3; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ref t1_c2 t1_c2 5 const 2 Using where +2 DEPENDENT SUBQUERY a index NULL t1_c2 10 NULL 8 Using where; Using index +update v1 set c1=c1 + (select max(a.c2) from t1 a +where a.c1 = v1.c1) +10 where c3 > 3; +affected rows: 1 +info: Rows matched: 1 Changed: 1 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +NULL 1 +NULL 2 +NULL 3 +NULL 4 +2->17 5 * +NULL 6 +NULL 7 +NULL 8 +truncate table t1; +insert into t1 select * from tmp; +# +# Update view with reference to the same view in subquery +# +explain update v1 set c1=c1 + 1 +where c1 <2 +and exists (select 'X' from v1 a where a.c1 = v1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 range t1_c2 t1_c2 10 NULL 1 Using index condition; Using where +2 MATERIALIZED t1 ref t1_c2 t1_c2 5 const 2 Using index +update v1 set c1=c1 + 1 +where c1 <2 +and exists (select 'X' from v1 a where a.c1 = v1.c1); +affected rows: 1 +info: Rows matched: 1 Changed: 1 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +NULL 1 +1->2 2 * +NULL 3 +NULL 4 +NULL 5 +NULL 6 +NULL 7 +NULL 8 +truncate table t1; +insert into t1 select * from tmp; +# +# Update view with EXISTS and reference to the same view in subquery +# +explain update v1 +set c1=(select max(a.c1)+10 from v1 a where a.c1 = v1.c1) +where c1 <10 and exists (select 'X' from v1 a where a.c2 = v1.c2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 range t1_c2 t1_c2 10 NULL 2 Using index condition +3 MATERIALIZED t1 ref t1_c2 t1_c2 5 const 2 Using index +2 DEPENDENT SUBQUERY t1 ref t1_c2 t1_c2 10 const,test.t1.c1 1 Using index +update v1 +set c1=(select max(a.c1)+10 from v1 a where a.c1 = v1.c1) +where c1 <10 and exists (select 'X' from v1 a where a.c2 = v1.c2); +affected rows: 2 +info: Rows matched: 2 Changed: 2 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +NULL 1 +1->11 2 * +NULL 3 +NULL 4 +2->12 5 * +NULL 6 +NULL 7 +NULL 8 +truncate table t1; +insert into t1 select * from tmp; +# +# Update with IN predicand over the updated table in WHERE +# +explain update t1 set c3=c3+10 +where c2 in (select distinct a.c2 from t1 a where t1.c1=a.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL t1_c2 NULL NULL NULL 8 Using where +1 PRIMARY a ref t1_c2 t1_c2 10 test.t1.c2,test.t1.c1 1 Using index; FirstMatch(t1) +update t1 set c3=c3+10 +where c2 in (select distinct a.c2 from t1 a where t1.c1=a.c1); +affected rows: 8 +info: Rows matched: 8 Changed: 8 Warnings: 0 +select c3 from t1; +c3 +11 +12 +13 +14 +15 +16 +17 +18 +truncate table t1; +insert into t1 select * from tmp; +# +# Update with a limit +# +explain update t1 +set c1=(select a.c3 from t1 a where a.c3 = t1.c3) limit 2; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 8 Using where +update t1 +set c1=(select a.c3 from t1 a where a.c3 = t1.c3) limit 2; +affected rows: 2 +info: Rows matched: 2 Changed: 2 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +1->1 1 +1->2 2 * +NULL 3 +NULL 4 +NULL 5 +NULL 6 +NULL 7 +NULL 8 +truncate table t1; +insert into t1 select * from tmp; +# +# Update with a limit and an order by +# +update t1 +set c1=(select a.c3 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 2; +affected rows: 2 +info: Rows matched: 2 Changed: 2 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +NULL 1 +NULL 2 +NULL 3 +NULL 4 +NULL 5 +NULL 6 +2->7 7 * +2->8 8 * +truncate table t1; +insert into t1 select * from tmp; +# Test with an index on updated columns +create index t1_c3 on t1 (c3); +analyze table t1; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +# +# Update with value from subquery on the same table +# +explain update t1 set c1=(select a.c3 from t1 a where a.c3 = t1.c3); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 +2 DEPENDENT SUBQUERY a ref t1_c3 t1_c3 5 test.t1.c3 1 Using index +update t1 set c1=(select a.c3 from t1 a where a.c3 = t1.c3); +affected rows: 8 +info: Rows matched: 8 Changed: 8 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +1->1 1 +1->2 2 * +1->3 3 * +2->4 4 * +2->5 5 * +2->6 6 * +2->7 7 * +2->8 8 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update with EXISTS subquery over the updated table +# in WHERE + possibly sargable condition +# +explain update t1 set c1=10 +where c1 <2 +and exists (select 'X' from t1 a where a.c1 = t1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a index NULL t1_c2 10 NULL 8 Using index +update t1 set c1=10 +where c1 <2 +and exists (select 'X' from t1 a where a.c1 = t1.c1); +affected rows: 3 +info: Rows matched: 3 Changed: 3 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +1->10 1 * +1->10 2 * +1->10 3 * +NULL 4 +NULL 5 +NULL 6 +NULL 7 +NULL 8 +truncate table t1; +insert into t1 select * from tmp; +# +# Update with EXISTS subquery over the updated table +# in WHERE + non-sargable condition +# +explain update t1 set c1=c1+10 +where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 >= 3; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 range t1_c2 t1_c2 5 NULL 5 Using index condition +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a range t1_c2 t1_c2 5 NULL 5 Using where; Using index +update t1 set c1=c1+10 +where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 >= 3; +affected rows: 4 +info: Rows matched: 4 Changed: 4 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +NULL 1 +NULL 2 +1->11 3 * +NULL 4 +NULL 5 +2->12 6 * +2->12 7 * +2->12 8 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update with order by +# +explain update t1 set c1=c1+10 +where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 order by c2; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 range t1_c2 t1_c2 5 NULL 5 Using index condition +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a range t1_c2 t1_c2 5 NULL 5 Using where; Using index +update t1 set c1=c1+10 +where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 order by c2; +affected rows: 4 +info: Rows matched: 4 Changed: 4 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +NULL 1 +NULL 2 +1->11 3 * +NULL 4 +NULL 5 +2->12 6 * +2->12 7 * +2->12 8 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update with a reference to view in subquery +# +explain update t1 set c1=c1 +(select max(a.c2) from v1 a +where a.c1 = t1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 +2 DEPENDENT SUBQUERY t1 ref t1_c2 t1_c2 10 const,test.t1.c1 1 Using index +update t1 set c1=c1 +(select max(a.c2) from v1 a +where a.c1 = t1.c1); +affected rows: 8 +info: Rows matched: 8 Changed: 8 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +1->3 1 * +1->3 2 * +1->3 3 * +2->4 4 * +2->4 5 * +2->4 6 * +2->4 7 * +2->4 8 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update view +# +explain update v1 set c1=c1 + (select max(a.c2) from t1 a +where a.c1 = v1.c1) +10 where c3 > 3; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ref t1_c2,t1_c3 t1_c2 5 const 2 Using where +2 DEPENDENT SUBQUERY a index NULL t1_c2 10 NULL 8 Using where; Using index +update v1 set c1=c1 + (select max(a.c2) from t1 a +where a.c1 = v1.c1) +10 where c3 > 3; +affected rows: 1 +info: Rows matched: 1 Changed: 1 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +NULL 1 +NULL 2 +NULL 3 +NULL 4 +2->17 5 * +NULL 6 +NULL 7 +NULL 8 +truncate table t1; +insert into t1 select * from tmp; +# +# Update view with reference to the same view in subquery +# +explain update v1 set c1=c1 + 1 +where c1 <2 +and exists (select 'X' from v1 a where a.c1 = v1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 range t1_c2 t1_c2 10 NULL 1 Using index condition; Using where +2 MATERIALIZED t1 ref t1_c2 t1_c2 5 const 2 Using index +update v1 set c1=c1 + 1 +where c1 <2 +and exists (select 'X' from v1 a where a.c1 = v1.c1); +affected rows: 1 +info: Rows matched: 1 Changed: 1 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +NULL 1 +1->2 2 * +NULL 3 +NULL 4 +NULL 5 +NULL 6 +NULL 7 +NULL 8 +truncate table t1; +insert into t1 select * from tmp; +# +# Update view with EXISTS and reference to the same view in subquery +# +explain update v1 +set c1=(select max(a.c1)+10 from v1 a where a.c1 = v1.c1) +where c1 <10 and exists (select 'X' from v1 a where a.c2 = v1.c2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 range t1_c2 t1_c2 10 NULL 2 Using index condition +3 MATERIALIZED t1 ref t1_c2 t1_c2 5 const 2 Using index +2 DEPENDENT SUBQUERY t1 ref t1_c2 t1_c2 10 const,test.t1.c1 1 Using index +update v1 +set c1=(select max(a.c1)+10 from v1 a where a.c1 = v1.c1) +where c1 <10 and exists (select 'X' from v1 a where a.c2 = v1.c2); +affected rows: 2 +info: Rows matched: 2 Changed: 2 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +NULL 1 +1->11 2 * +NULL 3 +NULL 4 +2->12 5 * +NULL 6 +NULL 7 +NULL 8 +truncate table t1; +insert into t1 select * from tmp; +# +# Update with IN predicand over the updated table in WHERE +# +explain update t1 set c3=c3+10 +where c2 in (select distinct a.c2 from t1 a where t1.c1=a.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL t1_c2 NULL NULL NULL 8 Using where +1 PRIMARY a ref t1_c2 t1_c2 10 test.t1.c2,test.t1.c1 1 Using index; FirstMatch(t1) +update t1 set c3=c3+10 +where c2 in (select distinct a.c2 from t1 a where t1.c1=a.c1); +affected rows: 8 +info: Rows matched: 8 Changed: 8 Warnings: 0 +select c3 from t1; +c3 +11 +12 +13 +14 +15 +16 +17 +18 +truncate table t1; +insert into t1 select * from tmp; +# +# Update with a limit +# +explain update t1 +set c1=(select a.c3 from t1 a where a.c3 = t1.c3) limit 2; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 +2 DEPENDENT SUBQUERY a ref t1_c3 t1_c3 5 test.t1.c3 1 Using index +update t1 +set c1=(select a.c3 from t1 a where a.c3 = t1.c3) limit 2; +affected rows: 2 +info: Rows matched: 2 Changed: 2 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +1->1 1 +1->2 2 * +NULL 3 +NULL 4 +NULL 5 +NULL 6 +NULL 7 +NULL 8 +truncate table t1; +insert into t1 select * from tmp; +# +# Update with a limit and an order by +# +update t1 +set c1=(select a.c3 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 2; +affected rows: 2 +info: Rows matched: 2 Changed: 2 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +NULL 1 +NULL 2 +NULL 3 +NULL 4 +NULL 5 +NULL 6 +2->7 7 * +2->8 8 * +truncate table t1; +insert into t1 select * from tmp; +# Test with a primary key on updated columns +drop index t1_c3 on t1; +alter table t1 add primary key (c3); +analyze table t1; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +# +# Update with value from subquery on the same table +# +explain update t1 set c1=(select a.c3 from t1 a where a.c3 = t1.c3); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 +2 DEPENDENT SUBQUERY a eq_ref PRIMARY PRIMARY 4 test.t1.c3 1 Using index +update t1 set c1=(select a.c3 from t1 a where a.c3 = t1.c3); +affected rows: 8 +info: Rows matched: 8 Changed: 8 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +1->1 1 +1->2 2 * +1->3 3 * +2->4 4 * +2->5 5 * +2->6 6 * +2->7 7 * +2->8 8 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update with EXISTS subquery over the updated table +# in WHERE + possibly sargable condition +# +explain update t1 set c1=10 +where c1 <2 +and exists (select 'X' from t1 a where a.c1 = t1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a index NULL t1_c2 10 NULL 8 Using index +update t1 set c1=10 +where c1 <2 +and exists (select 'X' from t1 a where a.c1 = t1.c1); +affected rows: 3 +info: Rows matched: 3 Changed: 3 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +1->10 1 * +1->10 2 * +1->10 3 * +NULL 4 +NULL 5 +NULL 6 +NULL 7 +NULL 8 +truncate table t1; +insert into t1 select * from tmp; +# +# Update with EXISTS subquery over the updated table +# in WHERE + non-sargable condition +# +explain update t1 set c1=c1+10 +where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 >= 3; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 range t1_c2 t1_c2 5 NULL 5 Using index condition +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a range t1_c2 t1_c2 5 NULL 5 Using where; Using index +update t1 set c1=c1+10 +where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 >= 3; +affected rows: 4 +info: Rows matched: 4 Changed: 4 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +NULL 1 +NULL 2 +1->11 3 * +NULL 4 +NULL 5 +2->12 6 * +2->12 7 * +2->12 8 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update with order by +# +explain update t1 set c1=c1+10 +where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 order by c2; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 range t1_c2 t1_c2 5 NULL 5 Using index condition +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a range t1_c2 t1_c2 5 NULL 5 Using where; Using index +update t1 set c1=c1+10 +where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 order by c2; +affected rows: 4 +info: Rows matched: 4 Changed: 4 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +NULL 1 +NULL 2 +1->11 3 * +NULL 4 +NULL 5 +2->12 6 * +2->12 7 * +2->12 8 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update with a reference to view in subquery +# +explain update t1 set c1=c1 +(select max(a.c2) from v1 a +where a.c1 = t1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 +2 DEPENDENT SUBQUERY t1 ref t1_c2 t1_c2 10 const,test.t1.c1 1 Using index +update t1 set c1=c1 +(select max(a.c2) from v1 a +where a.c1 = t1.c1); +affected rows: 8 +info: Rows matched: 8 Changed: 8 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +1->3 1 * +1->3 2 * +1->3 3 * +2->4 4 * +2->4 5 * +2->4 6 * +2->4 7 * +2->4 8 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update view +# +explain update v1 set c1=c1 + (select max(a.c2) from t1 a +where a.c1 = v1.c1) +10 where c3 > 3; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ref PRIMARY,t1_c2 t1_c2 5 const 2 Using where +2 DEPENDENT SUBQUERY a index NULL t1_c2 10 NULL 8 Using where; Using index +update v1 set c1=c1 + (select max(a.c2) from t1 a +where a.c1 = v1.c1) +10 where c3 > 3; +affected rows: 1 +info: Rows matched: 1 Changed: 1 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +NULL 1 +NULL 2 +NULL 3 +NULL 4 +2->17 5 * +NULL 6 +NULL 7 +NULL 8 +truncate table t1; +insert into t1 select * from tmp; +# +# Update view with reference to the same view in subquery +# +explain update v1 set c1=c1 + 1 +where c1 <2 +and exists (select 'X' from v1 a where a.c1 = v1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 range t1_c2 t1_c2 10 NULL 1 Using index condition; Using where +2 MATERIALIZED t1 ref t1_c2 t1_c2 5 const 2 Using index +update v1 set c1=c1 + 1 +where c1 <2 +and exists (select 'X' from v1 a where a.c1 = v1.c1); +affected rows: 1 +info: Rows matched: 1 Changed: 1 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +NULL 1 +1->2 2 * +NULL 3 +NULL 4 +NULL 5 +NULL 6 +NULL 7 +NULL 8 +truncate table t1; +insert into t1 select * from tmp; +# +# Update view with EXISTS and reference to the same view in subquery +# +explain update v1 +set c1=(select max(a.c1)+10 from v1 a where a.c1 = v1.c1) +where c1 <10 and exists (select 'X' from v1 a where a.c2 = v1.c2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 range t1_c2 t1_c2 10 NULL 2 Using index condition +3 MATERIALIZED t1 ref t1_c2 t1_c2 5 const 2 Using index +2 DEPENDENT SUBQUERY t1 ref t1_c2 t1_c2 10 const,test.t1.c1 1 Using index +update v1 +set c1=(select max(a.c1)+10 from v1 a where a.c1 = v1.c1) +where c1 <10 and exists (select 'X' from v1 a where a.c2 = v1.c2); +affected rows: 2 +info: Rows matched: 2 Changed: 2 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +NULL 1 +1->11 2 * +NULL 3 +NULL 4 +2->12 5 * +NULL 6 +NULL 7 +NULL 8 +truncate table t1; +insert into t1 select * from tmp; +# +# Update with IN predicand over the updated table in WHERE +# +explain update t1 set c3=c3+10 +where c2 in (select distinct a.c2 from t1 a where t1.c1=a.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL t1_c2 NULL NULL NULL 8 Using where +1 PRIMARY a ref t1_c2 t1_c2 10 test.t1.c2,test.t1.c1 1 Using index; FirstMatch(t1) +update t1 set c3=c3+10 +where c2 in (select distinct a.c2 from t1 a where t1.c1=a.c1); +affected rows: 8 +info: Rows matched: 8 Changed: 8 Warnings: 0 +select c3 from t1; +c3 +11 +12 +13 +14 +15 +16 +17 +18 +truncate table t1; +insert into t1 select * from tmp; +# +# Update with a limit +# +explain update t1 +set c1=(select a.c3 from t1 a where a.c3 = t1.c3) limit 2; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 +2 DEPENDENT SUBQUERY a eq_ref PRIMARY PRIMARY 4 test.t1.c3 1 Using index +update t1 +set c1=(select a.c3 from t1 a where a.c3 = t1.c3) limit 2; +affected rows: 2 +info: Rows matched: 2 Changed: 2 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +1->1 1 +1->2 2 * +NULL 3 +NULL 4 +NULL 5 +NULL 6 +NULL 7 +NULL 8 +truncate table t1; +insert into t1 select * from tmp; +# +# Update with a limit and an order by +# +update t1 +set c1=(select a.c3 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 2; +affected rows: 2 +info: Rows matched: 2 Changed: 2 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +NULL 1 +NULL 2 +NULL 3 +NULL 4 +NULL 5 +NULL 6 +2->7 7 * +2->8 8 * +truncate table t1; +insert into t1 select * from tmp; +# Update with error "Subquery returns more than 1 row" +update t1 set c2=(select c2 from t1); +ERROR 21000: Subquery returns more than 1 row +select c1,c2,c3 from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +# Update with error "Subquery returns more than 1 row" +# and order by +update t1 set c2=(select c2 from t1) order by c3; +ERROR 21000: Subquery returns more than 1 row +select c1,c2,c3 from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +# Duplicate value on update a primary key +update t1 set c3=0 +where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 >= 3; +ERROR 23000: Duplicate entry '0' for key 'PRIMARY' +select c1,c2,c3 from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 0 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +truncate table t1; +insert into t1 select * from tmp; +# Duplicate value on update a primary key with ignore +update ignore t1 set c3=0 +where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 >= 3; +affected rows: 4 +info: Rows matched: 4 Changed: 4 Warnings: 0 +select c1,c2,c3 from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 0 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +truncate table t1; +insert into t1 select * from tmp; +# Duplicate value on update a primary key and limit +update t1 set c3=0 +where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 limit 2; +ERROR 23000: Duplicate entry '0' for key 'PRIMARY' +select c1,c2,c3 from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 0 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +truncate table t1; +insert into t1 select * from tmp; +# Duplicate value on update a primary key with ignore +# and limit +update ignore t1 set c3=0 +where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 limit 2; +affected rows: 2 +info: Rows matched: 2 Changed: 2 Warnings: 0 +select c1,c2,c3 from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 0 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +truncate table t1; +insert into t1 select * from tmp; +# Update no rows found +update t1 set c1=10 +where c1 <2 and exists (select 'X' from t1 a where a.c1 = t1.c1 + 10); +affected rows: 0 +info: Rows matched: 0 Changed: 0 Warnings: 0 +select c1,c2,c3 from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +truncate table t1; +insert into t1 select * from tmp; +# Update no rows changed +drop trigger trg_t1; +update t1 set c1=c1 +where c1 <2 and exists (select 'X' from t1 a where a.c1 = t1.c1); +affected rows: 0 +info: Rows matched: 3 Changed: 0 Warnings: 0 +select c1,c2,c3 from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +truncate table t1; +insert into t1 select * from tmp; +# +# Check call of after trigger +# +create or replace trigger trg_t2 after update on t1 for each row +begin +declare msg varchar(100); +if (new.c3 = 5) then +set msg=concat('in after update trigger on ',new.c3); +SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = msg; +end if; +end; +/ +update t1 set c1=2 +where c3 in (select distinct a.c3 from t1 a where a.c1=t1.c1); +ERROR 45000: in after update trigger on 5 +select c1,c2,c3 from t1; +c1 c2 c3 +2 1 1 +2 1 4 +2 2 2 +2 2 5 +2 3 3 +2 3 6 +2 4 7 +2 5 8 +truncate table t1; +insert into t1 select * from tmp; +# +# Check update with order by and after trigger +# +update t1 set c1=2 +where c3 in (select distinct a.c3 from t1 a where a.c1=t1.c1) +order by t1.c2, t1.c1; +ERROR 45000: in after update trigger on 5 +select c1,c2,c3 from t1; +c1 c2 c3 +1 3 3 +2 1 1 +2 1 4 +2 2 2 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +truncate table t1; +insert into t1 select * from tmp; +drop view v1; +# +# Check update on view with check option +# +create view v1 as select * from t1 where c2=2 with check option; +update v1 set c2=3 where c1=1; +ERROR 44000: CHECK OPTION failed `test`.`v1` +select c1,c2,c3 from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +truncate table t1; +insert into t1 select * from tmp; +update v1 set c2=(select max(c3) from v1) where c1=1; +ERROR 44000: CHECK OPTION failed `test`.`v1` +select c1,c2,c3 from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +truncate table t1; +insert into t1 select * from tmp; +update v1 set c2=(select min(va.c3) from v1 va), c1=0 where c1=1; +select c1,c2,c3 from t1; +c1 c2 c3 +0 2 2 +1 1 1 +1 3 3 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +truncate table t1; +insert into t1 select * from tmp; +drop table tmp; +drop view v1; +drop table t1; +# +# Test on dynamic columns (blob) +# +create table assets ( +item_name varchar(32) primary key, -- A common attribute for all items +dynamic_cols blob -- Dynamic columns will be stored here +); +INSERT INTO assets VALUES ('MariaDB T-shirt', +COLUMN_CREATE('color', 'blue', 'size', 'XL')); +INSERT INTO assets VALUES ('Thinkpad Laptop', +COLUMN_CREATE('color', 'black', 'price', 500)); +SELECT item_name, COLUMN_GET(dynamic_cols, 'color' as char) AS color +FROM assets; +item_name color +MariaDB T-shirt blue +Thinkpad Laptop black +UPDATE assets +SET dynamic_cols=COLUMN_ADD(dynamic_cols, 'warranty', '3 years') +WHERE item_name='Thinkpad Laptop'; +SELECT item_name, +COLUMN_GET(dynamic_cols, 'warranty' as char) AS color +FROM assets; +item_name color +MariaDB T-shirt NULL +Thinkpad Laptop 3 years +UPDATE assets +SET dynamic_cols=COLUMN_ADD(dynamic_cols, 'warranty', '4 years') +WHERE item_name in +(select b.item_name from assets b +where COLUMN_GET(b.dynamic_cols, 'color' as char) ='black'); +SELECT item_name, +COLUMN_GET(dynamic_cols, 'warranty' as char) AS color +FROM assets; +item_name color +MariaDB T-shirt NULL +Thinkpad Laptop 4 years +UPDATE assets SET dynamic_cols=COLUMN_ADD(dynamic_cols, 'warranty', +(select COLUMN_GET(b.dynamic_cols, 'color' as char) +from assets b +where assets.item_name = item_name)); +SELECT item_name, +COLUMN_GET(dynamic_cols, 'warranty' as char) AS color +FROM assets; +item_name color +MariaDB T-shirt blue +Thinkpad Laptop black +drop table assets; +# +# Test on fulltext columns +# +CREATE TABLE ft2(copy TEXT,FULLTEXT(copy)); +INSERT INTO ft2(copy) VALUES +('MySQL vs MariaDB database'), +('Oracle vs MariaDB database'), +('PostgreSQL vs MariaDB database'), +('MariaDB overview'), +('Foreign keys'), +('Primary keys'), +('Indexes'), +('Transactions'), +('Triggers'); +SELECT * FROM ft2 WHERE MATCH(copy) AGAINST('database'); +copy +MySQL vs MariaDB database +Oracle vs MariaDB database +PostgreSQL vs MariaDB database +update ft2 set copy = (select max(concat('mykeyword ',substr(b.copy,1,5))) +from ft2 b WHERE MATCH(b.copy) AGAINST('database')) +where MATCH(copy) AGAINST('keys'); +SELECT * FROM ft2 WHERE MATCH(copy) AGAINST('mykeyword'); +copy +mykeyword Postg +mykeyword Postg +drop table ft2; +set default_storage_engine=MyISAM; +create table t1 (old_c1 integer, +old_c2 integer, +c1 integer, +c2 integer, +c3 integer); +insert into t1 select c1+10,c2,c3+10, NULL, NULL from t1; +insert into t1 select c1+20,c2+1,c3+20, NULL, NULL from t1; +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status Table is already up to date +create view v1 as select * from t1 where c2=2; +create trigger trg_t1 before update on t1 for each row +begin +set new.old_c1=old.c1; +set new.old_c2=old.c2; +end; +/ +insert into t1(c1,c2,c3) +values (1,1,1), (1,2,2), (1,3,3), +(2,1,4), (2,2,5), (2,3,6), +(2,4,7), (2,5,8); +analyze table t1; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +select * from t1; +old_c1 old_c2 c1 c2 c3 +NULL NULL 1 1 1 +NULL NULL 1 2 2 +NULL NULL 1 3 3 +NULL NULL 2 1 4 +NULL NULL 2 2 5 +NULL NULL 2 3 6 +NULL NULL 2 4 7 +NULL NULL 2 5 8 +create table tmp as select * from t1; +# Test without any index +# +# Update with value from subquery on the same table +# +explain update t1 set c1=(select a.c3 from t1 a where a.c3 = t1.c3); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 8 Using where +update t1 set c1=(select a.c3 from t1 a where a.c3 = t1.c3); +affected rows: 8 +info: Rows matched: 8 Changed: 8 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +1->1 1 +1->2 2 * +1->3 3 * +2->4 4 * +2->5 5 * +2->6 6 * +2->7 7 * +2->8 8 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update with EXISTS subquery over the updated table +# in WHERE + possibly sargable condition +# +explain update t1 set c1=10 +where c1 <2 +and exists (select 'X' from t1 a where a.c1 = t1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ALL NULL NULL NULL NULL 8 +update t1 set c1=10 +where c1 <2 +and exists (select 'X' from t1 a where a.c1 = t1.c1); +affected rows: 3 +info: Rows matched: 3 Changed: 3 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +1->10 1 * +1->10 2 * +1->10 3 * +NULL 4 +NULL 5 +NULL 6 +NULL 7 +NULL 8 +truncate table t1; +insert into t1 select * from tmp; +# +# Update with EXISTS subquery over the updated table +# in WHERE + non-sargable condition +# +explain update t1 set c1=c1+10 +where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 >= 3; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ALL NULL NULL NULL NULL 8 +update t1 set c1=c1+10 +where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 >= 3; +affected rows: 4 +info: Rows matched: 4 Changed: 4 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +NULL 1 +NULL 2 +1->11 3 * +NULL 4 +NULL 5 +2->12 6 * +2->12 7 * +2->12 8 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update with order by +# +explain update t1 set c1=c1+10 +where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 order by c2; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where; Using filesort +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ALL NULL NULL NULL NULL 8 +update t1 set c1=c1+10 +where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 order by c2; +affected rows: 4 +info: Rows matched: 4 Changed: 4 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +NULL 1 +NULL 2 +1->11 3 * +NULL 4 +NULL 5 +2->12 6 * +2->12 7 * +2->12 8 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update with a reference to view in subquery +# +explain update t1 set c1=c1 +(select max(a.c2) from v1 a +where a.c1 = t1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 +2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 8 Using where +update t1 set c1=c1 +(select max(a.c2) from v1 a +where a.c1 = t1.c1); +affected rows: 8 +info: Rows matched: 8 Changed: 8 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +1->3 1 * +1->3 2 * +1->3 3 * +2->4 4 * +2->4 5 * +2->4 6 * +2->4 7 * +2->4 8 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update view +# +explain update v1 set c1=c1 + (select max(a.c2) from t1 a +where a.c1 = v1.c1) +10 where c3 > 3; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 8 Using where +update v1 set c1=c1 + (select max(a.c2) from t1 a +where a.c1 = v1.c1) +10 where c3 > 3; +affected rows: 1 +info: Rows matched: 1 Changed: 1 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +NULL 1 +NULL 2 +NULL 3 +NULL 4 +2->17 5 * +NULL 6 +NULL 7 +NULL 8 +truncate table t1; +insert into t1 select * from tmp; +# +# Update view with reference to the same view in subquery +# +explain update v1 set c1=c1 + 1 +where c1 <2 +and exists (select 'X' from v1 a where a.c1 = v1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where +2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 8 Using where +update v1 set c1=c1 + 1 +where c1 <2 +and exists (select 'X' from v1 a where a.c1 = v1.c1); +affected rows: 1 +info: Rows matched: 1 Changed: 1 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +NULL 1 +1->2 2 * +NULL 3 +NULL 4 +NULL 5 +NULL 6 +NULL 7 +NULL 8 +truncate table t1; +insert into t1 select * from tmp; +# +# Update view with EXISTS and reference to the same view in subquery +# +explain update v1 +set c1=(select max(a.c1)+10 from v1 a where a.c1 = v1.c1) +where c1 <10 and exists (select 'X' from v1 a where a.c2 = v1.c2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where +3 MATERIALIZED t1 ALL NULL NULL NULL NULL 8 Using where +2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 8 Using where +update v1 +set c1=(select max(a.c1)+10 from v1 a where a.c1 = v1.c1) +where c1 <10 and exists (select 'X' from v1 a where a.c2 = v1.c2); +affected rows: 2 +info: Rows matched: 2 Changed: 2 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +NULL 1 +1->11 2 * +NULL 3 +NULL 4 +2->12 5 * +NULL 6 +NULL 7 +NULL 8 +truncate table t1; +insert into t1 select * from tmp; +# +# Update with IN predicand over the updated table in WHERE +# +explain update t1 set c3=c3+10 +where c2 in (select distinct a.c2 from t1 a where t1.c1=a.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 +1 PRIMARY a ALL NULL NULL NULL NULL 8 Using where; FirstMatch(t1) +update t1 set c3=c3+10 +where c2 in (select distinct a.c2 from t1 a where t1.c1=a.c1); +affected rows: 8 +info: Rows matched: 8 Changed: 8 Warnings: 0 +select c3 from t1; +c3 +11 +12 +13 +14 +15 +16 +17 +18 +truncate table t1; +insert into t1 select * from tmp; +# +# Update with a limit +# +explain update t1 +set c1=(select a.c3 from t1 a where a.c3 = t1.c3) limit 2; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 8 Using where +update t1 +set c1=(select a.c3 from t1 a where a.c3 = t1.c3) limit 2; +affected rows: 2 +info: Rows matched: 2 Changed: 2 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +1->1 1 +1->2 2 * +NULL 3 +NULL 4 +NULL 5 +NULL 6 +NULL 7 +NULL 8 +truncate table t1; +insert into t1 select * from tmp; +# +# Update with a limit and an order by +# +update t1 +set c1=(select a.c3 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 2; +affected rows: 2 +info: Rows matched: 2 Changed: 2 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +NULL 1 +NULL 2 +NULL 3 +NULL 4 +NULL 5 +NULL 6 +2->7 7 * +2->8 8 * +truncate table t1; +insert into t1 select * from tmp; +# Test with an index on updated columns +create index t1_c2 on t1 (c2,c1); +analyze table t1; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +# +# Update with value from subquery on the same table +# +explain update t1 set c1=(select a.c3 from t1 a where a.c3 = t1.c3); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 8 Using where +update t1 set c1=(select a.c3 from t1 a where a.c3 = t1.c3); +affected rows: 8 +info: Rows matched: 8 Changed: 8 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +1->1 1 +1->2 2 * +1->3 3 * +2->4 4 * +2->5 5 * +2->6 6 * +2->7 7 * +2->8 8 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update with EXISTS subquery over the updated table +# in WHERE + possibly sargable condition +# +explain update t1 set c1=10 +where c1 <2 +and exists (select 'X' from t1 a where a.c1 = t1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a index NULL t1_c2 10 NULL 8 Using index +update t1 set c1=10 +where c1 <2 +and exists (select 'X' from t1 a where a.c1 = t1.c1); +affected rows: 3 +info: Rows matched: 3 Changed: 3 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +1->10 1 * +1->10 2 * +1->10 3 * +NULL 4 +NULL 5 +NULL 6 +NULL 7 +NULL 8 +truncate table t1; +insert into t1 select * from tmp; +# +# Update with EXISTS subquery over the updated table +# in WHERE + non-sargable condition +# +explain update t1 set c1=c1+10 +where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 >= 3; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 range t1_c2 t1_c2 5 NULL 4 Using index condition +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a range t1_c2 t1_c2 5 NULL 4 Using where; Using index +update t1 set c1=c1+10 +where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 >= 3; +affected rows: 4 +info: Rows matched: 4 Changed: 4 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +NULL 1 +NULL 2 +1->11 3 * +NULL 4 +NULL 5 +2->12 6 * +2->12 7 * +2->12 8 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update with order by +# +explain update t1 set c1=c1+10 +where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 order by c2; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 range t1_c2 t1_c2 5 NULL 4 Using index condition +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a range t1_c2 t1_c2 5 NULL 4 Using where; Using index +update t1 set c1=c1+10 +where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 order by c2; +affected rows: 4 +info: Rows matched: 4 Changed: 4 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +NULL 1 +NULL 2 +1->11 3 * +NULL 4 +NULL 5 +2->12 6 * +2->12 7 * +2->12 8 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update with a reference to view in subquery +# +explain update t1 set c1=c1 +(select max(a.c2) from v1 a +where a.c1 = t1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 +2 DEPENDENT SUBQUERY t1 ref t1_c2 t1_c2 10 const,test.t1.c1 1 Using index +update t1 set c1=c1 +(select max(a.c2) from v1 a +where a.c1 = t1.c1); +affected rows: 8 +info: Rows matched: 8 Changed: 8 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +1->3 1 * +1->3 2 * +1->3 3 * +2->4 4 * +2->4 5 * +2->4 6 * +2->4 7 * +2->4 8 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update view +# +explain update v1 set c1=c1 + (select max(a.c2) from t1 a +where a.c1 = v1.c1) +10 where c3 > 3; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ref t1_c2 t1_c2 5 const 2 Using where +2 DEPENDENT SUBQUERY a index NULL t1_c2 10 NULL 8 Using where; Using index +update v1 set c1=c1 + (select max(a.c2) from t1 a +where a.c1 = v1.c1) +10 where c3 > 3; +affected rows: 1 +info: Rows matched: 1 Changed: 1 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +NULL 1 +NULL 2 +NULL 3 +NULL 4 +2->17 5 * +NULL 6 +NULL 7 +NULL 8 +truncate table t1; +insert into t1 select * from tmp; +# +# Update view with reference to the same view in subquery +# +explain update v1 set c1=c1 + 1 +where c1 <2 +and exists (select 'X' from v1 a where a.c1 = v1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 range t1_c2 t1_c2 10 NULL 1 Using index condition; Using where +2 MATERIALIZED t1 ref t1_c2 t1_c2 5 const 2 Using index +update v1 set c1=c1 + 1 +where c1 <2 +and exists (select 'X' from v1 a where a.c1 = v1.c1); +affected rows: 1 +info: Rows matched: 1 Changed: 1 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +NULL 1 +1->2 2 * +NULL 3 +NULL 4 +NULL 5 +NULL 6 +NULL 7 +NULL 8 +truncate table t1; +insert into t1 select * from tmp; +# +# Update view with EXISTS and reference to the same view in subquery +# +explain update v1 +set c1=(select max(a.c1)+10 from v1 a where a.c1 = v1.c1) +where c1 <10 and exists (select 'X' from v1 a where a.c2 = v1.c2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 range t1_c2 t1_c2 10 NULL 2 Using index condition +3 MATERIALIZED t1 ref t1_c2 t1_c2 5 const 2 Using index +2 DEPENDENT SUBQUERY t1 ref t1_c2 t1_c2 10 const,test.t1.c1 1 Using index +update v1 +set c1=(select max(a.c1)+10 from v1 a where a.c1 = v1.c1) +where c1 <10 and exists (select 'X' from v1 a where a.c2 = v1.c2); +affected rows: 2 +info: Rows matched: 2 Changed: 2 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +NULL 1 +1->11 2 * +NULL 3 +NULL 4 +2->12 5 * +NULL 6 +NULL 7 +NULL 8 +truncate table t1; +insert into t1 select * from tmp; +# +# Update with IN predicand over the updated table in WHERE +# +explain update t1 set c3=c3+10 +where c2 in (select distinct a.c2 from t1 a where t1.c1=a.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL t1_c2 NULL NULL NULL 8 Using where +1 PRIMARY a ref t1_c2 t1_c2 10 test.t1.c2,test.t1.c1 1 Using index; FirstMatch(t1) +update t1 set c3=c3+10 +where c2 in (select distinct a.c2 from t1 a where t1.c1=a.c1); +affected rows: 8 +info: Rows matched: 8 Changed: 8 Warnings: 0 +select c3 from t1; +c3 +11 +12 +13 +14 +15 +16 +17 +18 +truncate table t1; +insert into t1 select * from tmp; +# +# Update with a limit +# +explain update t1 +set c1=(select a.c3 from t1 a where a.c3 = t1.c3) limit 2; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 8 Using where +update t1 +set c1=(select a.c3 from t1 a where a.c3 = t1.c3) limit 2; +affected rows: 2 +info: Rows matched: 2 Changed: 2 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +1->1 1 +1->2 2 * +NULL 3 +NULL 4 +NULL 5 +NULL 6 +NULL 7 +NULL 8 +truncate table t1; +insert into t1 select * from tmp; +# +# Update with a limit and an order by +# +update t1 +set c1=(select a.c3 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 2; +affected rows: 2 +info: Rows matched: 2 Changed: 2 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +NULL 1 +NULL 2 +NULL 3 +NULL 4 +NULL 5 +NULL 6 +2->7 7 * +2->8 8 * +truncate table t1; +insert into t1 select * from tmp; +# Test with an index on updated columns +create index t1_c3 on t1 (c3); +analyze table t1; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +# +# Update with value from subquery on the same table +# +explain update t1 set c1=(select a.c3 from t1 a where a.c3 = t1.c3); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 +2 DEPENDENT SUBQUERY a ref t1_c3 t1_c3 5 test.t1.c3 1 Using index +update t1 set c1=(select a.c3 from t1 a where a.c3 = t1.c3); +affected rows: 8 +info: Rows matched: 8 Changed: 8 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +1->1 1 +1->2 2 * +1->3 3 * +2->4 4 * +2->5 5 * +2->6 6 * +2->7 7 * +2->8 8 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update with EXISTS subquery over the updated table +# in WHERE + possibly sargable condition +# +explain update t1 set c1=10 +where c1 <2 +and exists (select 'X' from t1 a where a.c1 = t1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a index NULL t1_c2 10 NULL 8 Using index +update t1 set c1=10 +where c1 <2 +and exists (select 'X' from t1 a where a.c1 = t1.c1); +affected rows: 3 +info: Rows matched: 3 Changed: 3 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +1->10 1 * +1->10 2 * +1->10 3 * +NULL 4 +NULL 5 +NULL 6 +NULL 7 +NULL 8 +truncate table t1; +insert into t1 select * from tmp; +# +# Update with EXISTS subquery over the updated table +# in WHERE + non-sargable condition +# +explain update t1 set c1=c1+10 +where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 >= 3; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 range t1_c2 t1_c2 5 NULL 4 Using index condition +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a range t1_c2 t1_c2 5 NULL 4 Using where; Using index +update t1 set c1=c1+10 +where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 >= 3; +affected rows: 4 +info: Rows matched: 4 Changed: 4 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +NULL 1 +NULL 2 +1->11 3 * +NULL 4 +NULL 5 +2->12 6 * +2->12 7 * +2->12 8 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update with order by +# +explain update t1 set c1=c1+10 +where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 order by c2; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 range t1_c2 t1_c2 5 NULL 4 Using index condition +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a range t1_c2 t1_c2 5 NULL 4 Using where; Using index +update t1 set c1=c1+10 +where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 order by c2; +affected rows: 4 +info: Rows matched: 4 Changed: 4 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +NULL 1 +NULL 2 +1->11 3 * +NULL 4 +NULL 5 +2->12 6 * +2->12 7 * +2->12 8 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update with a reference to view in subquery +# +explain update t1 set c1=c1 +(select max(a.c2) from v1 a +where a.c1 = t1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 +2 DEPENDENT SUBQUERY t1 ref t1_c2 t1_c2 10 const,test.t1.c1 1 Using index +update t1 set c1=c1 +(select max(a.c2) from v1 a +where a.c1 = t1.c1); +affected rows: 8 +info: Rows matched: 8 Changed: 8 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +1->3 1 * +1->3 2 * +1->3 3 * +2->4 4 * +2->4 5 * +2->4 6 * +2->4 7 * +2->4 8 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update view +# +explain update v1 set c1=c1 + (select max(a.c2) from t1 a +where a.c1 = v1.c1) +10 where c3 > 3; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ref t1_c2,t1_c3 t1_c2 5 const 2 Using where +2 DEPENDENT SUBQUERY a index NULL t1_c2 10 NULL 8 Using where; Using index +update v1 set c1=c1 + (select max(a.c2) from t1 a +where a.c1 = v1.c1) +10 where c3 > 3; +affected rows: 1 +info: Rows matched: 1 Changed: 1 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +NULL 1 +NULL 2 +NULL 3 +NULL 4 +2->17 5 * +NULL 6 +NULL 7 +NULL 8 +truncate table t1; +insert into t1 select * from tmp; +# +# Update view with reference to the same view in subquery +# +explain update v1 set c1=c1 + 1 +where c1 <2 +and exists (select 'X' from v1 a where a.c1 = v1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 range t1_c2 t1_c2 10 NULL 1 Using index condition; Using where +2 MATERIALIZED t1 ref t1_c2 t1_c2 5 const 2 Using index +update v1 set c1=c1 + 1 +where c1 <2 +and exists (select 'X' from v1 a where a.c1 = v1.c1); +affected rows: 1 +info: Rows matched: 1 Changed: 1 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +NULL 1 +1->2 2 * +NULL 3 +NULL 4 +NULL 5 +NULL 6 +NULL 7 +NULL 8 +truncate table t1; +insert into t1 select * from tmp; +# +# Update view with EXISTS and reference to the same view in subquery +# +explain update v1 +set c1=(select max(a.c1)+10 from v1 a where a.c1 = v1.c1) +where c1 <10 and exists (select 'X' from v1 a where a.c2 = v1.c2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 range t1_c2 t1_c2 10 NULL 2 Using index condition +3 MATERIALIZED t1 ref t1_c2 t1_c2 5 const 2 Using index +2 DEPENDENT SUBQUERY t1 ref t1_c2 t1_c2 10 const,test.t1.c1 1 Using index +update v1 +set c1=(select max(a.c1)+10 from v1 a where a.c1 = v1.c1) +where c1 <10 and exists (select 'X' from v1 a where a.c2 = v1.c2); +affected rows: 2 +info: Rows matched: 2 Changed: 2 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +NULL 1 +1->11 2 * +NULL 3 +NULL 4 +2->12 5 * +NULL 6 +NULL 7 +NULL 8 +truncate table t1; +insert into t1 select * from tmp; +# +# Update with IN predicand over the updated table in WHERE +# +explain update t1 set c3=c3+10 +where c2 in (select distinct a.c2 from t1 a where t1.c1=a.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL t1_c2 NULL NULL NULL 8 Using where +1 PRIMARY a ref t1_c2 t1_c2 10 test.t1.c2,test.t1.c1 1 Using index; FirstMatch(t1) +update t1 set c3=c3+10 +where c2 in (select distinct a.c2 from t1 a where t1.c1=a.c1); +affected rows: 8 +info: Rows matched: 8 Changed: 8 Warnings: 0 +select c3 from t1; +c3 +11 +12 +13 +14 +15 +16 +17 +18 +truncate table t1; +insert into t1 select * from tmp; +# +# Update with a limit +# +explain update t1 +set c1=(select a.c3 from t1 a where a.c3 = t1.c3) limit 2; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 +2 DEPENDENT SUBQUERY a ref t1_c3 t1_c3 5 test.t1.c3 1 Using index +update t1 +set c1=(select a.c3 from t1 a where a.c3 = t1.c3) limit 2; +affected rows: 2 +info: Rows matched: 2 Changed: 2 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +1->1 1 +1->2 2 * +NULL 3 +NULL 4 +NULL 5 +NULL 6 +NULL 7 +NULL 8 +truncate table t1; +insert into t1 select * from tmp; +# +# Update with a limit and an order by +# +update t1 +set c1=(select a.c3 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 2; +affected rows: 2 +info: Rows matched: 2 Changed: 2 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +NULL 1 +NULL 2 +NULL 3 +NULL 4 +NULL 5 +NULL 6 +2->7 7 * +2->8 8 * +truncate table t1; +insert into t1 select * from tmp; +# Test with a primary key on updated columns +drop index t1_c3 on t1; +alter table t1 add primary key (c3); +analyze table t1; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +# +# Update with value from subquery on the same table +# +explain update t1 set c1=(select a.c3 from t1 a where a.c3 = t1.c3); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 +2 DEPENDENT SUBQUERY a eq_ref PRIMARY PRIMARY 4 test.t1.c3 1 Using index +update t1 set c1=(select a.c3 from t1 a where a.c3 = t1.c3); +affected rows: 8 +info: Rows matched: 8 Changed: 8 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +1->1 1 +1->2 2 * +1->3 3 * +2->4 4 * +2->5 5 * +2->6 6 * +2->7 7 * +2->8 8 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update with EXISTS subquery over the updated table +# in WHERE + possibly sargable condition +# +explain update t1 set c1=10 +where c1 <2 +and exists (select 'X' from t1 a where a.c1 = t1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a index NULL t1_c2 10 NULL 8 Using index +update t1 set c1=10 +where c1 <2 +and exists (select 'X' from t1 a where a.c1 = t1.c1); +affected rows: 3 +info: Rows matched: 3 Changed: 3 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +1->10 1 * +1->10 2 * +1->10 3 * +NULL 4 +NULL 5 +NULL 6 +NULL 7 +NULL 8 +truncate table t1; +insert into t1 select * from tmp; +# +# Update with EXISTS subquery over the updated table +# in WHERE + non-sargable condition +# +explain update t1 set c1=c1+10 +where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 >= 3; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 range t1_c2 t1_c2 5 NULL 4 Using index condition +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a range t1_c2 t1_c2 5 NULL 4 Using where; Using index +update t1 set c1=c1+10 +where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 >= 3; +affected rows: 4 +info: Rows matched: 4 Changed: 4 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +NULL 1 +NULL 2 +1->11 3 * +NULL 4 +NULL 5 +2->12 6 * +2->12 7 * +2->12 8 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update with order by +# +explain update t1 set c1=c1+10 +where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 order by c2; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 range t1_c2 t1_c2 5 NULL 4 Using index condition +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a range t1_c2 t1_c2 5 NULL 4 Using where; Using index +update t1 set c1=c1+10 +where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 order by c2; +affected rows: 4 +info: Rows matched: 4 Changed: 4 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +NULL 1 +NULL 2 +1->11 3 * +NULL 4 +NULL 5 +2->12 6 * +2->12 7 * +2->12 8 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update with a reference to view in subquery +# +explain update t1 set c1=c1 +(select max(a.c2) from v1 a +where a.c1 = t1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 +2 DEPENDENT SUBQUERY t1 ref t1_c2 t1_c2 10 const,test.t1.c1 1 Using index +update t1 set c1=c1 +(select max(a.c2) from v1 a +where a.c1 = t1.c1); +affected rows: 8 +info: Rows matched: 8 Changed: 8 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +1->3 1 * +1->3 2 * +1->3 3 * +2->4 4 * +2->4 5 * +2->4 6 * +2->4 7 * +2->4 8 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update view +# +explain update v1 set c1=c1 + (select max(a.c2) from t1 a +where a.c1 = v1.c1) +10 where c3 > 3; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ref PRIMARY,t1_c2 t1_c2 5 const 2 Using where +2 DEPENDENT SUBQUERY a index NULL t1_c2 10 NULL 8 Using where; Using index +update v1 set c1=c1 + (select max(a.c2) from t1 a +where a.c1 = v1.c1) +10 where c3 > 3; +affected rows: 1 +info: Rows matched: 1 Changed: 1 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +NULL 1 +NULL 2 +NULL 3 +NULL 4 +2->17 5 * +NULL 6 +NULL 7 +NULL 8 +truncate table t1; +insert into t1 select * from tmp; +# +# Update view with reference to the same view in subquery +# +explain update v1 set c1=c1 + 1 +where c1 <2 +and exists (select 'X' from v1 a where a.c1 = v1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 range t1_c2 t1_c2 10 NULL 1 Using index condition; Using where +2 MATERIALIZED t1 ref t1_c2 t1_c2 5 const 2 Using index +update v1 set c1=c1 + 1 +where c1 <2 +and exists (select 'X' from v1 a where a.c1 = v1.c1); +affected rows: 1 +info: Rows matched: 1 Changed: 1 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +NULL 1 +1->2 2 * +NULL 3 +NULL 4 +NULL 5 +NULL 6 +NULL 7 +NULL 8 +truncate table t1; +insert into t1 select * from tmp; +# +# Update view with EXISTS and reference to the same view in subquery +# +explain update v1 +set c1=(select max(a.c1)+10 from v1 a where a.c1 = v1.c1) +where c1 <10 and exists (select 'X' from v1 a where a.c2 = v1.c2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 range t1_c2 t1_c2 10 NULL 2 Using index condition +3 MATERIALIZED t1 ref t1_c2 t1_c2 5 const 2 Using index +2 DEPENDENT SUBQUERY t1 ref t1_c2 t1_c2 10 const,test.t1.c1 1 Using index +update v1 +set c1=(select max(a.c1)+10 from v1 a where a.c1 = v1.c1) +where c1 <10 and exists (select 'X' from v1 a where a.c2 = v1.c2); +affected rows: 2 +info: Rows matched: 2 Changed: 2 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +NULL 1 +1->11 2 * +NULL 3 +NULL 4 +2->12 5 * +NULL 6 +NULL 7 +NULL 8 +truncate table t1; +insert into t1 select * from tmp; +# +# Update with IN predicand over the updated table in WHERE +# +explain update t1 set c3=c3+10 +where c2 in (select distinct a.c2 from t1 a where t1.c1=a.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL t1_c2 NULL NULL NULL 8 Using where +1 PRIMARY a ref t1_c2 t1_c2 10 test.t1.c2,test.t1.c1 1 Using index; FirstMatch(t1) +update t1 set c3=c3+10 +where c2 in (select distinct a.c2 from t1 a where t1.c1=a.c1); +affected rows: 8 +info: Rows matched: 8 Changed: 8 Warnings: 0 +select c3 from t1; +c3 +11 +12 +13 +14 +15 +16 +17 +18 +truncate table t1; +insert into t1 select * from tmp; +# +# Update with a limit +# +explain update t1 +set c1=(select a.c3 from t1 a where a.c3 = t1.c3) limit 2; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 +2 DEPENDENT SUBQUERY a eq_ref PRIMARY PRIMARY 4 test.t1.c3 1 Using index +update t1 +set c1=(select a.c3 from t1 a where a.c3 = t1.c3) limit 2; +affected rows: 2 +info: Rows matched: 2 Changed: 2 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +1->1 1 +1->2 2 * +NULL 3 +NULL 4 +NULL 5 +NULL 6 +NULL 7 +NULL 8 +truncate table t1; +insert into t1 select * from tmp; +# +# Update with a limit and an order by +# +update t1 +set c1=(select a.c3 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 2; +affected rows: 2 +info: Rows matched: 2 Changed: 2 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +NULL 1 +NULL 2 +NULL 3 +NULL 4 +NULL 5 +NULL 6 +2->7 7 * +2->8 8 * +truncate table t1; +insert into t1 select * from tmp; +# Update with error "Subquery returns more than 1 row" +update t1 set c2=(select c2 from t1); +ERROR 21000: Subquery returns more than 1 row +select c1,c2,c3 from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +# Update with error "Subquery returns more than 1 row" +# and order by +update t1 set c2=(select c2 from t1) order by c3; +ERROR 21000: Subquery returns more than 1 row +select c1,c2,c3 from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +# Duplicate value on update a primary key +update t1 set c3=0 +where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 >= 3; +ERROR 23000: Duplicate entry '0' for key 'PRIMARY' +select c1,c2,c3 from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 0 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +truncate table t1; +insert into t1 select * from tmp; +# Duplicate value on update a primary key with ignore +update ignore t1 set c3=0 +where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 >= 3; +affected rows: 4 +info: Rows matched: 4 Changed: 4 Warnings: 0 +select c1,c2,c3 from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 0 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +truncate table t1; +insert into t1 select * from tmp; +# Duplicate value on update a primary key and limit +update t1 set c3=0 +where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 limit 2; +ERROR 23000: Duplicate entry '0' for key 'PRIMARY' +select c1,c2,c3 from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 0 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +truncate table t1; +insert into t1 select * from tmp; +# Duplicate value on update a primary key with ignore +# and limit +update ignore t1 set c3=0 +where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 limit 2; +affected rows: 2 +info: Rows matched: 2 Changed: 2 Warnings: 0 +select c1,c2,c3 from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 0 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +truncate table t1; +insert into t1 select * from tmp; +# Update no rows found +update t1 set c1=10 +where c1 <2 and exists (select 'X' from t1 a where a.c1 = t1.c1 + 10); +affected rows: 0 +info: Rows matched: 0 Changed: 0 Warnings: 0 +select c1,c2,c3 from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +truncate table t1; +insert into t1 select * from tmp; +# Update no rows changed +drop trigger trg_t1; +update t1 set c1=c1 +where c1 <2 and exists (select 'X' from t1 a where a.c1 = t1.c1); +affected rows: 0 +info: Rows matched: 3 Changed: 0 Warnings: 0 +select c1,c2,c3 from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +truncate table t1; +insert into t1 select * from tmp; +# +# Check call of after trigger +# +create or replace trigger trg_t2 after update on t1 for each row +begin +declare msg varchar(100); +if (new.c3 = 5) then +set msg=concat('in after update trigger on ',new.c3); +SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = msg; +end if; +end; +/ +update t1 set c1=2 +where c3 in (select distinct a.c3 from t1 a where a.c1=t1.c1); +ERROR 45000: in after update trigger on 5 +select c1,c2,c3 from t1; +c1 c2 c3 +2 1 1 +2 1 4 +2 2 2 +2 2 5 +2 3 3 +2 3 6 +2 4 7 +2 5 8 +truncate table t1; +insert into t1 select * from tmp; +# +# Check update with order by and after trigger +# +update t1 set c1=2 +where c3 in (select distinct a.c3 from t1 a where a.c1=t1.c1) +order by t1.c2, t1.c1; +ERROR 45000: in after update trigger on 5 +select c1,c2,c3 from t1; +c1 c2 c3 +1 3 3 +2 1 1 +2 1 4 +2 2 2 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +truncate table t1; +insert into t1 select * from tmp; +drop view v1; +# +# Check update on view with check option +# +create view v1 as select * from t1 where c2=2 with check option; +update v1 set c2=3 where c1=1; +ERROR 44000: CHECK OPTION failed `test`.`v1` +select c1,c2,c3 from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +truncate table t1; +insert into t1 select * from tmp; +update v1 set c2=(select max(c3) from v1) where c1=1; +ERROR 44000: CHECK OPTION failed `test`.`v1` +select c1,c2,c3 from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +truncate table t1; +insert into t1 select * from tmp; +update v1 set c2=(select min(va.c3) from v1 va), c1=0 where c1=1; +select c1,c2,c3 from t1; +c1 c2 c3 +0 2 2 +1 1 1 +1 3 3 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +truncate table t1; +insert into t1 select * from tmp; +drop table tmp; +drop view v1; +drop table t1; +# +# Test on dynamic columns (blob) +# +create table assets ( +item_name varchar(32) primary key, -- A common attribute for all items +dynamic_cols blob -- Dynamic columns will be stored here +); +INSERT INTO assets VALUES ('MariaDB T-shirt', +COLUMN_CREATE('color', 'blue', 'size', 'XL')); +INSERT INTO assets VALUES ('Thinkpad Laptop', +COLUMN_CREATE('color', 'black', 'price', 500)); +SELECT item_name, COLUMN_GET(dynamic_cols, 'color' as char) AS color +FROM assets; +item_name color +MariaDB T-shirt blue +Thinkpad Laptop black +UPDATE assets +SET dynamic_cols=COLUMN_ADD(dynamic_cols, 'warranty', '3 years') +WHERE item_name='Thinkpad Laptop'; +SELECT item_name, +COLUMN_GET(dynamic_cols, 'warranty' as char) AS color +FROM assets; +item_name color +MariaDB T-shirt NULL +Thinkpad Laptop 3 years +UPDATE assets +SET dynamic_cols=COLUMN_ADD(dynamic_cols, 'warranty', '4 years') +WHERE item_name in +(select b.item_name from assets b +where COLUMN_GET(b.dynamic_cols, 'color' as char) ='black'); +SELECT item_name, +COLUMN_GET(dynamic_cols, 'warranty' as char) AS color +FROM assets; +item_name color +MariaDB T-shirt NULL +Thinkpad Laptop 4 years +UPDATE assets SET dynamic_cols=COLUMN_ADD(dynamic_cols, 'warranty', +(select COLUMN_GET(b.dynamic_cols, 'color' as char) +from assets b +where assets.item_name = item_name)); +SELECT item_name, +COLUMN_GET(dynamic_cols, 'warranty' as char) AS color +FROM assets; +item_name color +MariaDB T-shirt blue +Thinkpad Laptop black +drop table assets; +# +# Test on fulltext columns +# +CREATE TABLE ft2(copy TEXT,FULLTEXT(copy)); +INSERT INTO ft2(copy) VALUES +('MySQL vs MariaDB database'), +('Oracle vs MariaDB database'), +('PostgreSQL vs MariaDB database'), +('MariaDB overview'), +('Foreign keys'), +('Primary keys'), +('Indexes'), +('Transactions'), +('Triggers'); +SELECT * FROM ft2 WHERE MATCH(copy) AGAINST('database'); +copy +MySQL vs MariaDB database +Oracle vs MariaDB database +PostgreSQL vs MariaDB database +update ft2 set copy = (select max(concat('mykeyword ',substr(b.copy,1,5))) +from ft2 b WHERE MATCH(b.copy) AGAINST('database')) +where MATCH(copy) AGAINST('keys'); +SELECT * FROM ft2 WHERE MATCH(copy) AGAINST('mykeyword'); +copy +mykeyword Postg +mykeyword Postg +drop table ft2; +set default_storage_engine=MEMORY; +create table t1 (old_c1 integer, +old_c2 integer, +c1 integer, +c2 integer, +c3 integer); +insert into t1 select c1+10,c2,c3+10, NULL, NULL from t1; +insert into t1 select c1+20,c2+1,c3+20, NULL, NULL from t1; +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze note The storage engine for the table doesn't support analyze +create view v1 as select * from t1 where c2=2; +create trigger trg_t1 before update on t1 for each row +begin +set new.old_c1=old.c1; +set new.old_c2=old.c2; +end; +/ +insert into t1(c1,c2,c3) +values (1,1,1), (1,2,2), (1,3,3), +(2,1,4), (2,2,5), (2,3,6), +(2,4,7), (2,5,8); +analyze table t1; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze note The storage engine for the table doesn't support analyze +select * from t1; +old_c1 old_c2 c1 c2 c3 +NULL NULL 1 1 1 +NULL NULL 1 2 2 +NULL NULL 1 3 3 +NULL NULL 2 1 4 +NULL NULL 2 2 5 +NULL NULL 2 3 6 +NULL NULL 2 4 7 +NULL NULL 2 5 8 +create table tmp as select * from t1; +# Test without any index +# +# Update with value from subquery on the same table +# +explain update t1 set c1=(select a.c3 from t1 a where a.c3 = t1.c3); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 8 Using where +update t1 set c1=(select a.c3 from t1 a where a.c3 = t1.c3); +affected rows: 8 +info: Rows matched: 8 Changed: 8 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +1->1 1 +1->2 2 * +1->3 3 * +2->4 4 * +2->5 5 * +2->6 6 * +2->7 7 * +2->8 8 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update with EXISTS subquery over the updated table +# in WHERE + possibly sargable condition +# +explain update t1 set c1=10 +where c1 <2 +and exists (select 'X' from t1 a where a.c1 = t1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ALL NULL NULL NULL NULL 8 +update t1 set c1=10 +where c1 <2 +and exists (select 'X' from t1 a where a.c1 = t1.c1); +affected rows: 3 +info: Rows matched: 3 Changed: 3 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +1->10 1 * +1->10 2 * +1->10 3 * +NULL 4 +NULL 5 +NULL 6 +NULL 7 +NULL 8 +truncate table t1; +insert into t1 select * from tmp; +# +# Update with EXISTS subquery over the updated table +# in WHERE + non-sargable condition +# +explain update t1 set c1=c1+10 +where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 >= 3; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ALL NULL NULL NULL NULL 8 +update t1 set c1=c1+10 +where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 >= 3; +affected rows: 4 +info: Rows matched: 4 Changed: 4 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +NULL 1 +NULL 2 +1->11 3 * +NULL 4 +NULL 5 +2->12 6 * +2->12 7 * +2->12 8 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update with order by +# +explain update t1 set c1=c1+10 +where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 order by c2; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where; Using filesort +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ALL NULL NULL NULL NULL 8 +update t1 set c1=c1+10 +where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 order by c2; +affected rows: 4 +info: Rows matched: 4 Changed: 4 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +NULL 1 +NULL 2 +1->11 3 * +NULL 4 +NULL 5 +2->12 6 * +2->12 7 * +2->12 8 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update with a reference to view in subquery +# +explain update t1 set c1=c1 +(select max(a.c2) from v1 a +where a.c1 = t1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 +2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 8 Using where +update t1 set c1=c1 +(select max(a.c2) from v1 a +where a.c1 = t1.c1); +affected rows: 8 +info: Rows matched: 8 Changed: 8 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +1->3 1 * +1->3 2 * +1->3 3 * +2->4 4 * +2->4 5 * +2->4 6 * +2->4 7 * +2->4 8 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update view +# +explain update v1 set c1=c1 + (select max(a.c2) from t1 a +where a.c1 = v1.c1) +10 where c3 > 3; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 8 Using where +update v1 set c1=c1 + (select max(a.c2) from t1 a +where a.c1 = v1.c1) +10 where c3 > 3; +affected rows: 1 +info: Rows matched: 1 Changed: 1 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +NULL 1 +NULL 2 +NULL 3 +NULL 4 +2->17 5 * +NULL 6 +NULL 7 +NULL 8 +truncate table t1; +insert into t1 select * from tmp; +# +# Update view with reference to the same view in subquery +# +explain update v1 set c1=c1 + 1 +where c1 <2 +and exists (select 'X' from v1 a where a.c1 = v1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where +2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 8 Using where +update v1 set c1=c1 + 1 +where c1 <2 +and exists (select 'X' from v1 a where a.c1 = v1.c1); +affected rows: 1 +info: Rows matched: 1 Changed: 1 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +NULL 1 +1->2 2 * +NULL 3 +NULL 4 +NULL 5 +NULL 6 +NULL 7 +NULL 8 +truncate table t1; +insert into t1 select * from tmp; +# +# Update view with EXISTS and reference to the same view in subquery +# +explain update v1 +set c1=(select max(a.c1)+10 from v1 a where a.c1 = v1.c1) +where c1 <10 and exists (select 'X' from v1 a where a.c2 = v1.c2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where +3 MATERIALIZED t1 ALL NULL NULL NULL NULL 8 Using where +2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 8 Using where +update v1 +set c1=(select max(a.c1)+10 from v1 a where a.c1 = v1.c1) +where c1 <10 and exists (select 'X' from v1 a where a.c2 = v1.c2); +affected rows: 2 +info: Rows matched: 2 Changed: 2 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +NULL 1 +1->11 2 * +NULL 3 +NULL 4 +2->12 5 * +NULL 6 +NULL 7 +NULL 8 +truncate table t1; +insert into t1 select * from tmp; +# +# Update with IN predicand over the updated table in WHERE +# +explain update t1 set c3=c3+10 +where c2 in (select distinct a.c2 from t1 a where t1.c1=a.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 +1 PRIMARY a ALL NULL NULL NULL NULL 8 Using where; FirstMatch(t1) +update t1 set c3=c3+10 +where c2 in (select distinct a.c2 from t1 a where t1.c1=a.c1); +affected rows: 8 +info: Rows matched: 8 Changed: 8 Warnings: 0 +select c3 from t1; +c3 +11 +12 +13 +14 +15 +16 +17 +18 +truncate table t1; +insert into t1 select * from tmp; +# +# Update with a limit +# +explain update t1 +set c1=(select a.c3 from t1 a where a.c3 = t1.c3) limit 2; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 8 Using where +update t1 +set c1=(select a.c3 from t1 a where a.c3 = t1.c3) limit 2; +affected rows: 2 +info: Rows matched: 2 Changed: 2 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +1->1 1 +1->2 2 * +NULL 3 +NULL 4 +NULL 5 +NULL 6 +NULL 7 +NULL 8 +truncate table t1; +insert into t1 select * from tmp; +# +# Update with a limit and an order by +# +update t1 +set c1=(select a.c3 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 2; +affected rows: 2 +info: Rows matched: 2 Changed: 2 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +NULL 1 +NULL 2 +NULL 3 +NULL 4 +NULL 5 +NULL 6 +2->7 7 * +2->8 8 * +truncate table t1; +insert into t1 select * from tmp; +# Test with an index on updated columns +create index t1_c2 on t1 (c2,c1); +analyze table t1; +Table Op Msg_type Msg_text +test.t1 analyze status Operation failed +# +# Update with value from subquery on the same table +# +explain update t1 set c1=(select a.c3 from t1 a where a.c3 = t1.c3); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 8 Using where +update t1 set c1=(select a.c3 from t1 a where a.c3 = t1.c3); +affected rows: 8 +info: Rows matched: 8 Changed: 8 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +1->1 1 +1->2 2 * +1->3 3 * +2->4 4 * +2->5 5 * +2->6 6 * +2->7 7 * +2->8 8 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update with EXISTS subquery over the updated table +# in WHERE + possibly sargable condition +# +explain update t1 set c1=10 +where c1 <2 +and exists (select 'X' from t1 a where a.c1 = t1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ALL NULL NULL NULL NULL 8 +update t1 set c1=10 +where c1 <2 +and exists (select 'X' from t1 a where a.c1 = t1.c1); +affected rows: 3 +info: Rows matched: 3 Changed: 3 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +1->10 1 * +1->10 2 * +1->10 3 * +NULL 4 +NULL 5 +NULL 6 +NULL 7 +NULL 8 +truncate table t1; +insert into t1 select * from tmp; +# +# Update with EXISTS subquery over the updated table +# in WHERE + non-sargable condition +# +explain update t1 set c1=c1+10 +where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 >= 3; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL t1_c2 NULL NULL NULL 8 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ALL t1_c2 NULL NULL NULL 8 +update t1 set c1=c1+10 +where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 >= 3; +affected rows: 4 +info: Rows matched: 4 Changed: 4 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +NULL 1 +NULL 2 +1->11 3 * +NULL 4 +NULL 5 +2->12 6 * +2->12 7 * +2->12 8 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update with order by +# +explain update t1 set c1=c1+10 +where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 order by c2; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL t1_c2 NULL NULL NULL 8 Using where; Using filesort +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ALL t1_c2 NULL NULL NULL 8 +update t1 set c1=c1+10 +where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 order by c2; +affected rows: 4 +info: Rows matched: 4 Changed: 4 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +NULL 1 +NULL 2 +1->11 3 * +NULL 4 +NULL 5 +2->12 6 * +2->12 7 * +2->12 8 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update with a reference to view in subquery +# +explain update t1 set c1=c1 +(select max(a.c2) from v1 a +where a.c1 = t1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 +2 DEPENDENT SUBQUERY t1 ref t1_c2 t1_c2 10 const,test.t1.c1 2 +update t1 set c1=c1 +(select max(a.c2) from v1 a +where a.c1 = t1.c1); +affected rows: 8 +info: Rows matched: 8 Changed: 8 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +1->3 1 * +1->3 2 * +1->3 3 * +2->4 4 * +2->4 5 * +2->4 6 * +2->4 7 * +2->4 8 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update view +# +explain update v1 set c1=c1 + (select max(a.c2) from t1 a +where a.c1 = v1.c1) +10 where c3 > 3; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL t1_c2 NULL NULL NULL 8 Using where +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 8 Using where +update v1 set c1=c1 + (select max(a.c2) from t1 a +where a.c1 = v1.c1) +10 where c3 > 3; +affected rows: 1 +info: Rows matched: 1 Changed: 1 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +NULL 1 +NULL 2 +NULL 3 +NULL 4 +2->17 5 * +NULL 6 +NULL 7 +NULL 8 +truncate table t1; +insert into t1 select * from tmp; +# +# Update view with reference to the same view in subquery +# +explain update v1 set c1=c1 + 1 +where c1 <2 +and exists (select 'X' from v1 a where a.c1 = v1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL t1_c2 NULL NULL NULL 8 Using where +2 DEPENDENT SUBQUERY t1 ref t1_c2 t1_c2 10 const,func 2 Using where +update v1 set c1=c1 + 1 +where c1 <2 +and exists (select 'X' from v1 a where a.c1 = v1.c1); +affected rows: 1 +info: Rows matched: 1 Changed: 1 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +NULL 1 +1->2 2 * +NULL 3 +NULL 4 +NULL 5 +NULL 6 +NULL 7 +NULL 8 +truncate table t1; +insert into t1 select * from tmp; +# +# Update view with EXISTS and reference to the same view in subquery +# +explain update v1 +set c1=(select max(a.c1)+10 from v1 a where a.c1 = v1.c1) +where c1 <10 and exists (select 'X' from v1 a where a.c2 = v1.c2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL t1_c2 NULL NULL NULL 8 Using where +3 MATERIALIZED t1 ALL t1_c2 NULL NULL NULL 8 Using where +2 DEPENDENT SUBQUERY t1 ref t1_c2 t1_c2 10 const,test.t1.c1 2 +update v1 +set c1=(select max(a.c1)+10 from v1 a where a.c1 = v1.c1) +where c1 <10 and exists (select 'X' from v1 a where a.c2 = v1.c2); +affected rows: 2 +info: Rows matched: 2 Changed: 2 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +NULL 1 +1->11 2 * +NULL 3 +NULL 4 +2->12 5 * +NULL 6 +NULL 7 +NULL 8 +truncate table t1; +insert into t1 select * from tmp; +# +# Update with IN predicand over the updated table in WHERE +# +explain update t1 set c3=c3+10 +where c2 in (select distinct a.c2 from t1 a where t1.c1=a.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL t1_c2 NULL NULL NULL 8 Using where +1 PRIMARY a ref t1_c2 t1_c2 10 test.t1.c2,test.t1.c1 2 FirstMatch(t1) +update t1 set c3=c3+10 +where c2 in (select distinct a.c2 from t1 a where t1.c1=a.c1); +affected rows: 8 +info: Rows matched: 8 Changed: 8 Warnings: 0 +select c3 from t1; +c3 +11 +12 +13 +14 +15 +16 +17 +18 +truncate table t1; +insert into t1 select * from tmp; +# +# Update with a limit +# +explain update t1 +set c1=(select a.c3 from t1 a where a.c3 = t1.c3) limit 2; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 8 Using where +update t1 +set c1=(select a.c3 from t1 a where a.c3 = t1.c3) limit 2; +affected rows: 2 +info: Rows matched: 2 Changed: 2 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +1->1 1 +1->2 2 * +NULL 3 +NULL 4 +NULL 5 +NULL 6 +NULL 7 +NULL 8 +truncate table t1; +insert into t1 select * from tmp; +# +# Update with a limit and an order by +# +update t1 +set c1=(select a.c3 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 2; +affected rows: 2 +info: Rows matched: 2 Changed: 2 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +NULL 1 +NULL 2 +NULL 3 +NULL 4 +NULL 5 +NULL 6 +2->7 7 * +2->8 8 * +truncate table t1; +insert into t1 select * from tmp; +# Test with an index on updated columns +create index t1_c3 on t1 (c3); +analyze table t1; +Table Op Msg_type Msg_text +test.t1 analyze status Operation failed +# +# Update with value from subquery on the same table +# +explain update t1 set c1=(select a.c3 from t1 a where a.c3 = t1.c3); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 +2 DEPENDENT SUBQUERY a ref t1_c3 t1_c3 5 test.t1.c3 2 +update t1 set c1=(select a.c3 from t1 a where a.c3 = t1.c3); +affected rows: 8 +info: Rows matched: 8 Changed: 8 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +1->1 1 +1->2 2 * +1->3 3 * +2->4 4 * +2->5 5 * +2->6 6 * +2->7 7 * +2->8 8 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update with EXISTS subquery over the updated table +# in WHERE + possibly sargable condition +# +explain update t1 set c1=10 +where c1 <2 +and exists (select 'X' from t1 a where a.c1 = t1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ALL NULL NULL NULL NULL 8 +update t1 set c1=10 +where c1 <2 +and exists (select 'X' from t1 a where a.c1 = t1.c1); +affected rows: 3 +info: Rows matched: 3 Changed: 3 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +1->10 1 * +1->10 2 * +1->10 3 * +NULL 4 +NULL 5 +NULL 6 +NULL 7 +NULL 8 +truncate table t1; +insert into t1 select * from tmp; +# +# Update with EXISTS subquery over the updated table +# in WHERE + non-sargable condition +# +explain update t1 set c1=c1+10 +where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 >= 3; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL t1_c2 NULL NULL NULL 8 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ALL t1_c2 NULL NULL NULL 8 +update t1 set c1=c1+10 +where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 >= 3; +affected rows: 4 +info: Rows matched: 4 Changed: 4 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +NULL 1 +NULL 2 +1->11 3 * +NULL 4 +NULL 5 +2->12 6 * +2->12 7 * +2->12 8 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update with order by +# +explain update t1 set c1=c1+10 +where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 order by c2; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL t1_c2 NULL NULL NULL 8 Using where; Using filesort +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ALL t1_c2 NULL NULL NULL 8 +update t1 set c1=c1+10 +where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 order by c2; +affected rows: 4 +info: Rows matched: 4 Changed: 4 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +NULL 1 +NULL 2 +1->11 3 * +NULL 4 +NULL 5 +2->12 6 * +2->12 7 * +2->12 8 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update with a reference to view in subquery +# +explain update t1 set c1=c1 +(select max(a.c2) from v1 a +where a.c1 = t1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 +2 DEPENDENT SUBQUERY t1 ref t1_c2 t1_c2 10 const,test.t1.c1 2 +update t1 set c1=c1 +(select max(a.c2) from v1 a +where a.c1 = t1.c1); +affected rows: 8 +info: Rows matched: 8 Changed: 8 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +1->3 1 * +1->3 2 * +1->3 3 * +2->4 4 * +2->4 5 * +2->4 6 * +2->4 7 * +2->4 8 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update view +# +explain update v1 set c1=c1 + (select max(a.c2) from t1 a +where a.c1 = v1.c1) +10 where c3 > 3; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL t1_c2,t1_c3 NULL NULL NULL 8 Using where +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 8 Using where +update v1 set c1=c1 + (select max(a.c2) from t1 a +where a.c1 = v1.c1) +10 where c3 > 3; +affected rows: 1 +info: Rows matched: 1 Changed: 1 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +NULL 1 +NULL 2 +NULL 3 +NULL 4 +2->17 5 * +NULL 6 +NULL 7 +NULL 8 +truncate table t1; +insert into t1 select * from tmp; +# +# Update view with reference to the same view in subquery +# +explain update v1 set c1=c1 + 1 +where c1 <2 +and exists (select 'X' from v1 a where a.c1 = v1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL t1_c2 NULL NULL NULL 8 Using where +2 DEPENDENT SUBQUERY t1 ref t1_c2 t1_c2 10 const,func 2 Using where +update v1 set c1=c1 + 1 +where c1 <2 +and exists (select 'X' from v1 a where a.c1 = v1.c1); +affected rows: 1 +info: Rows matched: 1 Changed: 1 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +NULL 1 +1->2 2 * +NULL 3 +NULL 4 +NULL 5 +NULL 6 +NULL 7 +NULL 8 +truncate table t1; +insert into t1 select * from tmp; +# +# Update view with EXISTS and reference to the same view in subquery +# +explain update v1 +set c1=(select max(a.c1)+10 from v1 a where a.c1 = v1.c1) +where c1 <10 and exists (select 'X' from v1 a where a.c2 = v1.c2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL t1_c2 NULL NULL NULL 8 Using where +3 MATERIALIZED t1 ALL t1_c2 NULL NULL NULL 8 Using where +2 DEPENDENT SUBQUERY t1 ref t1_c2 t1_c2 10 const,test.t1.c1 2 +update v1 +set c1=(select max(a.c1)+10 from v1 a where a.c1 = v1.c1) +where c1 <10 and exists (select 'X' from v1 a where a.c2 = v1.c2); +affected rows: 2 +info: Rows matched: 2 Changed: 2 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +NULL 1 +1->11 2 * +NULL 3 +NULL 4 +2->12 5 * +NULL 6 +NULL 7 +NULL 8 +truncate table t1; +insert into t1 select * from tmp; +# +# Update with IN predicand over the updated table in WHERE +# +explain update t1 set c3=c3+10 +where c2 in (select distinct a.c2 from t1 a where t1.c1=a.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL t1_c2 NULL NULL NULL 8 Using where +1 PRIMARY a ref t1_c2 t1_c2 10 test.t1.c2,test.t1.c1 2 FirstMatch(t1) +update t1 set c3=c3+10 +where c2 in (select distinct a.c2 from t1 a where t1.c1=a.c1); +affected rows: 8 +info: Rows matched: 8 Changed: 8 Warnings: 0 +select c3 from t1; +c3 +11 +12 +13 +14 +15 +16 +17 +18 +truncate table t1; +insert into t1 select * from tmp; +# +# Update with a limit +# +explain update t1 +set c1=(select a.c3 from t1 a where a.c3 = t1.c3) limit 2; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 +2 DEPENDENT SUBQUERY a ref t1_c3 t1_c3 5 test.t1.c3 2 +update t1 +set c1=(select a.c3 from t1 a where a.c3 = t1.c3) limit 2; +affected rows: 2 +info: Rows matched: 2 Changed: 2 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +1->1 1 +1->2 2 * +NULL 3 +NULL 4 +NULL 5 +NULL 6 +NULL 7 +NULL 8 +truncate table t1; +insert into t1 select * from tmp; +# +# Update with a limit and an order by +# +update t1 +set c1=(select a.c3 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 2; +affected rows: 2 +info: Rows matched: 2 Changed: 2 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +NULL 1 +NULL 2 +NULL 3 +NULL 4 +NULL 5 +NULL 6 +2->7 7 * +2->8 8 * +truncate table t1; +insert into t1 select * from tmp; +# Test with a primary key on updated columns +drop index t1_c3 on t1; +alter table t1 add primary key (c3); +analyze table t1; +Table Op Msg_type Msg_text +test.t1 analyze status Operation failed +# +# Update with value from subquery on the same table +# +explain update t1 set c1=(select a.c3 from t1 a where a.c3 = t1.c3); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 +2 DEPENDENT SUBQUERY a eq_ref PRIMARY PRIMARY 4 test.t1.c3 1 +update t1 set c1=(select a.c3 from t1 a where a.c3 = t1.c3); +affected rows: 8 +info: Rows matched: 8 Changed: 8 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +1->1 1 +1->2 2 * +1->3 3 * +2->4 4 * +2->5 5 * +2->6 6 * +2->7 7 * +2->8 8 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update with EXISTS subquery over the updated table +# in WHERE + possibly sargable condition +# +explain update t1 set c1=10 +where c1 <2 +and exists (select 'X' from t1 a where a.c1 = t1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ALL NULL NULL NULL NULL 8 +update t1 set c1=10 +where c1 <2 +and exists (select 'X' from t1 a where a.c1 = t1.c1); +affected rows: 3 +info: Rows matched: 3 Changed: 3 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +1->10 1 * +1->10 2 * +1->10 3 * +NULL 4 +NULL 5 +NULL 6 +NULL 7 +NULL 8 +truncate table t1; +insert into t1 select * from tmp; +# +# Update with EXISTS subquery over the updated table +# in WHERE + non-sargable condition +# +explain update t1 set c1=c1+10 +where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 >= 3; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL t1_c2 NULL NULL NULL 8 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ALL t1_c2 NULL NULL NULL 8 +update t1 set c1=c1+10 +where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 >= 3; +affected rows: 4 +info: Rows matched: 4 Changed: 4 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +NULL 1 +NULL 2 +1->11 3 * +NULL 4 +NULL 5 +2->12 6 * +2->12 7 * +2->12 8 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update with order by +# +explain update t1 set c1=c1+10 +where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 order by c2; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL t1_c2 NULL NULL NULL 8 Using where; Using filesort +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ALL t1_c2 NULL NULL NULL 8 +update t1 set c1=c1+10 +where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 order by c2; +affected rows: 4 +info: Rows matched: 4 Changed: 4 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +NULL 1 +NULL 2 +1->11 3 * +NULL 4 +NULL 5 +2->12 6 * +2->12 7 * +2->12 8 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update with a reference to view in subquery +# +explain update t1 set c1=c1 +(select max(a.c2) from v1 a +where a.c1 = t1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 +2 DEPENDENT SUBQUERY t1 ref t1_c2 t1_c2 10 const,test.t1.c1 2 +update t1 set c1=c1 +(select max(a.c2) from v1 a +where a.c1 = t1.c1); +affected rows: 8 +info: Rows matched: 8 Changed: 8 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +1->3 1 * +1->3 2 * +1->3 3 * +2->4 4 * +2->4 5 * +2->4 6 * +2->4 7 * +2->4 8 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update view +# +explain update v1 set c1=c1 + (select max(a.c2) from t1 a +where a.c1 = v1.c1) +10 where c3 > 3; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL PRIMARY,t1_c2 NULL NULL NULL 8 Using where +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 8 Using where +update v1 set c1=c1 + (select max(a.c2) from t1 a +where a.c1 = v1.c1) +10 where c3 > 3; +affected rows: 1 +info: Rows matched: 1 Changed: 1 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +NULL 1 +NULL 2 +NULL 3 +NULL 4 +2->17 5 * +NULL 6 +NULL 7 +NULL 8 +truncate table t1; +insert into t1 select * from tmp; +# +# Update view with reference to the same view in subquery +# +explain update v1 set c1=c1 + 1 +where c1 <2 +and exists (select 'X' from v1 a where a.c1 = v1.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL t1_c2 NULL NULL NULL 8 Using where +2 DEPENDENT SUBQUERY t1 ref t1_c2 t1_c2 10 const,func 2 Using where +update v1 set c1=c1 + 1 +where c1 <2 +and exists (select 'X' from v1 a where a.c1 = v1.c1); +affected rows: 1 +info: Rows matched: 1 Changed: 1 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +NULL 1 +1->2 2 * +NULL 3 +NULL 4 +NULL 5 +NULL 6 +NULL 7 +NULL 8 +truncate table t1; +insert into t1 select * from tmp; +# +# Update view with EXISTS and reference to the same view in subquery +# +explain update v1 +set c1=(select max(a.c1)+10 from v1 a where a.c1 = v1.c1) +where c1 <10 and exists (select 'X' from v1 a where a.c2 = v1.c2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL t1_c2 NULL NULL NULL 8 Using where +3 MATERIALIZED t1 ALL t1_c2 NULL NULL NULL 8 Using where +2 DEPENDENT SUBQUERY t1 ref t1_c2 t1_c2 10 const,test.t1.c1 2 +update v1 +set c1=(select max(a.c1)+10 from v1 a where a.c1 = v1.c1) +where c1 <10 and exists (select 'X' from v1 a where a.c2 = v1.c2); +affected rows: 2 +info: Rows matched: 2 Changed: 2 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +NULL 1 +1->11 2 * +NULL 3 +NULL 4 +2->12 5 * +NULL 6 +NULL 7 +NULL 8 +truncate table t1; +insert into t1 select * from tmp; +# +# Update with IN predicand over the updated table in WHERE +# +explain update t1 set c3=c3+10 +where c2 in (select distinct a.c2 from t1 a where t1.c1=a.c1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL t1_c2 NULL NULL NULL 8 Using where +1 PRIMARY a ref t1_c2 t1_c2 10 test.t1.c2,test.t1.c1 2 FirstMatch(t1) +update t1 set c3=c3+10 +where c2 in (select distinct a.c2 from t1 a where t1.c1=a.c1); +affected rows: 8 +info: Rows matched: 8 Changed: 8 Warnings: 0 +select c3 from t1; +c3 +11 +12 +13 +14 +15 +16 +17 +18 +truncate table t1; +insert into t1 select * from tmp; +# +# Update with a limit +# +explain update t1 +set c1=(select a.c3 from t1 a where a.c3 = t1.c3) limit 2; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 +2 DEPENDENT SUBQUERY a eq_ref PRIMARY PRIMARY 4 test.t1.c3 1 +update t1 +set c1=(select a.c3 from t1 a where a.c3 = t1.c3) limit 2; +affected rows: 2 +info: Rows matched: 2 Changed: 2 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +1->1 1 +1->2 2 * +NULL 3 +NULL 4 +NULL 5 +NULL 6 +NULL 7 +NULL 8 +truncate table t1; +insert into t1 select * from tmp; +# +# Update with a limit and an order by +# +update t1 +set c1=(select a.c3 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 2; +affected rows: 2 +info: Rows matched: 2 Changed: 2 Warnings: 0 +select concat(old_c1,'->',c1),c3, +case when c1 != old_c1 then '*' else ' ' end "Changed" from t1; +concat(old_c1,'->',c1) c3 Changed +NULL 1 +NULL 2 +NULL 3 +NULL 4 +NULL 5 +NULL 6 +2->7 7 * +2->8 8 * +truncate table t1; +insert into t1 select * from tmp; +# Update with error "Subquery returns more than 1 row" +update t1 set c2=(select c2 from t1); +ERROR 21000: Subquery returns more than 1 row +select c1,c2,c3 from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +# Update with error "Subquery returns more than 1 row" +# and order by +update t1 set c2=(select c2 from t1) order by c3; +ERROR 21000: Subquery returns more than 1 row +select c1,c2,c3 from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +# Duplicate value on update a primary key +update t1 set c3=0 +where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 >= 3; +ERROR 23000: Duplicate entry '0' for key 'PRIMARY' +select c1,c2,c3 from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 0 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +truncate table t1; +insert into t1 select * from tmp; +# Duplicate value on update a primary key with ignore +update ignore t1 set c3=0 +where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 >= 3; +affected rows: 4 +info: Rows matched: 4 Changed: 4 Warnings: 0 +select c1,c2,c3 from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 0 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +truncate table t1; +insert into t1 select * from tmp; +# Duplicate value on update a primary key and limit +update t1 set c3=0 +where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 limit 2; +ERROR 23000: Duplicate entry '0' for key 'PRIMARY' +select c1,c2,c3 from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 0 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +truncate table t1; +insert into t1 select * from tmp; +# Duplicate value on update a primary key with ignore +# and limit +update ignore t1 set c3=0 +where exists (select 'X' from t1 a where a.c2 = t1.c2) +and c2 >= 3 limit 2; +affected rows: 2 +info: Rows matched: 2 Changed: 2 Warnings: 0 +select c1,c2,c3 from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 0 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +truncate table t1; +insert into t1 select * from tmp; +# Update no rows found +update t1 set c1=10 +where c1 <2 and exists (select 'X' from t1 a where a.c1 = t1.c1 + 10); +affected rows: 0 +info: Rows matched: 0 Changed: 0 Warnings: 0 +select c1,c2,c3 from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +truncate table t1; +insert into t1 select * from tmp; +# Update no rows changed +drop trigger trg_t1; +update t1 set c1=c1 +where c1 <2 and exists (select 'X' from t1 a where a.c1 = t1.c1); +affected rows: 0 +info: Rows matched: 3 Changed: 0 Warnings: 0 +select c1,c2,c3 from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +truncate table t1; +insert into t1 select * from tmp; +# +# Check call of after trigger +# +create or replace trigger trg_t2 after update on t1 for each row +begin +declare msg varchar(100); +if (new.c3 = 5) then +set msg=concat('in after update trigger on ',new.c3); +SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = msg; +end if; +end; +/ +update t1 set c1=2 +where c3 in (select distinct a.c3 from t1 a where a.c1=t1.c1); +ERROR 45000: in after update trigger on 5 +select c1,c2,c3 from t1; +c1 c2 c3 +2 1 1 +2 1 4 +2 2 2 +2 2 5 +2 3 3 +2 3 6 +2 4 7 +2 5 8 +truncate table t1; +insert into t1 select * from tmp; +# +# Check update with order by and after trigger +# +update t1 set c1=2 +where c3 in (select distinct a.c3 from t1 a where a.c1=t1.c1) +order by t1.c2, t1.c1; +ERROR 45000: in after update trigger on 5 +select c1,c2,c3 from t1; +c1 c2 c3 +1 3 3 +2 1 1 +2 1 4 +2 2 2 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +truncate table t1; +insert into t1 select * from tmp; +drop view v1; +# +# Check update on view with check option +# +create view v1 as select * from t1 where c2=2 with check option; +update v1 set c2=3 where c1=1; +ERROR 44000: CHECK OPTION failed `test`.`v1` +select c1,c2,c3 from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +truncate table t1; +insert into t1 select * from tmp; +update v1 set c2=(select max(c3) from v1) where c1=1; +ERROR 44000: CHECK OPTION failed `test`.`v1` +select c1,c2,c3 from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 3 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +truncate table t1; +insert into t1 select * from tmp; +update v1 set c2=(select min(va.c3) from v1 va), c1=0 where c1=1; +select c1,c2,c3 from t1; +c1 c2 c3 +0 2 2 +1 1 1 +1 3 3 +2 1 4 +2 2 5 +2 3 6 +2 4 7 +2 5 8 +truncate table t1; +insert into t1 select * from tmp; +drop table tmp; +drop view v1; +drop table t1; +set @@default_storage_engine=@save_default_engine; # # Test with MyISAM # -create table t1 (old_c1 integer, old_c2 integer,c1 integer, c2 integer, c3 integer) engine=MyISAM; +create table t1 (old_c1 integer, +old_c2 integer, +c1 integer, +c2 integer, +c3 integer) engine=MyISAM; insert t1 (c1,c2,c3) select 0,seq,seq%10 from seq_1_to_500; insert t1 (c1,c2,c3) select 1,seq,seq%10 from seq_1_to_400; insert t1 (c1,c2,c3) select 2,seq,seq%10 from seq_1_to_300; @@ -1193,11 +5895,13 @@ count(*) 140 drop table t1; # -# Test error on multi_update conversion on view with order by or limit +# Test error on multi_update conversion on view +# with order by or limit # create table t1 (c1 integer) engine=InnoDb; create table t2 (c1 integer) engine=InnoDb; -create view v1 as select t1.c1 as "t1c1" ,t2.c1 as "t2c1" from t1,t2 where t1.c1=t2.c1; +create view v1 as select t1.c1 as "t1c1" ,t2.c1 as "t2c1" + from t1,t2 where t1.c1=t2.c1; update v1 set t1c1=2 order by 1; update v1 set t1c1=2 limit 1; drop table t1; diff --git a/mysql-test/main/update_use_source.test b/mysql-test/main/update_use_source.test index 3c32a25..65dfa8b 100644 --- a/mysql-test/main/update_use_source.test +++ b/mysql-test/main/update_use_source.test @@ -2,221 +2,35 @@ --source include/have_innodb.inc --source include/no_valgrind_without_big.inc -create table t1 (old_c1 integer, old_c2 integer,c1 integer, c2 integer, c3 integer) engine=InnoDB STATS_PERSISTENT=0; -create view v1 as select * from t1 where c2=2; -delimiter /; -create trigger trg_t1 before update on t1 for each row -begin - set new.old_c1=old.c1; - set new.old_c2=old.c2; -end; -/ -delimiter ;/ +set @save_default_engine=@@default_storage_engine; -insert into t1(c1,c2,c3) values (1,1,1); -insert into t1(c1,c2,c3) values (1,2,2); -insert into t1(c1,c2,c3) values (1,3,3); -insert into t1(c1,c2,c3) values (2,1,4); -insert into t1(c1,c2,c3) values (2,2,5); -insert into t1(c1,c2,c3) values (2,3,6); -insert into t1(c1,c2,c3) values (2,4,7); -insert into t1(c1,c2,c3) values (2,5,8); - -commit; -select * from t1; - ---echo Test without any index +set global innodb_stats_persistent=1; +set default_storage_engine=InnoDB; --source include/update_use_source.inc +--source include/update_use_source_ext.inc ---echo Test with an index on updated columns -create index t1_c2 on t1 (c2,c1); +set default_storage_engine=Aria; --source include/update_use_source.inc +--source include/update_use_source_ext.inc ---echo Test with an index on updated columns -create index t1_c3 on t1 (c3); +set default_storage_engine=MyISAM; --source include/update_use_source.inc +--source include/update_use_source_ext.inc ---echo Test with a primary key on updated columns -drop index t1_c3 on t1; -alter table t1 add primary key (c3); +set default_storage_engine=MEMORY; --source include/update_use_source.inc ---echo # Update with error "Subquery returns more than 1 row" ---error ER_SUBQUERY_NO_1_ROW -update t1 set c2=(select c2 from t1); - ---echo # Update with error "Subquery returns more than 1 row" and order by ---error ER_SUBQUERY_NO_1_ROW -update t1 set c2=(select c2 from t1) order by c3; - --- echo Duplicate value on update a primary key -start transaction; ---error ER_DUP_ENTRY -update t1 set c3=0 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 >= 3; -rollback; - --- echo Duplicate value on update a primary key with ignore -start transaction; ---enable_info ONCE -update ignore t1 set c3=0 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 >= 3; -rollback; - --- echo Duplicate value on update a primary key and limit -start transaction; ---error ER_DUP_ENTRY -update t1 set c3=0 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 >= 3 limit 2; -rollback; - --- echo Duplicate value on update a primary key with ignore and limit -start transaction; ---enable_info ONCE -update ignore t1 set c3=0 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 >= 3 limit 2; -rollback; - ---echo # Update no rows found ---enable_info ONCE -update t1 - set c1=10 - where c1 <2 - and exists (select 'X' - from t1 a - where a.c1 = t1.c1 + 10); - ---echo # Update no rows changed -drop trigger trg_t1; -start transaction; ---enable_info ONCE -update t1 - set c1=c1 - where c1 <2 - and exists (select 'X' - from t1 a - where a.c1 = t1.c1); -rollback; - ---echo # ---echo # Check call of after trigger ---echo # - -delimiter /; -create or replace trigger trg_t2 after update on t1 for each row -begin - declare msg varchar(100); - if (new.c3 = 5) then - set msg=concat('in after update trigger on ',new.c3); - SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = msg; - end if; -end; -/ -delimiter ;/ ---error 1644 -update t1 set c1=2 where c3 in (select distinct a.c3 from t1 a where a.c1=t1.c1); - ---echo # ---echo # Check update with order by and after trigger ---echo # - ---error 1644 -update t1 set c1=2 where c3 in (select distinct a.c3 from t1 a where a.c1=t1.c1) order by t1.c2; - -drop view v1; ---echo # ---echo # Check update on view with check option ---echo # - -create view v1 as select * from t1 where c2=2 with check option; - -start transaction; --- error 1369 -update v1 set c2=3 where c1=1; -rollback; - -start transaction; --- error 1369 -update v1 set c2=(select max(c3) from v1) where c1=1; -rollback; - -start transaction; -update v1 set c2=(select min(va.c3) from v1 va), c1=0 where c1=1; -rollback; - -drop view v1; -drop table t1; - ---echo # ---echo # Test with a temporary table ---echo # - -create temporary table t1 (c1 integer, c2 integer, c3 integer) engine=InnoDb; -insert into t1(c1,c2,c3) values (1,1,1); -insert into t1(c1,c2,c3) values (1,2,2); -insert into t1(c1,c2,c3) values (1,3,3); -insert into t1(c1,c2,c3) values (2,1,4); -insert into t1(c1,c2,c3) values (2,2,5); -insert into t1(c1,c2,c3) values (2,3,6); -insert into t1(c1,c2,c3) values (2,4,7); -insert into t1(c1,c2,c3) values (2,5,8); - -start transaction; ---enable_info ONCE -update t1 - set c1=(select a.c2 - from t1 a - where a.c3 = t1.c3) limit 3; -select * from t1 ; -rollback; -drop table t1; - ---echo # ---echo # Test on dynamic columns (blob) ---echo # - -create table assets ( - item_name varchar(32) primary key, -- A common attribute for all items - dynamic_cols blob -- Dynamic columns will be stored here -); -INSERT INTO assets VALUES ('MariaDB T-shirt', COLUMN_CREATE('color', 'blue', 'size', 'XL')); -INSERT INTO assets VALUES ('Thinkpad Laptop', COLUMN_CREATE('color', 'black', 'price', 500)); -SELECT item_name, COLUMN_GET(dynamic_cols, 'color' as char) AS color FROM assets; -UPDATE assets SET dynamic_cols=COLUMN_ADD(dynamic_cols, 'warranty', '3 years') WHERE item_name='Thinkpad Laptop'; -SELECT item_name, COLUMN_GET(dynamic_cols, 'warranty' as char) AS color FROM assets; -UPDATE assets SET dynamic_cols=COLUMN_ADD(dynamic_cols, 'warranty', '4 years') - WHERE item_name in (select b.item_name - from assets b - where COLUMN_GET(b.dynamic_cols, 'color' as char) ='black'); -SELECT item_name, COLUMN_GET(dynamic_cols, 'warranty' as char) AS color FROM assets; - -UPDATE assets SET dynamic_cols=COLUMN_ADD(dynamic_cols, 'warranty', (select COLUMN_GET(b.dynamic_cols, 'color' as char) - from assets b - where assets.item_name = item_name)); -SELECT item_name, COLUMN_GET(dynamic_cols, 'warranty' as char) AS color FROM assets; -drop table assets ; - ---echo # ---echo # Test on fulltext columns ---echo # -CREATE TABLE ft2(copy TEXT,FULLTEXT(copy)) ENGINE=MyISAM; -INSERT INTO ft2(copy) VALUES - ('MySQL vs MariaDB database'), - ('Oracle vs MariaDB database'), - ('PostgreSQL vs MariaDB database'), - ('MariaDB overview'), - ('Foreign keys'), - ('Primary keys'), - ('Indexes'), - ('Transactions'), - ('Triggers'); -SELECT * FROM ft2 WHERE MATCH(copy) AGAINST('database'); -update ft2 set copy = (select max(concat('mykeyword ',substr(b.copy,1,5))) from ft2 b WHERE MATCH(b.copy) AGAINST('database')) - where MATCH(copy) AGAINST('keys'); -SELECT * FROM ft2 WHERE MATCH(copy) AGAINST('mykeyword'); -drop table ft2; +set @@default_storage_engine=@save_default_engine; --echo # --echo # Test with MyISAM --echo # -create table t1 (old_c1 integer, old_c2 integer,c1 integer, c2 integer, c3 integer) engine=MyISAM; +create table t1 (old_c1 integer, + old_c2 integer, + c1 integer, + c2 integer, + c3 integer) engine=MyISAM; insert t1 (c1,c2,c3) select 0,seq,seq%10 from seq_1_to_500; insert t1 (c1,c2,c3) select 1,seq,seq%10 from seq_1_to_400; insert t1 (c1,c2,c3) select 2,seq,seq%10 from seq_1_to_300; @@ -232,12 +46,14 @@ drop table t1; --echo # ---echo # Test error on multi_update conversion on view with order by or limit +--echo # Test error on multi_update conversion on view +--echo # with order by or limit --echo # create table t1 (c1 integer) engine=InnoDb; create table t2 (c1 integer) engine=InnoDb; -create view v1 as select t1.c1 as "t1c1" ,t2.c1 as "t2c1" from t1,t2 where t1.c1=t2.c1; +create view v1 as select t1.c1 as "t1c1" ,t2.c1 as "t2c1" + from t1,t2 where t1.c1=t2.c1; # 'order by 1' should be considered as in 'select * from v1 order 1' update v1 set t1c1=2 order by 1; update v1 set t1c1=2 limit 1; diff --git a/mysql-test/suite/json/r/json_table.result b/mysql-test/suite/json/r/json_table.result index 4495735..059a2fe 100644 --- a/mysql-test/suite/json/r/json_table.result +++ b/mysql-test/suite/json/r/json_table.result @@ -1143,3 +1143,104 @@ ERROR 42000: You have an error in your SQL syntax; check the manual that corresp # # End of 10.9 tests # +# +# MDEV-29390: Improve coverage for UPDATE and DELETE statements in MTR test suites +# +# Multi-update with JSON_TABLE +create table t1 ( name varchar(10), +color varchar(10), +price decimal(8,2), +instock BOOLEAN); +insert into t1 values ("Laptop", "black", 20000, 1); +insert into t1 values ("Jacket", "brown", 5000, 1); +insert into t1 values ("Jeans", "blue", 5000, 1); +select * from t1; +name color price instock +Laptop black 20000.00 1 +Jacket brown 5000.00 1 +Jeans blue 5000.00 1 +set @json=' +[ + {"name":"Laptop", "color":"black", "price":"1000", "ordered":"3"}, + {"name":"Jeans", "color":"blue", "ordered":"0"}, + {"name":"Phone", "color":"red", "ordered":"0"} +]'; +select * from json_table(@json, '$[*]' +columns( +name varchar(10) path '$.name', +color varchar(10) path '$.color', +price decimal(8,2) path '$.price', +ordered boolean path '$.ordered' ) +) as jt; +name color price ordered +Laptop black 1000.00 3 +Jeans blue NULL 0 +Phone red NULL 0 +explain update t1, JSON_TABLE(@json,'$[*]' +COLUMNS ( +name varchar(10) path '$.name', +color varchar(10) path '$.color', +price decimal(8,2) path '$.price', +ordered boolean path '$.ordered' + )) AS jt1 +SET t1.instock=0 where t1.name=jt1.name and jt1.ordered=3; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 +1 SIMPLE jt1 ALL NULL NULL NULL NULL 40 Table function: json_table; Using where +update t1, JSON_TABLE(@json,'$[*]' +COLUMNS ( +name varchar(10) path '$.name', +color varchar(10) path '$.color', +price decimal(8,2) path '$.price', +ordered boolean path '$.ordered' + )) AS jt1 +SET t1.instock=0 where t1.name=jt1.name and jt1.ordered=2; +select * from t1; +name color price instock +Laptop black 20000.00 1 +Jacket brown 5000.00 1 +Jeans blue 5000.00 1 +explain update t1 +SET t1.instock=2 where t1.name in ( +select jt1.name from json_table(@json, '$[*]' +columns( +name varchar(10) path '$.name', +color varchar(10) path '$.color', +price decimal(8,2) path '$.price', +ordered boolean path '$.ordered' ) +) as jt1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 3 +1 PRIMARY jt1 ALL NULL NULL NULL NULL 40 Table function: json_table; Using where; FirstMatch(t1) +update t1 +SET t1.instock=2 where t1.name in ( +select jt1.name from json_table(@json, '$[*]' +columns( +name varchar(10) path '$.name', +color varchar(10) path '$.color', +price decimal(8,2) path '$.price', +ordered boolean path '$.ordered' ) +) as jt1); +select * from t1; +name color price instock +Laptop black 20000.00 2 +Jacket brown 5000.00 1 +Jeans blue 5000.00 2 +update t1, JSON_TABLE(@json,'$[*]' +COLUMNS ( +name varchar(10) path '$.name', +color varchar(10) path '$.color', +price decimal(8,2) path '$.price', +ordered boolean path '$.ordered' + )) AS jt1 +SET t1.instock=0, jt1.ordered=1 where t1.name=jt1.name; +ERROR HY000: The target table jt1 of the UPDATE is not updatable +select * from t1; +name color price instock +Laptop black 20000.00 2 +Jacket brown 5000.00 1 +Jeans blue 5000.00 2 +drop table t1; +# +# End of 11.0 tests +# diff --git a/mysql-test/suite/json/t/json_table.test b/mysql-test/suite/json/t/json_table.test index 05db8f6..8612ab9 100644 --- a/mysql-test/suite/json/t/json_table.test +++ b/mysql-test/suite/json/t/json_table.test @@ -995,3 +995,97 @@ COLUMNS --echo # --echo # End of 10.9 tests --echo # + +--echo # +--echo # MDEV-29390: Improve coverage for UPDATE and DELETE statements in MTR test suites +--echo # + +--echo # Multi-update with JSON_TABLE + +create table t1 ( name varchar(10), + color varchar(10), + price decimal(8,2), + instock BOOLEAN); + +insert into t1 values ("Laptop", "black", 20000, 1); +insert into t1 values ("Jacket", "brown", 5000, 1); +insert into t1 values ("Jeans", "blue", 5000, 1); + +select * from t1; + +set @json=' +[ + {"name":"Laptop", "color":"black", "price":"1000", "ordered":"3"}, + {"name":"Jeans", "color":"blue", "ordered":"0"}, + {"name":"Phone", "color":"red", "ordered":"0"} +]'; + +select * from json_table(@json, '$[*]' + columns( + name varchar(10) path '$.name', + color varchar(10) path '$.color', + price decimal(8,2) path '$.price', + ordered boolean path '$.ordered' ) +) as jt; + +explain update t1, JSON_TABLE(@json,'$[*]' + COLUMNS ( + name varchar(10) path '$.name', + color varchar(10) path '$.color', + price decimal(8,2) path '$.price', + ordered boolean path '$.ordered' + )) AS jt1 + SET t1.instock=0 where t1.name=jt1.name and jt1.ordered=3; + +update t1, JSON_TABLE(@json,'$[*]' + COLUMNS ( + name varchar(10) path '$.name', + color varchar(10) path '$.color', + price decimal(8,2) path '$.price', + ordered boolean path '$.ordered' + )) AS jt1 + SET t1.instock=0 where t1.name=jt1.name and jt1.ordered=2; + +select * from t1; + +explain update t1 + SET t1.instock=2 where t1.name in ( + select jt1.name from json_table(@json, '$[*]' + columns( + name varchar(10) path '$.name', + color varchar(10) path '$.color', + price decimal(8,2) path '$.price', + ordered boolean path '$.ordered' ) + ) as jt1); + + +update t1 + SET t1.instock=2 where t1.name in ( + select jt1.name from json_table(@json, '$[*]' + columns( + name varchar(10) path '$.name', + color varchar(10) path '$.color', + price decimal(8,2) path '$.price', + ordered boolean path '$.ordered' ) + ) as jt1); + +select * from t1; + + +-- error ER_NON_UPDATABLE_TABLE +update t1, JSON_TABLE(@json,'$[*]' + COLUMNS ( + name varchar(10) path '$.name', + color varchar(10) path '$.color', + price decimal(8,2) path '$.price', + ordered boolean path '$.ordered' + )) AS jt1 + SET t1.instock=0, jt1.ordered=1 where t1.name=jt1.name; + +select * from t1; + +drop table t1; + +--echo # +--echo # End of 11.0 tests +--echo # diff --git a/storage/connect/mysql-test/connect/r/upd.result b/storage/connect/mysql-test/connect/r/upd.result index 8faf0089..7e3e880 100644 --- a/storage/connect/mysql-test/connect/r/upd.result +++ b/storage/connect/mysql-test/connect/r/upd.result @@ -1627,3 +1627,163 @@ serialno name sex title manager department secretary salary DROP PROCEDURE test.tst_up; DROP TABLE employee; SET sql_mode = DEFAULT; +# +# End of 10.10 tests +# +SET sql_mode = 'NO_ENGINE_SUBSTITUTION'; +CREATE TABLE t1 +( +name char(12) not null, +city char(11) not null, +birth date not null date_format='DD/MM/YYYY', +hired date not null date_format='DD/MM/YYYY' flag=36 +) ENGINE=CONNECT TABLE_TYPE=FIX FILE_NAME='boys.txt' ENDING=1; +CREATE TABLE t2 ( +_id INT(2) NOT NULL, +name_first CHAR(9) NOT NULL JPATH='$.name.first', +name_aka CHAR(4) DEFAULT NULL JPATH='$.name.aka', +name_last CHAR(10) NOT NULL JPATH='$.name.last', +title CHAR(12) DEFAULT NULL, +birth CHAR(20) DEFAULT NULL, +death CHAR(20) DEFAULT NULL, +contribs CHAR(50) NOT NULL JPATH='$.contribs', +awards_award CHAR(42) DEFAULT NULL JPATH='$.awards.award', +awards_year CHAR(4) DEFAULT NULL JPATH='$.awards.year', +awards_by CHAR(38) DEFAULT NULL JPATH='$.awards.by' +) ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='bios.json'; +# Multi-update +select t1.name, t1.city from t1; +name city +John Boston +Henry Boston +George San Jose +Sam Chicago +James Dallas +Bill Boston +select t2._id, t2.name_first, t2.name_aka, t2.name_last from t2; +_id name_first name_aka name_last +1 John NULL Backus +2 John NULL McCarthy +3 Grace NULL Hopper +4 Kristen NULL Nygaard +5 Ole-Johan NULL Dahl +6 Guido NULL van Rossum +7 Dennis NULL Ritchie +8 Yukihiro Matz Matsumoto +9 James NULL Gosling +10 Martin NULL Odersky +select t1.name, t2.name_last, t2.name_aka, t1.city from t1, t2 where t1.name=t2.name_first and t1.birth +BETWEEN '1992-01-01' and '1995-01-01'; +name name_last name_aka city +James Gosling NULL Dallas +explain update t1, t2 +set t1.city='Washington', t2.name_aka='von' where t1.name=t2.name_first and t1.birth +BETWEEN '1992-01-01' and '1995-01-01'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 6 Using where +1 SIMPLE t2 ALL NULL NULL NULL NULL 10 Using where +update t1, t2 +set t1.city='Washington', t2.name_aka='von' where t1.name=t2.name_first and t1.birth +BETWEEN '1992-01-01' and '1995-01-01'; +select t1.name, t2.name_last, t2.name_aka, t1.city from t1, t2 where t1.name=t2.name_first and t1.birth +BETWEEN '1992-01-01' and '1995-01-01'; +name name_last name_aka city +James Gosling von Washington +# Conversion to multi-update +select t1.name, t1.city from t1; +name city +John Boston +Henry Boston +George San Jose +Sam Chicago +James Washington +Bill Boston +explain update t1 +set t1.city='New York' where t1.name in (select t2.name_first from t2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 6 +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 9 func 1 Using where +2 MATERIALIZED t2 ALL NULL NULL NULL NULL 10 +update t1 +set t1.city='New York' where t1.name in (select t2.name_first from t2); +select t1.name, t1.city from t1; +name city +John New York +Henry Boston +George San Jose +Sam Chicago +James New York +Bill Boston +select t1.name, t1.city from t1 where t1.name in (select a.name from t1 as a where a.birth +BETWEEN '1981-01-01' and '1982-01-01'); +name city +George San Jose +explain update t1 set t1.city='Los Angeles' where t1.name in (select a.name from t1 as a where a.birth +BETWEEN '1981-01-01' and '1982-01-01'); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 6 +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 12 func 1 +2 MATERIALIZED a ALL NULL NULL NULL NULL 6 Using where +update t1 set t1.city='Los Angeles' where t1.name in (select a.name from t1 as a where a.birth +BETWEEN '1981-01-01' and '1982-01-01'); +select t1.name, t1.city from t1 where t1.name in (select a.name from t1 as a where a.birth +BETWEEN '1981-01-01' and '1982-01-01'); +name city +George Los Angeles +# Multi-delete +explain delete t1.*, t2.* from t1, t2 where t1.name=t2.name_first and t1.birth +BETWEEN '1992-01-01' and '1995-01-01'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 6 Using where +1 SIMPLE t2 ALL NULL NULL NULL NULL 10 Using where +delete t1.*, t2.* from t1, t2 where t1.name=t2.name_first and t1.birth +BETWEEN '1992-01-01' and '1995-01-01'; +select t1.name, t1.city from t1; +name city +John New York +Henry Boston +George Los Angeles +Sam Chicago +Bill Boston +select t2._id, t2.name_first, t2.name_aka, t2.name_last from t2; +_id name_first name_aka name_last +1 John NULL Backus +2 John NULL McCarthy +3 Grace NULL Hopper +4 Kristen NULL Nygaard +5 Ole-Johan NULL Dahl +6 Guido NULL van Rossum +7 Dennis NULL Ritchie +8 Yukihiro Matz Matsumoto +10 Martin NULL Odersky +# Conversion to multi-delete +explain delete from t1 where t1.name in (select t2.name_first from t2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 5 +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 9 func 1 Using where +2 MATERIALIZED t2 ALL NULL NULL NULL NULL 9 +delete from t1 where t1.name in (select t2.name_first from t2); +select t1.name, t1.city from t1; +name city +Henry Boston +George Los Angeles +Sam Chicago +Bill Boston +explain delete from t1 where t1.name in (select a.name from t1 as a where a.birth +BETWEEN '1981-01-01' and '1982-01-01'); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 4 +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 12 func 1 +2 MATERIALIZED a ALL NULL NULL NULL NULL 4 Using where +delete from t1 where t1.name in (select a.name from t1 as a where a.birth +BETWEEN '1981-01-01' and '1982-01-01'); +select t1.name, t1.city from t1; +name city +Henry Boston +Sam Chicago +Bill Boston +drop tables t1, t2; +SET sql_mode = DEFAULT; +# +# End of 11.0 tests +# diff --git a/storage/connect/mysql-test/connect/t/upd.test b/storage/connect/mysql-test/connect/t/upd.test index 28b566b..0372a9a 100644 --- a/storage/connect/mysql-test/connect/t/upd.test +++ b/storage/connect/mysql-test/connect/t/upd.test @@ -155,3 +155,99 @@ DROP TABLE employee; SET sql_mode = DEFAULT; --remove_file $MYSQLD_DATADIR/test/employee.dat + +--echo # +--echo # End of 10.10 tests +--echo # + +--copy_file $MTR_SUITE_DIR/std_data/boys.txt $MYSQLD_DATADIR/test/boys.txt +--copy_file $MTR_SUITE_DIR/std_data/bios.json $MYSQLD_DATADIR/test/bios.json + +SET sql_mode = 'NO_ENGINE_SUBSTITUTION'; + +CREATE TABLE t1 +( + name char(12) not null, + city char(11) not null, + birth date not null date_format='DD/MM/YYYY', + hired date not null date_format='DD/MM/YYYY' flag=36 +) ENGINE=CONNECT TABLE_TYPE=FIX FILE_NAME='boys.txt' ENDING=1; + +CREATE TABLE t2 ( + _id INT(2) NOT NULL, + name_first CHAR(9) NOT NULL JPATH='$.name.first', + name_aka CHAR(4) DEFAULT NULL JPATH='$.name.aka', + name_last CHAR(10) NOT NULL JPATH='$.name.last', + title CHAR(12) DEFAULT NULL, + birth CHAR(20) DEFAULT NULL, + death CHAR(20) DEFAULT NULL, + contribs CHAR(50) NOT NULL JPATH='$.contribs', + awards_award CHAR(42) DEFAULT NULL JPATH='$.awards.award', + awards_year CHAR(4) DEFAULT NULL JPATH='$.awards.year', + awards_by CHAR(38) DEFAULT NULL JPATH='$.awards.by' +) ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='bios.json'; + +--echo # Multi-update + +select t1.name, t1.city from t1; +select t2._id, t2.name_first, t2.name_aka, t2.name_last from t2; + +let $c1 = where t1.name=t2.name_first and t1.birth + BETWEEN '1992-01-01' and '1995-01-01'; + +eval select t1.name, t2.name_last, t2.name_aka, t1.city from t1, t2 $c1; +eval explain update t1, t2 + set t1.city='Washington', t2.name_aka='von' $c1; +eval update t1, t2 + set t1.city='Washington', t2.name_aka='von' $c1; +eval select t1.name, t2.name_last, t2.name_aka, t1.city from t1, t2 $c1; + +--echo # Conversion to multi-update + +let $c2 = where t1.name in (select t2.name_first from t2); + +select t1.name, t1.city from t1; +eval explain update t1 + set t1.city='New York' $c2; +eval update t1 + set t1.city='New York' $c2; +select t1.name, t1.city from t1; + +let $c3 = where t1.name in (select a.name from t1 as a where a.birth + BETWEEN '1981-01-01' and '1982-01-01'); + +eval select t1.name, t1.city from t1 $c3; +eval explain update t1 set t1.city='Los Angeles' $c3; +eval update t1 set t1.city='Los Angeles' $c3; +eval select t1.name, t1.city from t1 $c3; + +--echo # Multi-delete + +eval explain delete t1.*, t2.* from t1, t2 $c1; +eval delete t1.*, t2.* from t1, t2 $c1; + +select t1.name, t1.city from t1; +select t2._id, t2.name_first, t2.name_aka, t2.name_last from t2; + +--echo # Conversion to multi-delete + +eval explain delete from t1 $c2; +eval delete from t1 $c2; + +select t1.name, t1.city from t1; + +eval explain delete from t1 $c3; +eval delete from t1 $c3; + +select t1.name, t1.city from t1; + +drop tables t1, t2; + +SET sql_mode = DEFAULT; + +--remove_file $MYSQLD_DATADIR/test/boys.txt +--remove_file $MYSQLD_DATADIR/test/bios.json + +--echo # +--echo # End of 11.0 tests +--echo #