[Commits] fa896dc: MDEV-29390: Improve coverage for UPDATE and DELETE statements in MTR test suites
revision-id: fa896dc433f835bbde98619d5091c482d2586e07 (mariadb-11.0.1-28-gfa896dc) parent(s): 2ae8dc24351b830fd15970758b65f58caf504678 author: Lena Startseva committer: Igor Babaev timestamp: 2023-03-15 14:19:02 -0700 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 | 94 + mysql-test/include/delete_use_source_cases.inc | 214 + .../include/delete_use_source_cases_memory.inc | 294 + .../include/delete_use_source_cases_non_innodb.inc | 81 + mysql-test/include/delete_use_source_innodb.inc | 91 + mysql-test/include/delete_use_source_memory.inc | 33 + mysql-test/include/update_use_source.inc | 292 +- mysql-test/include/update_use_source_cases.inc | 183 + mysql-test/include/update_use_source_ext.inc | 59 + mysql-test/main/delete_single_to_multi.result | 830 ++ mysql-test/main/delete_single_to_multi.test | 244 + mysql-test/main/delete_use_source_engines.result | 8870 ++++++++++++++++ mysql-test/main/delete_use_source_engines.test | 42 + mysql-test/main/update_single_to_multi.result | 615 ++ mysql-test/main/update_single_to_multi.test | 242 + mysql-test/main/update_use_source.result | 10273 +++++++++++++++++-- mysql-test/main/update_use_source.test | 250 +- 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 | 156 + storage/connect/mysql-test/connect/t/upd.test | 96 + 21 files changed, 22157 insertions(+), 997 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..3f78976 --- /dev/null +++ b/mysql-test/include/delete_use_source.inc @@ -0,0 +1,94 @@ +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 ####################################### +--echo # Test without any index # +--echo ####################################### +--source include/delete_use_source_cases.inc +--source include/delete_use_source_cases_non_innodb.inc + +--echo ####################################### +--echo # Test with an index # +--echo ####################################### +create index t1_c2 on t1 (c2,c1); +--source include/delete_use_source_cases.inc +--source include/delete_use_source_cases_non_innodb.inc + +--echo ####################################### +--echo # Test with a primary key # +--echo ####################################### +drop index t1_c2 on t1; +alter table t1 add primary key (c3); +--source include/delete_use_source_cases.inc +--source include/delete_use_source_cases_non_innodb.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..24408b7 --- /dev/null +++ b/mysql-test/include/delete_use_source_cases.inc @@ -0,0 +1,214 @@ +--echo # +--echo # Delete with value from subquery on the same table +--echo # + +analyze table t1 persistent for all; + +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 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; + 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..7a61b59 --- /dev/null +++ b/mysql-test/include/delete_use_source_cases_memory.inc @@ -0,0 +1,294 @@ +--echo # +--echo # Delete with value from subquery on the same table +--echo # + +analyze table t1 persistent for all; + +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; +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; + diff --git a/mysql-test/include/delete_use_source_cases_non_innodb.inc b/mysql-test/include/delete_use_source_cases_non_innodb.inc new file mode 100644 index 0000000..caa5817 --- /dev/null +++ b/mysql-test/include/delete_use_source_cases_non_innodb.inc @@ -0,0 +1,81 @@ +--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; +--replace_column 9 # +eval explain select * from t1 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; + +--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_innodb.inc b/mysql-test/include/delete_use_source_innodb.inc new file mode 100644 index 0000000..83915d4 --- /dev/null +++ b/mysql-test/include/delete_use_source_innodb.inc @@ -0,0 +1,91 @@ +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 ####################################### +--echo # Test without any index # +--echo ####################################### +--source include/delete_use_source_cases.inc + +--echo ####################################### +--echo # Test with an index # +--echo ####################################### +create index t1_c2 on t1 (c2,c1); +--source include/delete_use_source_cases.inc + +--echo ####################################### +--echo # Test with a primary key # +--echo ####################################### +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_memory.inc b/mysql-test/include/delete_use_source_memory.inc new file mode 100644 index 0000000..dbaae1a --- /dev/null +++ b/mysql-test/include/delete_use_source_memory.inc @@ -0,0 +1,33 @@ +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 ####################################### +--echo # Test without any index # +--echo ####################################### +--source include/delete_use_source_cases_memory.inc + +--echo ####################################### +--echo # Test with an index # +--echo ####################################### +create index t1_c2 on t1 (c2,c1); +--source include/delete_use_source_cases_memory.inc + +--echo ####################################### +--echo # Test with a primary key # +--echo ####################################### +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..e1b66d2 100644 --- a/mysql-test/include/update_use_source.inc +++ b/mysql-test/include/update_use_source.inc @@ -1,150 +1,188 @@ # 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); + +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); +insert into t1 select NULL, NULL, c1+10,c2,c3+10 from t1; +insert into t1 select NULL, NULL, c1+20,c2+1,c3+20 from t1; +analyze table t1 persistent for all; + +create table tmp as select * from t1; + +--echo ####################################### +--echo # Test without any index # +--echo ####################################### +--source include/update_use_source_cases.inc + +--echo ####################################### +--echo # Test with an index # +--echo ####################################### +create index t1_c2 on t1 (c2,c1); +analyze table t1; +--source include/update_use_source_cases.inc + +--echo ####################################### +--echo # Test with a primary key # +--echo ####################################### +drop index t1_c2 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..f1025f7 --- /dev/null +++ b/mysql-test/include/update_use_source_cases.inc @@ -0,0 +1,183 @@ +--echo # +--echo # Update with value from subquery on the same table +--echo # + +analyze table t1 persistent for all; +let $q = update t1 set c1=(select a.c3 from t1 a where a.c3 = t1.c3); +eval explain select * from t1; +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 # + +analyze table t1 persistent for all; +let $c = c1 <2 + and exists (select 'X' from t1 a where a.c1 = t1.c1); +let $q = update t1 set c1=10 where $c; +eval explain select * from t1 where $c; +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 # + +analyze table t1 persistent for all; +let $c = exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 >= 3; +let $q = update t1 set c1=c1+10 where $c; +eval explain select * from t1 where $c; +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 # + +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; +let $q = update t1 set c1=c1+10 where $c; +eval explain select * from t1 where $c; +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 # in settable value +--echo # + +analyze table t1 persistent for all; +let $q = update t1 set c1=c1 +(select max(a.c2) from v1 a + where a.c1 = t1.c1); +eval explain select * from t1; +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 # + +analyze table t1 persistent for all; +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 select * from v1; +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 # + +analyze table t1 persistent for all; +let $c = c1 <2 + and exists (select 'X' from v1 a where a.c1 = v1.c1); +let $q = update v1 set c1=c1 + 1 where $c; +eval explain select * from v1 where $c; +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 # + +analyze table t1 persistent for all; +let $c = c1 <10 and exists (select 'X' from v1 a where a.c2 = v1.c2); +let $q = update v1 + set c1=(select max(a.c1)+10 from v1 a where a.c1 = v1.c1) + where $c; +eval explain select * from v1 where $c; +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 # + +analyze table t1 persistent for all; +let $c = c2 in (select distinct a.c2 from t1 a where t1.c1=a.c1); +let $q = update t1 set c3=c3+110 where $c; +eval explain select * from t1 where $c; +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 # + +analyze table t1 persistent for all; +let $q = update t1 + set c1=(select a.c3 from t1 a where a.c3 = t1.c3) limit 2; +eval explain select * from t1 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 # + +analyze table t1 persistent for all; +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 select * from t1 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 eba4ca8..57cc224 100644 --- a/mysql-test/main/delete_single_to_multi.result +++ b/mysql-test/main/delete_single_to_multi.result @@ -3419,4 +3419,834 @@ o_orderkey o_totalprice 4903 34363.63 5607 24660.06 drop table t; +CREATE TABLE partsupp_small ( +ps_partkey int(11) NOT NULL DEFAULT '0', +ps_suppkey int(11) NOT NULL DEFAULT '0', +ps_availqty int(11) DEFAULT NULL, +ps_supplycost double DEFAULT NULL, +ps_comment varchar(199) DEFAULT NULL, +PRIMARY KEY (ps_partkey,ps_suppkey), +KEY i_ps_partkey (ps_partkey), +KEY i_ps_suppkey (ps_suppkey) +); +create index i_ps_sup_part on partsupp_small(ps_suppkey, ps_partkey); +insert into partsupp_small select * from partsupp where ps_partkey <50; +analyze table partsupp_small persistent for all; +Table Op Msg_type Msg_text +dbt3_s001.partsupp_small analyze status Engine-independent statistics collected +dbt3_s001.partsupp_small analyze status OK +# LooseScan +# ========= +explain +select count(*) from lineitem where l_partkey in +(select ps_partkey from partsupp_small +where ps_suppkey in (1,2,3)); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY partsupp_small index PRIMARY,i_ps_partkey,i_ps_suppkey,i_ps_sup_part PRIMARY 8 NULL 176 Using where; Using index; LooseScan +1 PRIMARY lineitem ref i_l_suppkey_partkey,i_l_partkey i_l_partkey 5 dbt3_s001.partsupp_small.ps_partkey 30 Using index +explain format=json +select count(*) from lineitem where l_partkey in +(select ps_partkey from partsupp_small +where ps_suppkey in (1,2,3)); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "cost": 0.222764041, + "nested_loop": [ + { + "table": { + "table_name": "partsupp_small", + "access_type": "index", + "possible_keys": [ + "PRIMARY", + "i_ps_partkey", + "i_ps_suppkey", + "i_ps_sup_part" + ], + "key": "PRIMARY", + "key_length": "8", + "used_key_parts": ["ps_partkey", "ps_suppkey"], + "loops": 1, + "rows": 176, + "cost": 0.019403477, + "filtered": 23.86363602, + "attached_condition": "partsupp_small.ps_suppkey in (1,2,3)", + "using_index": true, + "loose_scan": 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_small.ps_partkey"], + "loops": 42, + "rows": 30, + "cost": 0.203360564, + "filtered": 2.380952358, + "using_index": true + } + } + ] + } +} +explain +select l_partkey from lineitem where l_partkey in +(select ps_partkey from partsupp_small +where ps_suppkey in (1,2,3)); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY partsupp_small index PRIMARY,i_ps_partkey,i_ps_suppkey,i_ps_sup_part PRIMARY 8 NULL 176 Using where; Using index; LooseScan +1 PRIMARY lineitem ref i_l_suppkey_partkey,i_l_partkey i_l_partkey 5 dbt3_s001.partsupp_small.ps_partkey 30 Using index +explain format=json +select l_partkey from lineitem where l_partkey in +(select ps_partkey from partsupp_small +where ps_suppkey in (1,2,3)); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "cost": 0.222764041, + "nested_loop": [ + { + "table": { + "table_name": "partsupp_small", + "access_type": "index", + "possible_keys": [ + "PRIMARY", + "i_ps_partkey", + "i_ps_suppkey", + "i_ps_sup_part" + ], + "key": "PRIMARY", + "key_length": "8", + "used_key_parts": ["ps_partkey", "ps_suppkey"], + "loops": 1, + "rows": 176, + "cost": 0.019403477, + "filtered": 23.86363602, + "attached_condition": "partsupp_small.ps_suppkey in (1,2,3)", + "using_index": true, + "loose_scan": 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_small.ps_partkey"], + "loops": 42, + "rows": 30, + "cost": 0.203360564, + "filtered": 2.380952358, + "using_index": true + } + } + ] + } +} +select count(*) from lineitem where l_partkey in +(select ps_partkey from partsupp_small +where ps_suppkey in (1,2,3)); +count(*) +1175 +create table t as +select * from lineitem where l_partkey in +(select ps_partkey from partsupp_small +where ps_suppkey in (1,2,3)); +explain +delete from lineitem where l_partkey in +(select ps_partkey from partsupp_small +where ps_suppkey in (1,2,3)); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY partsupp_small index PRIMARY,i_ps_partkey,i_ps_suppkey,i_ps_sup_part PRIMARY 8 NULL 176 Using where; Using index; LooseScan +1 PRIMARY lineitem ref i_l_suppkey_partkey,i_l_partkey i_l_partkey 5 dbt3_s001.partsupp_small.ps_partkey 30 +explain format=json +delete from lineitem where l_partkey in +(select ps_partkey from partsupp_small +where ps_suppkey in (1,2,3)); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "cost": 0.222764041, + "nested_loop": [ + { + "table": { + "table_name": "partsupp_small", + "access_type": "index", + "possible_keys": [ + "PRIMARY", + "i_ps_partkey", + "i_ps_suppkey", + "i_ps_sup_part" + ], + "key": "PRIMARY", + "key_length": "8", + "used_key_parts": ["ps_partkey", "ps_suppkey"], + "loops": 1, + "rows": 176, + "cost": 0.019403477, + "filtered": 23.86363602, + "attached_condition": "partsupp_small.ps_suppkey in (1,2,3)", + "using_index": true, + "loose_scan": 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_small.ps_partkey"], + "loops": 42, + "rows": 30, + "cost": 0.203360564, + "filtered": 2.380952358 + } + } + ] + } +} +delete from lineitem where l_partkey in +(select ps_partkey from partsupp_small +where ps_suppkey in (1,2,3)); +select count(*) from lineitem where l_partkey in +(select ps_partkey from partsupp_small +where ps_suppkey in (1,2,3)); +count(*) +0 +insert into lineitem select * from t; +select count(*) from lineitem where l_partkey in +(select ps_partkey from partsupp_small +where ps_suppkey in (1,2,3)); +count(*) +1175 +drop table t; +# LooseScan PS +# ============ +prepare stmt from " +delete from lineitem where l_partkey in +(select ps_partkey from partsupp_small +where ps_suppkey in (1,2,3)); +"; +select count(*) from lineitem where l_partkey in +(select ps_partkey from partsupp_small +where ps_suppkey in (1,2,3)); +count(*) +1175 +create table t as +select * from lineitem where l_partkey in +(select ps_partkey from partsupp_small +where ps_suppkey in (1,2,3)); +execute stmt; +select count(*) from lineitem where l_partkey in +(select ps_partkey from partsupp_small +where ps_suppkey in (1,2,3)); +count(*) +0 +insert into lineitem select * from t; +select count(*) from lineitem where l_partkey in +(select ps_partkey from partsupp_small +where ps_suppkey in (1,2,3)); +count(*) +1175 +create table r as +select * from lineitem where l_partkey in +(select ps_partkey from partsupp_small +where ps_suppkey in (1,2,3)); +execute stmt; +select count(*) from lineitem where l_partkey in +(select ps_partkey from partsupp_small +where ps_suppkey in (1,2,3)); +count(*) +0 +insert into lineitem select * from r; +select count(*) from lineitem where l_partkey in +(select ps_partkey from partsupp_small +where ps_suppkey in (1,2,3)); +count(*) +1175 +drop tables r, t; +deallocate prepare stmt; +# LooseScan SP +# ============ +create procedure p() +delete from lineitem where l_partkey in +(select ps_partkey from partsupp_small +where ps_suppkey in (1,2,3)); +select count(*) from lineitem where l_partkey in +(select ps_partkey from partsupp_small +where ps_suppkey in (1,2,3)); +count(*) +1175 +create table t as +select * from lineitem where l_partkey in +(select ps_partkey from partsupp_small +where ps_suppkey in (1,2,3)); +call p(); +select count(*) from lineitem where l_partkey in +(select ps_partkey from partsupp_small +where ps_suppkey in (1,2,3)); +count(*) +0 +insert into lineitem select * from t; +select count(*) from lineitem where l_partkey in +(select ps_partkey from partsupp_small +where ps_suppkey in (1,2,3)); +count(*) +1175 +create table r as +select * from lineitem where l_partkey in +(select ps_partkey from partsupp_small +where ps_suppkey in (1,2,3)); +call p(); +select count(*) from lineitem where l_partkey in +(select ps_partkey from partsupp_small +where ps_suppkey in (1,2,3)); +count(*) +0 +insert into lineitem select * from r; +select count(*) from lineitem where l_partkey in +(select ps_partkey from partsupp_small +where ps_suppkey in (1,2,3)); +count(*) +1175 +drop tables r, t; +drop procedure p; +# 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 OK +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_small 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_small ref PRIMARY,i_ps_partkey,i_ps_suppkey,i_ps_sup_part i_ps_sup_part 4 dbt3_s001.supplier.s_suppkey 17 Using where; Using index +1 PRIMARY lineitem ref i_l_suppkey_partkey,i_l_partkey i_l_suppkey_partkey 5 dbt3_s001.partsupp_small.ps_partkey 30 Using index +1 PRIMARY lineitem ref i_l_suppkey_partkey,i_l_partkey i_l_partkey 5 dbt3_s001.partsupp_small.ps_partkey 30 Using index; End temporary +explain format=json +select count(*) from lineitem where l_partkey in ( +select ps_partkey +from partsupp_small 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, + "cost": 4.129940741, + "nested_loop": [ + { + "duplicates_removal": [ + { + "table": { + "table_name": "supplier", + "access_type": "range", + "possible_keys": ["PRIMARY"], + "key": "PRIMARY", + "key_length": "4", + "used_key_parts": ["s_suppkey"], + "loops": 1, + "rows": 1, + "cost": 0.001478954, + "filtered": 100, + "attached_condition": "supplier.s_suppkey < 2", + "using_index": true + } + }, + { + "table": { + "table_name": "partsupp_small", + "access_type": "ref", + "possible_keys": [ + "PRIMARY", + "i_ps_partkey", + "i_ps_suppkey", + "i_ps_sup_part" + ], + "key": "i_ps_sup_part", + "key_length": "4", + "used_key_parts": ["ps_suppkey"], + "ref": ["dbt3_s001.supplier.s_suppkey"], + "loops": 1, + "rows": 17, + "cost": 0.003160332, + "filtered": 79.54545593, + "attached_condition": "partsupp_small.ps_partkey is not null", + "using_index": true + } + }, + { + "table": { + "table_name": "lineitem", + "access_type": "ref", + "possible_keys": ["i_l_suppkey_partkey", "i_l_partkey"], + "key": "i_l_suppkey_partkey", + "key_length": "5", + "used_key_parts": ["l_partkey"], + "ref": ["dbt3_s001.partsupp_small.ps_partkey"], + "loops": 14, + "rows": 30, + "cost": 0.069152188, + "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_small.ps_partkey"], + "loops": 420.35, + "rows": 30, + "cost": 1.994712365, + "filtered": 0.237896994, + "using_index": true + } + } + ] + } + ] + } +} +explain +select l_partkey from lineitem where l_partkey in ( +select ps_partkey +from partsupp_small 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_small ref PRIMARY,i_ps_partkey,i_ps_suppkey,i_ps_sup_part i_ps_sup_part 4 dbt3_s001.supplier.s_suppkey 17 Using where; Using index +1 PRIMARY lineitem ref i_l_suppkey_partkey,i_l_partkey i_l_suppkey_partkey 5 dbt3_s001.partsupp_small.ps_partkey 30 Using index +1 PRIMARY lineitem ref i_l_suppkey_partkey,i_l_partkey i_l_partkey 5 dbt3_s001.partsupp_small.ps_partkey 30 Using index; End temporary +explain format=json +select l_partkey from lineitem where l_partkey in ( +select ps_partkey +from partsupp_small 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, + "cost": 4.129940741, + "nested_loop": [ + { + "duplicates_removal": [ + { + "table": { + "table_name": "supplier", + "access_type": "range", + "possible_keys": ["PRIMARY"], + "key": "PRIMARY", + "key_length": "4", + "used_key_parts": ["s_suppkey"], + "loops": 1, + "rows": 1, + "cost": 0.001478954, + "filtered": 100, + "attached_condition": "supplier.s_suppkey < 2", + "using_index": true + } + }, + { + "table": { + "table_name": "partsupp_small", + "access_type": "ref", + "possible_keys": [ + "PRIMARY", + "i_ps_partkey", + "i_ps_suppkey", + "i_ps_sup_part" + ], + "key": "i_ps_sup_part", + "key_length": "4", + "used_key_parts": ["ps_suppkey"], + "ref": ["dbt3_s001.supplier.s_suppkey"], + "loops": 1, + "rows": 17, + "cost": 0.003160332, + "filtered": 79.54545593, + "attached_condition": "partsupp_small.ps_partkey is not null", + "using_index": true + } + }, + { + "table": { + "table_name": "lineitem", + "access_type": "ref", + "possible_keys": ["i_l_suppkey_partkey", "i_l_partkey"], + "key": "i_l_suppkey_partkey", + "key_length": "5", + "used_key_parts": ["l_partkey"], + "ref": ["dbt3_s001.partsupp_small.ps_partkey"], + "loops": 14, + "rows": 30, + "cost": 0.069152188, + "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_small.ps_partkey"], + "loops": 420.35, + "rows": 30, + "cost": 1.994712365, + "filtered": 0.237896994, + "using_index": true + } + } + ] + } + ] + } +} +select count(*) from lineitem where l_partkey in ( +select ps_partkey +from partsupp_small join lineitem on ps_partkey=l_partkey +where ps_suppkey in ( +select s_suppkey from supplier where s_suppkey < 2 +) +); +count(*) +471 +create table t as +select * from lineitem where l_partkey in ( +select ps_partkey +from partsupp_small 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_small 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_small ref PRIMARY,i_ps_partkey,i_ps_suppkey,i_ps_sup_part i_ps_sup_part 4 dbt3_s001.supplier.s_suppkey 17 Using where; Using index +1 PRIMARY lineitem ref i_l_suppkey_partkey,i_l_partkey i_l_suppkey_partkey 5 dbt3_s001.partsupp_small.ps_partkey 30 +1 PRIMARY lineitem ref i_l_suppkey_partkey,i_l_partkey i_l_partkey 5 dbt3_s001.partsupp_small.ps_partkey 30 Using index; End temporary +explain format=json +delete from lineitem where l_partkey in ( +select ps_partkey +from partsupp_small 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, + "cost": 4.129940741, + "nested_loop": [ + { + "duplicates_removal": [ + { + "table": { + "table_name": "supplier", + "access_type": "range", + "possible_keys": ["PRIMARY"], + "key": "PRIMARY", + "key_length": "4", + "used_key_parts": ["s_suppkey"], + "loops": 1, + "rows": 1, + "cost": 0.001478954, + "filtered": 100, + "attached_condition": "supplier.s_suppkey < 2", + "using_index": true + } + }, + { + "table": { + "table_name": "partsupp_small", + "access_type": "ref", + "possible_keys": [ + "PRIMARY", + "i_ps_partkey", + "i_ps_suppkey", + "i_ps_sup_part" + ], + "key": "i_ps_sup_part", + "key_length": "4", + "used_key_parts": ["ps_suppkey"], + "ref": ["dbt3_s001.supplier.s_suppkey"], + "loops": 1, + "rows": 17, + "cost": 0.003160332, + "filtered": 79.54545593, + "attached_condition": "partsupp_small.ps_partkey is not null", + "using_index": true + } + }, + { + "table": { + "table_name": "lineitem", + "access_type": "ref", + "possible_keys": ["i_l_suppkey_partkey", "i_l_partkey"], + "key": "i_l_suppkey_partkey", + "key_length": "5", + "used_key_parts": ["l_partkey"], + "ref": ["dbt3_s001.partsupp_small.ps_partkey"], + "loops": 14, + "rows": 30, + "cost": 0.069152188, + "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_small.ps_partkey"], + "loops": 420.35, + "rows": 30, + "cost": 1.994712365, + "filtered": 0.237896994, + "using_index": true + } + } + ] + } + ] + } +} +delete from lineitem where l_partkey in ( +select ps_partkey +from partsupp_small 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_small 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_small join lineitem on ps_partkey=l_partkey +where ps_suppkey in ( +select s_suppkey from supplier where s_suppkey < 2 +) +); +count(*) +471 +drop table t; +# DuplicateWeedout PS +# =================== +prepare stmt from " +delete from lineitem where l_partkey in ( +select ps_partkey +from partsupp_small 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_small join lineitem on ps_partkey=l_partkey +where ps_suppkey in ( +select s_suppkey from supplier where s_suppkey < 2 +) +); +count(*) +471 +create table t as +select * from lineitem where l_partkey in ( +select ps_partkey +from partsupp_small 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_small 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_small join lineitem on ps_partkey=l_partkey +where ps_suppkey in ( +select s_suppkey from supplier where s_suppkey < 2 +) +); +count(*) +471 +create table r as +select * from lineitem where l_partkey in ( +select ps_partkey +from partsupp_small 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_small 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_small join lineitem on ps_partkey=l_partkey +where ps_suppkey in ( +select s_suppkey from supplier where s_suppkey < 2 +) +); +count(*) +471 +drop tables r, t; +deallocate prepare stmt; +# DuplicateWeedout SP +# =================== +create procedure p() +delete from lineitem where l_partkey in ( +select ps_partkey +from partsupp_small 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_small join lineitem on ps_partkey=l_partkey +where ps_suppkey in ( +select s_suppkey from supplier where s_suppkey < 2 +) +); +count(*) +471 +create table t as +select * from lineitem where l_partkey in ( +select ps_partkey +from partsupp_small 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_small 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_small join lineitem on ps_partkey=l_partkey +where ps_suppkey in ( +select s_suppkey from supplier where s_suppkey < 2 +) +); +count(*) +471 +create table r as +select * from lineitem where l_partkey in ( +select ps_partkey +from partsupp_small 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_small 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_small join lineitem on ps_partkey=l_partkey +where ps_suppkey in ( +select s_suppkey from supplier where s_suppkey < 2 +) +); +count(*) +471 +drop tables r, t; +drop procedure p; +set @@optimizer_switch=@tmp_optimizer_switch; +drop table partsupp_small; 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 2829ae1..31f1d15 100644 --- a/mysql-test/main/delete_single_to_multi.test +++ b/mysql-test/main/delete_single_to_multi.test @@ -822,4 +822,248 @@ eval select o_orderkey, o_totalprice from orders where $c11; drop table t; + +CREATE TABLE partsupp_small ( + ps_partkey int(11) NOT NULL DEFAULT '0', + ps_suppkey int(11) NOT NULL DEFAULT '0', + ps_availqty int(11) DEFAULT NULL, + ps_supplycost double DEFAULT NULL, + ps_comment varchar(199) DEFAULT NULL, + PRIMARY KEY (ps_partkey,ps_suppkey), + KEY i_ps_partkey (ps_partkey), + KEY i_ps_suppkey (ps_suppkey) +); + +create index i_ps_sup_part on partsupp_small(ps_suppkey, ps_partkey); +insert into partsupp_small select * from partsupp where ps_partkey <50; +analyze table partsupp_small persistent for all; + +--echo # LooseScan +--echo # ========= + +let $c12 = l_partkey in + (select ps_partkey from partsupp_small + where ps_suppkey in (1,2,3)); + +eval +explain +select count(*) from lineitem where $c12; +eval +explain format=json +select count(*) from lineitem where $c12; +eval +explain +select l_partkey from lineitem where $c12; +eval +explain format=json +select l_partkey 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; + +--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_small 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 +explain +select l_partkey from lineitem where $c13; +eval +explain format=json +select l_partkey 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 table partsupp_small; + 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..fd0d3b8 --- /dev/null +++ b/mysql-test/main/delete_use_source_engines.result @@ -0,0 +1,8870 @@ +set @save_default_engine=@@default_storage_engine; +####################################### +# # +# Engine InnoDB # +# # +####################################### +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 +# +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=(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 a ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) +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 a ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1) +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 a ALL NULL NULL NULL NULL 32 12.00 100.00 5.56 Using where; FirstMatch(t1) +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 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 32.00 100.00 12.50 Using where +1 PRIMARY a ALL NULL NULL NULL NULL 32 24.50 100.00 1.02 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; +####################################### +# Test with an index # +####################################### +create index t1_c2 on t1 (c2,c1); +# +# Delete with value from subquery on the same table +# +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=(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 a index NULL t1_c2 10 NULL 32 Using where; Using index; FirstMatch(t1); Using join buffer (flat, BNL join) +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 a index NULL t1_c2 10 NULL 32 Using where; Using index; FirstMatch(t1) +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 a index NULL t1_c2 10 NULL 32 11.67 100.00 5.71 Using where; Using index; FirstMatch(t1) +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 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 32.00 100.00 12.50 Using where +1 PRIMARY a ref t1_c2 t1_c2 5 test.t1.c1 5 0.25 18.75 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; +####################################### +# 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 +# +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=(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 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 a ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) +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 a ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1) +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 a ALL NULL NULL NULL NULL 32 12.33 100.00 5.41 Using where; FirstMatch(t1) +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 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 3.12 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; +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; +####################################### +# # +# Engine Aria # +# # +####################################### +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 +# +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 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 a ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) +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 a ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1) +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 a ALL NULL NULL NULL NULL 32 12.67 100.00 5.26 Using where; FirstMatch(t1) +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 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 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 a ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) +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 a ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1) +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 # Using where; Using filesort +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func # +2 MATERIALIZED a ALL NULL NULL NULL NULL # +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 # Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func # +2 MATERIALIZED a ALL NULL NULL NULL NULL # +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.00 62.50 62.50 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func # 1.00 100.00 100.00 +2 MATERIALIZED a ALL NULL NULL NULL NULL # 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 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 t1 ALL NULL NULL NULL NULL # Using where; FirstMatch(t1); Using join buffer (flat, BNL join) +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 DEPENDENT SUBQUERY 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 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL # 5.00 25.00 20.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 +# +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=(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 a index NULL t1_c2 10 NULL 32 Using where; Using index; FirstMatch(t1); Using join buffer (flat, BNL join) +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 a index NULL t1_c2 10 NULL 32 Using where; Using index; FirstMatch(t1) +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 a index NULL t1_c2 10 NULL 32 11.67 100.00 5.71 Using where; Using index; FirstMatch(t1) +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 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 18.75 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 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 a ref t1_c2 t1_c2 5 const 8 Using index; FirstMatch(t1) +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 a ref t1_c2 t1_c2 5 const 8 Using index; FirstMatch(t1) +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 range t1_c2 t1_c2 5 NULL # Using index condition +1 PRIMARY a ref t1_c2 t1_c2 5 test.t1.c2 # Using index; FirstMatch(t1) +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 a index t1_c2 t1_c2 10 NULL # Using where; Using index; LooseScan +1 PRIMARY t1 ref t1_c2 t1_c2 5 test.a.c2 # +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 a index t1_c2 t1_c2 10 NULL # 16.00 20.00 25.00 Using where; Using index; LooseScan +1 PRIMARY t1 ref t1_c2 t1_c2 5 test.a.c2 # 5.00 4.76 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 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 t1 ref t1_c2 t1_c2 10 const,const # Using index; FirstMatch(t1) +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 +# +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=(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 a ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) +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 a ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1) +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 a ALL NULL NULL NULL NULL 32 12.00 100.00 5.56 Using where; FirstMatch(t1) +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 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 3.12 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 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 a ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) +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 a ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1) +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 # Using where; Using filesort +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func # +2 MATERIALIZED a ALL NULL NULL NULL NULL # +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 # Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func # +2 MATERIALIZED a ALL NULL NULL NULL NULL # +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.00 62.50 62.50 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func # 1.00 100.00 100.00 +2 MATERIALIZED a ALL NULL NULL NULL NULL # 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 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 t1 ALL NULL NULL NULL NULL # Using where; FirstMatch(t1); Using join buffer (flat, BNL join) +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 DEPENDENT SUBQUERY 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 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL # 6.00 25.00 16.67 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; +####################################### +# # +# Engine MyISAM # +# # +####################################### +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 +# +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 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 a ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) +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 a ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1) +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 a ALL NULL NULL NULL NULL 32 12.67 100.00 5.26 Using where; FirstMatch(t1) +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 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 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 a ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) +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 a ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1) +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 # Using where; Using filesort +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func # +2 MATERIALIZED a ALL NULL NULL NULL NULL # +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 # Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func # +2 MATERIALIZED a ALL NULL NULL NULL NULL # +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.00 62.50 62.50 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func # 1.00 100.00 100.00 +2 MATERIALIZED a ALL NULL NULL NULL NULL # 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 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 t1 ALL NULL NULL NULL NULL # Using where; FirstMatch(t1); Using join buffer (flat, BNL join) +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 DEPENDENT SUBQUERY 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 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL # 5.00 25.00 20.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 +# +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=(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 a index NULL t1_c2 10 NULL 32 Using where; Using index; FirstMatch(t1); Using join buffer (flat, BNL join) +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 a index NULL t1_c2 10 NULL 32 Using where; Using index; FirstMatch(t1) +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 a index NULL t1_c2 10 NULL 32 11.67 100.00 5.71 Using where; Using index; FirstMatch(t1) +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 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 29.00 100.00 13.79 Using where +1 PRIMARY a ref t1_c2 t1_c2 5 test.t1.c1 5 0.25 18.75 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 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 a ref t1_c2 t1_c2 5 const 8 Using index; FirstMatch(t1) +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 a ref t1_c2 t1_c2 5 const 8 Using index; FirstMatch(t1) +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 # Using where; Using filesort +1 PRIMARY a ref t1_c2 t1_c2 5 test.t1.c2 # Using index; FirstMatch(t1) +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 a index t1_c2 t1_c2 10 NULL # Using where; Using index; LooseScan +1 PRIMARY t1 ref t1_c2 t1_c2 5 test.a.c2 # +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 a index t1_c2 t1_c2 10 NULL # 16.00 20.00 25.00 Using where; Using index; LooseScan +1 PRIMARY t1 ref t1_c2 t1_c2 5 test.a.c2 # 5.00 5.00 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 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 t1 ref t1_c2 t1_c2 10 const,const # Using index; FirstMatch(t1) +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 +# +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=(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 a ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) +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 a ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1) +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 a ALL NULL NULL NULL NULL 32 13.33 100.00 5.00 Using where; FirstMatch(t1) +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 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 3.12 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 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 a ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) +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 a ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1) +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 # Using where; Using filesort +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func # +2 MATERIALIZED a ALL NULL NULL NULL NULL # +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 # Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func # +2 MATERIALIZED a ALL NULL NULL NULL NULL # +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.00 62.50 62.50 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func # 1.00 100.00 100.00 +2 MATERIALIZED a ALL NULL NULL NULL NULL # 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 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 t1 ALL NULL NULL NULL NULL # Using where; FirstMatch(t1); Using join buffer (flat, BNL join) +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 DEPENDENT SUBQUERY 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 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL # 3.00 25.00 33.33 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; +####################################### +# # +# Engine MEMORY # +# # +####################################### +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 +# +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=(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 a ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) +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 a ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1) +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 a ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) +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 a ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1) +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 32 Using where +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 32 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 32 Using where +3 DEPENDENT SUBQUERY 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.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 +# +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=(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 a ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) +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 a ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1) +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 a ALL t1_c2 NULL NULL NULL 32 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) +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 a ALL t1_c2 NULL NULL NULL 32 Using where; FirstMatch(t1) +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 2 Using where +1 PRIMARY t1 ref t1_c2 t1_c2 10 const,const 2 FirstMatch(t1) +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 32 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 2 Using where +3 DEPENDENT SUBQUERY t1 ref t1_c2 t1_c2 10 const,func 2 Using where +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 32 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 +# +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=(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 a ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) +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 a ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1) +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 a ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) +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 a ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1) +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 32 Using where +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) +2 DEPENDENT SUBQUERY a eq_ref PRIMARY PRIMARY 4 test.t1.c3 1 +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 32 Using where +3 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 32 Using where +2 DEPENDENT SUBQUERY a eq_ref PRIMARY PRIMARY 4 test.t1.c3 1 +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..1a0d98f --- /dev/null +++ b/mysql-test/main/delete_use_source_engines.test @@ -0,0 +1,42 @@ +--source include/have_innodb.inc + +set @save_default_engine=@@default_storage_engine; + +--echo ####################################### +--echo # # +--echo # Engine InnoDB # +--echo # # +--echo ####################################### +set global innodb_stats_persistent=1; +set default_storage_engine=InnoDB; +--source include/delete_use_source_innodb.inc + +--echo ####################################### +--echo # # +--echo # Engine Aria # +--echo # # +--echo ####################################### +set default_storage_engine=Aria; +--source include/delete_use_source.inc + +--echo ####################################### +--echo # # +--echo # Engine MyISAM # +--echo # # +--echo ####################################### +set default_storage_engine=MyISAM; +--source include/delete_use_source.inc + +--echo ####################################### +--echo # # +--echo # Engine MEMORY # +--echo # # +--echo ####################################### +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 11969f7..6792378 100644 --- a/mysql-test/main/update_single_to_multi.result +++ b/mysql-test/main/update_single_to_multi.result @@ -3242,4 +3242,619 @@ o_orderkey o_totalprice 3139 40975.96 4903 34363.63 5607 24660.06 +CREATE TABLE partsupp_small ( +ps_partkey int(11) NOT NULL DEFAULT '0', +ps_suppkey int(11) NOT NULL DEFAULT '0', +ps_availqty int(11) DEFAULT NULL, +ps_supplycost double DEFAULT NULL, +ps_comment varchar(199) DEFAULT NULL, +PRIMARY KEY (ps_partkey,ps_suppkey), +KEY i_ps_partkey (ps_partkey), +KEY i_ps_suppkey (ps_suppkey) +); +create index i_ps_sup_part on partsupp_small(ps_suppkey, ps_partkey); +insert into partsupp_small select * from partsupp where ps_partkey <50; +analyze table partsupp_small persistent for all; +Table Op Msg_type Msg_text +dbt3_s001.partsupp_small analyze status Engine-independent statistics collected +dbt3_s001.partsupp_small analyze status OK +# LooseScan +# ========= +explain +select count(*) from lineitem where l_suppkey in +(select ps_suppkey from partsupp_small +where ps_partkey in (1,2,3)); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY partsupp_small index PRIMARY,i_ps_partkey,i_ps_suppkey,i_ps_sup_part i_ps_sup_part 8 NULL 176 Using where; Using index; LooseScan +1 PRIMARY lineitem ref i_l_suppkey i_l_suppkey 5 dbt3_s001.partsupp_small.ps_suppkey 600 Using index +explain format=json +select count(*) from lineitem where l_suppkey in +(select ps_suppkey from partsupp_small +where ps_partkey in (1,2,3)); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "cost": 0.776623555, + "nested_loop": [ + { + "table": { + "table_name": "partsupp_small", + "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"], + "loops": 1, + "rows": 176, + "cost": 0.019403477, + "filtered": 5.113636494, + "attached_condition": "partsupp_small.ps_partkey in (1,2,3)", + "using_index": true, + "loose_scan": true + } + }, + { + "table": { + "table_name": "lineitem", + "access_type": "ref", + "possible_keys": ["i_l_suppkey"], + "key": "i_l_suppkey", + "key_length": "5", + "used_key_parts": ["l_suppkey"], + "ref": ["dbt3_s001.partsupp_small.ps_suppkey"], + "loops": 9, + "rows": 600, + "cost": 0.757220078, + "filtered": 11.11111069, + "using_index": true + } + } + ] + } +} +select count(*) from lineitem where l_suppkey in +(select ps_suppkey from partsupp_small +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_small +where ps_partkey in (1,2,3)); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY lineitem ALL i_l_suppkey NULL NULL NULL 6005 +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED partsupp_small range PRIMARY,i_ps_partkey,i_ps_suppkey,i_ps_sup_part PRIMARY 4 NULL 9 Using where; Using index +explain format=json +update lineitem set l_extendedprice=l_extendedprice+10 where l_suppkey in +(select ps_suppkey from partsupp_small +where ps_partkey in (1,2,3)); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "cost": 2.191459679, + "nested_loop": [ + { + "table": { + "table_name": "lineitem", + "access_type": "ALL", + "possible_keys": ["i_l_suppkey"], + "loops": 1, + "rows": 6005, + "cost": 0.988432825, + "filtered": 100 + } + }, + { + "table": { + "table_name": "<subquery2>", + "access_type": "eq_ref", + "possible_keys": ["distinct_key"], + "key": "distinct_key", + "key_length": "4", + "used_key_parts": ["ps_suppkey"], + "ref": ["func"], + "rows": 1, + "filtered": 100, + "materialized": { + "unique": 1, + "query_block": { + "select_id": 2, + "nested_loop": [ + { + "table": { + "table_name": "partsupp_small", + "access_type": "range", + "possible_keys": [ + "PRIMARY", + "i_ps_partkey", + "i_ps_suppkey", + "i_ps_sup_part" + ], + "key": "PRIMARY", + "key_length": "4", + "used_key_parts": ["ps_partkey"], + "loops": 1, + "rows": 9, + "cost": 0.003756598, + "filtered": 100, + "attached_condition": "partsupp_small.ps_partkey in (1,2,3)", + "using_index": true + } + } + ] + } + } + } + } + ] + } +} +update lineitem set l_extendedprice=l_extendedprice+10 where l_suppkey in +(select ps_suppkey from partsupp_small +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_small +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_small +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_small +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_small +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_small +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_small +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_small +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_small +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_small +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_small +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_small +where ps_partkey in (1,2,3)); +ROUND(sum(l_extendedprice),2) count old_sum +136458704.22 5373 136458704.22 +drop procedure p; +# 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 OK +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_small 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_small ref PRIMARY,i_ps_partkey,i_ps_suppkey,i_ps_sup_part i_ps_sup_part 4 dbt3_s001.supplier.s_suppkey 17 Using where; Using index +1 PRIMARY lineitem ref i_l_suppkey_partkey,i_l_partkey i_l_suppkey_partkey 5 dbt3_s001.partsupp_small.ps_partkey 30 Using index +1 PRIMARY lineitem ref i_l_suppkey_partkey,i_l_partkey i_l_partkey 5 dbt3_s001.partsupp_small.ps_partkey 30 Using index; End temporary +explain format=json +select count(*) from lineitem where l_partkey in ( +select ps_partkey +from partsupp_small 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, + "cost": 4.129940741, + "nested_loop": [ + { + "duplicates_removal": [ + { + "table": { + "table_name": "supplier", + "access_type": "range", + "possible_keys": ["PRIMARY"], + "key": "PRIMARY", + "key_length": "4", + "used_key_parts": ["s_suppkey"], + "loops": 1, + "rows": 1, + "cost": 0.001478954, + "filtered": 100, + "attached_condition": "supplier.s_suppkey < 2", + "using_index": true + } + }, + { + "table": { + "table_name": "partsupp_small", + "access_type": "ref", + "possible_keys": [ + "PRIMARY", + "i_ps_partkey", + "i_ps_suppkey", + "i_ps_sup_part" + ], + "key": "i_ps_sup_part", + "key_length": "4", + "used_key_parts": ["ps_suppkey"], + "ref": ["dbt3_s001.supplier.s_suppkey"], + "loops": 1, + "rows": 17, + "cost": 0.003160332, + "filtered": 79.54545593, + "attached_condition": "partsupp_small.ps_partkey is not null", + "using_index": true + } + }, + { + "table": { + "table_name": "lineitem", + "access_type": "ref", + "possible_keys": ["i_l_suppkey_partkey", "i_l_partkey"], + "key": "i_l_suppkey_partkey", + "key_length": "5", + "used_key_parts": ["l_partkey"], + "ref": ["dbt3_s001.partsupp_small.ps_partkey"], + "loops": 14, + "rows": 30, + "cost": 0.069152188, + "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_small.ps_partkey"], + "loops": 420.35, + "rows": 30, + "cost": 1.994712365, + "filtered": 0.237896994, + "using_index": true + } + } + ] + } + ] + } +} +select count(*) from lineitem where l_partkey in ( +select ps_partkey +from partsupp_small join lineitem on ps_partkey=l_partkey +where ps_suppkey in ( +select s_suppkey from supplier where s_suppkey < 2 +) +); +count(*) +471 +select 471 as count, 10751458.66 as old_sum; +count old_sum +471 10751458.66 +explain +update lineitem set l_extendedprice=l_extendedprice+10 where l_partkey in ( +select ps_partkey +from partsupp_small 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_small ref PRIMARY,i_ps_partkey,i_ps_suppkey,i_ps_sup_part i_ps_sup_part 4 dbt3_s001.supplier.s_suppkey 17 Using where; Using index +1 PRIMARY lineitem ref i_l_suppkey_partkey,i_l_partkey i_l_suppkey_partkey 5 dbt3_s001.partsupp_small.ps_partkey 30 +1 PRIMARY lineitem ref i_l_suppkey_partkey,i_l_partkey i_l_partkey 5 dbt3_s001.partsupp_small.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_small 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, + "cost": 4.590092321, + "nested_loop": [ + { + "duplicates_removal": [ + { + "table": { + "table_name": "supplier", + "access_type": "range", + "possible_keys": ["PRIMARY"], + "key": "PRIMARY", + "key_length": "4", + "used_key_parts": ["s_suppkey"], + "loops": 1, + "rows": 1, + "cost": 0.001478954, + "filtered": 100, + "attached_condition": "supplier.s_suppkey < 2", + "using_index": true + } + }, + { + "table": { + "table_name": "partsupp_small", + "access_type": "ref", + "possible_keys": [ + "PRIMARY", + "i_ps_partkey", + "i_ps_suppkey", + "i_ps_sup_part" + ], + "key": "i_ps_sup_part", + "key_length": "4", + "used_key_parts": ["ps_suppkey"], + "ref": ["dbt3_s001.supplier.s_suppkey"], + "loops": 1, + "rows": 17, + "cost": 0.003160332, + "filtered": 79.54545593, + "attached_condition": "partsupp_small.ps_partkey is not null", + "using_index": true + } + }, + { + "table": { + "table_name": "lineitem", + "access_type": "ref", + "possible_keys": ["i_l_suppkey_partkey", "i_l_partkey"], + "key": "i_l_suppkey_partkey", + "key_length": "5", + "used_key_parts": ["l_partkey"], + "ref": ["dbt3_s001.partsupp_small.ps_partkey"], + "loops": 14, + "rows": 30, + "cost": 0.529303768, + "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_small.ps_partkey"], + "loops": 420.35, + "rows": 30, + "cost": 1.994712365, + "filtered": 0.237896994, + "using_index": true + } + } + ] + } + ] + } +} +update lineitem set l_extendedprice=l_extendedprice+10 where l_partkey in ( +select ps_partkey +from partsupp_small 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), 471 as count, +(10751458.66+10*471) as 'old_sum+10*count' + from lineitem where l_partkey in ( +select ps_partkey +from partsupp_small 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 +10756168.66 471 10756168.66 +update lineitem set l_extendedprice=l_extendedprice-10 where l_partkey in ( +select ps_partkey +from partsupp_small 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), 471 as count, +10751458.66 as old_sum from lineitem where l_partkey in ( +select ps_partkey +from partsupp_small 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 +10751458.66 471 10751458.66 +# DuplicateWeedout PS +# =================== +prepare stmt from " +update lineitem set l_extendedprice=l_extendedprice+? where l_partkey in ( +select ps_partkey +from partsupp_small join lineitem on ps_partkey=l_partkey +where ps_suppkey in ( +select s_suppkey from supplier where s_suppkey < 2 +) +); +"; +select 471 as count, 10751458.66 as old_sum; +count old_sum +471 10751458.66 +set @a1=20; +execute stmt using @a1; +select ROUND(sum(l_extendedprice),2), 471 as count, +(10751458.66+20*471) as 'old_sum+20*count' + from lineitem where l_partkey in ( +select ps_partkey +from partsupp_small 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 +10760878.66 471 10760878.66 +set @a2=10; +execute stmt using @a2; +select ROUND(sum(l_extendedprice),2), 471 as count, +(10751458.66+30*471) as 'old_sum+30*count' + from lineitem where l_partkey in ( +select ps_partkey +from partsupp_small 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 +10765588.66 471 10765588.66 +execute stmt using -(@a1+@a2); +select ROUND(sum(l_extendedprice),2), 471 as count, +10751458.66 as old_sum from lineitem where l_partkey in ( +select ps_partkey +from partsupp_small 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 +10751458.66 471 10751458.66 +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_small join lineitem on ps_partkey=l_partkey +where ps_suppkey in ( +select s_suppkey from supplier where s_suppkey < 2 +) +); +select 471 as count, 10751458.66 as old_sum; +count old_sum +471 10751458.66 +call p(10); +select ROUND(sum(l_extendedprice),2), 471 as count, +(10751458.66+10*471) as 'old_sum+10*count' + from lineitem where l_partkey in ( +select ps_partkey +from partsupp_small 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 +10756168.66 471 10756168.66 +call p(20); +select ROUND(sum(l_extendedprice),2), 471 as count, +(10751458.66+30*471) as 'old_sum+30*count' + from lineitem where l_partkey in ( +select ps_partkey +from partsupp_small 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 +10765588.66 471 10765588.66 +call p(-(10+20)); +select ROUND(sum(l_extendedprice),2), 471 as count, +10751458.66 as old_sum from lineitem where l_partkey in ( +select ps_partkey +from partsupp_small 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 +10751458.66 471 10751458.66 +drop procedure p; +set @@optimizer_switch=@tmp_optimizer_switch; +drop table partsupp_small; 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 a215c5a..7364806 100644 --- a/mysql-test/main/update_single_to_multi.test +++ b/mysql-test/main/update_single_to_multi.test @@ -587,4 +587,246 @@ update orders set o_totalprice = o_totalprice+50 where $c11; eval select o_orderkey, o_totalprice from orders where $c11; +CREATE TABLE partsupp_small ( + ps_partkey int(11) NOT NULL DEFAULT '0', + ps_suppkey int(11) NOT NULL DEFAULT '0', + ps_availqty int(11) DEFAULT NULL, + ps_supplycost double DEFAULT NULL, + ps_comment varchar(199) DEFAULT NULL, + PRIMARY KEY (ps_partkey,ps_suppkey), + KEY i_ps_partkey (ps_partkey), + KEY i_ps_suppkey (ps_suppkey) +); + +create index i_ps_sup_part on partsupp_small(ps_suppkey, ps_partkey); +insert into partsupp_small select * from partsupp where ps_partkey <50; +analyze table partsupp_small persistent for all; + +--echo # LooseScan +--echo # ========= + +let $c12 = l_suppkey in + (select ps_suppkey from partsupp_small + 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; + +--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_small 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 table partsupp_small; + DROP DATABASE dbt3_s001; diff --git a/mysql-test/main/update_use_source.result b/mysql-test/main/update_use_source.result index 99d7242..d756775 100644 --- a/mysql-test/main/update_use_source.result +++ b/mysql-test/main/update_use_source.result @@ -1,4 +1,16 @@ -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; +####################################### +# # +# Engine InnoDB # +# # +####################################### +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); create view v1 as select * from t1 where c2=2; create trigger trg_t1 before update on t1 for each row begin @@ -6,37 +18,39 @@ 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; -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 -Test without any index -# -# Update a with value from subquery on the same table, no search clause. ALL access -# -start transaction; -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 ; +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 NULL, NULL, c1+10,c2,c3+10 from t1; +insert into t1 select NULL, NULL, 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 table tmp as select * from t1; +####################################### +# Test without any index # +####################################### +# +# Update with value from subquery on the same table +# +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 +explain select * from t1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 32 +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 32 +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 32 Using where +update t1 set c1=(select a.c3 from t1 a where a.c3 = t1.c3); +affected rows: 32 +info: Rows matched: 32 Changed: 32 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 * @@ -46,20 +60,56 @@ concat(old_c1,'->',c1) c3 Changed 2->6 6 * 2->7 7 * 2->8 8 * -rollback; +11->11 11 +11->12 12 * +11->13 13 * +12->14 14 * +12->15 15 * +12->16 16 * +12->17 17 * +12->18 18 * +21->21 21 +21->22 22 * +21->23 23 * +22->24 24 * +22->25 25 * +22->26 26 * +22->27 27 * +22->28 28 * +31->31 31 +31->32 32 * +31->33 33 * +32->34 34 * +32->35 35 * +32->36 36 * +32->37 37 * +32->38 38 * +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 -where c1 <2 -and exists (select 'X' - from t1 a -where a.c1 = t1.c1); +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 +explain select * from t1 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 32 Using where +1 PRIMARY a ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) +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 32 Using where +1 PRIMARY a ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1) +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,19 +119,55 @@ NULL 5 NULL 6 NULL 7 NULL 8 -rollback; +NULL 11 +NULL 12 +NULL 13 +NULL 14 +NULL 15 +NULL 16 +NULL 17 +NULL 18 +NULL 21 +NULL 22 +NULL 23 +NULL 24 +NULL 25 +NULL 26 +NULL 27 +NULL 28 +NULL 31 +NULL 32 +NULL 33 +NULL 34 +NULL 35 +NULL 36 +NULL 37 +NULL 38 +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; +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 +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 +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 a ALL NULL NULL NULL NULL 8 Using where; FirstMatch(t1) -start transaction; +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 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; +affected rows: 20 +info: Rows matched: 20 Changed: 20 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 @@ -91,13 +177,57 @@ NULL 5 2->12 6 * 2->12 7 * 2->12 8 * -rollback; +NULL 11 +NULL 12 +11->21 13 * +NULL 14 +NULL 15 +12->22 16 * +12->22 17 * +12->22 18 * +NULL 21 +21->31 22 * +21->31 23 * +NULL 24 +22->32 25 * +22->32 26 * +22->32 27 * +22->32 28 * +NULL 31 +31->41 32 * +31->41 33 * +NULL 34 +32->42 35 * +32->42 36 * +32->42 37 * +32->42 38 * +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; +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 +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 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 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 +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: 20 +info: Rows matched: 20 Changed: 20 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 @@ -107,18 +237,54 @@ NULL 5 2->12 6 * 2->12 7 * 2->12 8 * -rollback; +NULL 11 +NULL 12 +11->21 13 * +NULL 14 +NULL 15 +12->22 16 * +12->22 17 * +12->22 18 * +NULL 21 +21->31 22 * +21->31 23 * +NULL 24 +22->32 25 * +22->32 26 * +22->32 27 * +22->32 28 * +NULL 31 +31->41 32 * +31->41 33 * +NULL 34 +32->42 35 * +32->42 36 * +32->42 37 * +32->42 38 * +truncate table t1; +insert into t1 select * from tmp; # -Update using a view in subquery +# Update with a reference to view in subquery +# in settable value # -start transaction; -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; +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 +explain select * from t1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 32 +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 32 +2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 32 Using where +update t1 set c1=c1 +(select max(a.c2) from v1 a +where a.c1 = t1.c1); +affected rows: 32 +info: Rows matched: 32 Changed: 32 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 * @@ -128,19 +294,53 @@ concat(old_c1,'->',c1) c3 Changed 2->4 6 * 2->4 7 * 2->4 8 * -rollback; +11->13 11 * +11->13 12 * +11->13 13 * +12->14 14 * +12->14 15 * +12->14 16 * +12->14 17 * +12->14 18 * +21->23 21 * +21->23 22 * +21->23 23 * +22->24 24 * +22->24 25 * +22->24 26 * +22->24 27 * +22->24 28 * +31->33 31 * +31->33 32 * +31->33 33 * +32->34 34 * +32->34 35 * +32->34 36 * +32->34 37 * +32->34 38 * +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; -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; +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 +explain select * from v1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 32 Using where +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 32 Using where +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 32 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: 7 +info: Rows matched: 7 Changed: 7 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 @@ -150,20 +350,55 @@ NULL 4 NULL 6 NULL 7 NULL 8 -rollback; +NULL 11 +11->24 12 * +NULL 13 +NULL 14 +12->27 15 * +NULL 16 +NULL 17 +NULL 18 +21->35 21 * +NULL 22 +NULL 23 +22->38 24 * +NULL 25 +NULL 26 +NULL 27 +NULL 28 +31->45 31 * +NULL 32 +NULL 33 +32->48 34 * +NULL 35 +NULL 36 +NULL 37 +NULL 38 +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 -where c1 <2 -and exists (select 'X' - from v1 a -where a.c1 = v1.c1); +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 +explain select * from v1 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 32 Using where +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) +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 32 Using where +2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 32 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; +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 * @@ -173,22 +408,57 @@ NULL 5 NULL 6 NULL 7 NULL 8 -rollback; +NULL 11 +NULL 12 +NULL 13 +NULL 14 +NULL 15 +NULL 16 +NULL 17 +NULL 18 +NULL 21 +NULL 22 +NULL 23 +NULL 24 +NULL 25 +NULL 26 +NULL 27 +NULL 28 +NULL 31 +NULL 32 +NULL 33 +NULL 34 +NULL 35 +NULL 36 +NULL 37 +NULL 38 +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; +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 +explain select * from v1 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 32 Using where +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) +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 32 Using where +3 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 32 Using where +2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 32 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 * @@ -198,41 +468,107 @@ NULL 4 NULL 6 NULL 7 NULL 8 -rollback; +NULL 11 +NULL 12 +NULL 13 +NULL 14 +NULL 15 +NULL 16 +NULL 17 +NULL 18 +NULL 21 +NULL 22 +NULL 23 +NULL 24 +NULL 25 +NULL 26 +NULL 27 +NULL 28 +NULL 31 +NULL 32 +NULL 33 +NULL 34 +NULL 35 +NULL 36 +NULL 37 +NULL 38 +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); +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 +explain select * from t1 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 32 +1 PRIMARY a ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) +explain update t1 set c3=c3+110 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 +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 +1 PRIMARY a ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1) +update t1 set c3=c3+110 where c2 in (select distinct a.c2 from t1 a where t1.c1=a.c1); +affected rows: 32 +info: Rows matched: 32 Changed: 32 Warnings: 0 select c3 from t1; c3 -11 -12 -13 -14 -15 -16 -17 -18 -rollback; -# -# update with a limit -# -start transaction; +111 +112 +113 +114 +115 +116 +117 +118 +121 +122 +123 +124 +125 +126 +127 +128 +131 +132 +133 +134 +135 +136 +137 +138 +141 +142 +143 +144 +145 +146 +147 +148 +truncate table t1; +insert into t1 select * from tmp; +# +# Update with a limit +# +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 +explain select * from t1 limit 2; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 32 +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 32 +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 32 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 * @@ -242,19 +578,55 @@ NULL 5 NULL 6 NULL 7 NULL 8 -rollback; +NULL 11 +NULL 12 +NULL 13 +NULL 14 +NULL 15 +NULL 16 +NULL 17 +NULL 18 +NULL 21 +NULL 22 +NULL 23 +NULL 24 +NULL 25 +NULL 26 +NULL 27 +NULL 28 +NULL 31 +NULL 32 +NULL 33 +NULL 34 +NULL 35 +NULL 36 +NULL 37 +NULL 38 +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; +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 +explain select * from t1 order by c3 desc limit 2; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 32 Using filesort +explain update t1 +set c1=(select a.c3 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 2; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using filesort +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 32 Using where 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 @@ -262,22 +634,61 @@ NULL 3 NULL 4 NULL 5 NULL 6 -2->7 7 * -2->8 8 * -rollback; -Test with an index on updated columns +NULL 7 +NULL 8 +NULL 11 +NULL 12 +NULL 13 +NULL 14 +NULL 15 +NULL 16 +NULL 17 +NULL 18 +NULL 21 +NULL 22 +NULL 23 +NULL 24 +NULL 25 +NULL 26 +NULL 27 +NULL 28 +NULL 31 +NULL 32 +NULL 33 +NULL 34 +NULL 35 +NULL 36 +32->37 37 * +32->38 38 * +truncate table t1; +insert into t1 select * from tmp; +####################################### +# Test with an index # +####################################### 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); -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 ; +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 +explain select * from t1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 32 +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 32 +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 32 Using where +update t1 set c1=(select a.c3 from t1 a where a.c3 = t1.c3); +affected rows: 32 +info: Rows matched: 32 Changed: 32 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 * @@ -287,20 +698,56 @@ concat(old_c1,'->',c1) c3 Changed 2->6 6 * 2->7 7 * 2->8 8 * -rollback; +11->11 11 +11->12 12 * +11->13 13 * +12->14 14 * +12->15 15 * +12->16 16 * +12->17 17 * +12->18 18 * +21->21 21 +21->22 22 * +21->23 23 * +22->24 24 * +22->25 25 * +22->26 26 * +22->27 27 * +22->28 28 * +31->31 31 +31->32 32 * +31->33 33 * +32->34 34 * +32->35 35 * +32->36 36 * +32->37 37 * +32->38 38 * +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 -where c1 <2 -and exists (select 'X' - from t1 a -where a.c1 = t1.c1); +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 +explain select * from t1 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 32 Using where +1 PRIMARY a index NULL t1_c2 10 NULL 32 Using where; Using index; FirstMatch(t1); Using join buffer (flat, BNL join) +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 32 Using where +1 PRIMARY a index NULL t1_c2 10 NULL 32 Using where; Using index; FirstMatch(t1) +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 * @@ -310,19 +757,53 @@ NULL 5 NULL 6 NULL 7 NULL 8 -rollback; +NULL 11 +NULL 12 +NULL 13 +NULL 14 +NULL 15 +NULL 16 +NULL 17 +NULL 18 +NULL 21 +NULL 22 +NULL 23 +NULL 24 +NULL 25 +NULL 26 +NULL 27 +NULL 28 +NULL 31 +NULL 32 +NULL 33 +NULL 34 +NULL 35 +NULL 36 +NULL 37 +NULL 38 +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; +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 +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 a ref t1_c2 t1_c2 5 test.t1.c2 5 Using index; FirstMatch(t1) +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 a ref t1_c2 t1_c2 5 test.t1.c2 8 Using index; FirstMatch(t1) -start transaction; +1 PRIMARY t1 ALL t1_c2 NULL NULL NULL 32 Using where +1 PRIMARY a ref t1_c2 t1_c2 5 test.t1.c2 5 Using index; FirstMatch(t1) 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; +affected rows: 20 +info: Rows matched: 20 Changed: 20 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 @@ -332,13 +813,55 @@ NULL 5 2->12 6 * 2->12 7 * 2->12 8 * -rollback; +NULL 11 +NULL 12 +11->21 13 * +NULL 14 +NULL 15 +12->22 16 * +12->22 17 * +12->22 18 * +NULL 21 +21->31 22 * +21->31 23 * +NULL 24 +22->32 25 * +22->32 26 * +22->32 27 * +22->32 28 * +NULL 31 +31->41 32 * +31->41 33 * +NULL 34 +32->42 35 * +32->42 36 * +32->42 37 * +32->42 38 * +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; +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 +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 a ref t1_c2 t1_c2 5 test.t1.c2 5 Using index; FirstMatch(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 32 Using where; Using filesort +1 PRIMARY a ref t1_c2 t1_c2 5 test.t1.c2 5 Using index; FirstMatch(t1) +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: 20 +info: Rows matched: 20 Changed: 20 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 @@ -348,18 +871,54 @@ NULL 5 2->12 6 * 2->12 7 * 2->12 8 * -rollback; +NULL 11 +NULL 12 +11->21 13 * +NULL 14 +NULL 15 +12->22 16 * +12->22 17 * +12->22 18 * +NULL 21 +21->31 22 * +21->31 23 * +NULL 24 +22->32 25 * +22->32 26 * +22->32 27 * +22->32 28 * +NULL 31 +31->41 32 * +31->41 33 * +NULL 34 +32->42 35 * +32->42 36 * +32->42 37 * +32->42 38 * +truncate table t1; +insert into t1 select * from tmp; # -Update using a view in subquery +# Update with a reference to view in subquery +# in settable value # -start transaction; -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; +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 +explain select * from t1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 32 +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 32 +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: 32 +info: Rows matched: 32 Changed: 32 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 * @@ -369,19 +928,53 @@ concat(old_c1,'->',c1) c3 Changed 2->4 6 * 2->4 7 * 2->4 8 * -rollback; +11->13 11 * +11->13 12 * +11->13 13 * +12->14 14 * +12->14 15 * +12->14 16 * +12->14 17 * +12->14 18 * +21->23 21 * +21->23 22 * +21->23 23 * +22->24 24 * +22->24 25 * +22->24 26 * +22->24 27 * +22->24 28 * +31->33 31 * +31->33 32 * +31->33 33 * +32->34 34 * +32->34 35 * +32->34 36 * +32->34 37 * +32->34 38 * +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; -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; +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 +explain select * from v1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref t1_c2 t1_c2 5 const 8 +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 8 Using where +2 DEPENDENT SUBQUERY a index NULL t1_c2 10 NULL 32 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: 7 +info: Rows matched: 7 Changed: 7 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 @@ -391,20 +984,55 @@ NULL 4 NULL 6 NULL 7 NULL 8 -rollback; +NULL 11 +11->24 12 * +NULL 13 +NULL 14 +12->27 15 * +NULL 16 +NULL 17 +NULL 18 +21->35 21 * +NULL 22 +NULL 23 +22->38 24 * +NULL 25 +NULL 26 +NULL 27 +NULL 28 +31->45 31 * +NULL 32 +NULL 33 +32->48 34 * +NULL 35 +NULL 36 +NULL 37 +NULL 38 +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 -where c1 <2 -and exists (select 'X' - from v1 a -where a.c1 = v1.c1); +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 +explain select * from v1 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 +1 PRIMARY t1 ref t1_c2 t1_c2 10 const,test.t1.c1 1 Using index; FirstMatch(t1) +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 DEPENDENT SUBQUERY t1 ref t1_c2 t1_c2 10 const,func 1 Using where; 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; +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 * @@ -414,22 +1042,57 @@ NULL 5 NULL 6 NULL 7 NULL 8 -rollback; +NULL 11 +NULL 12 +NULL 13 +NULL 14 +NULL 15 +NULL 16 +NULL 17 +NULL 18 +NULL 21 +NULL 22 +NULL 23 +NULL 24 +NULL 25 +NULL 26 +NULL 27 +NULL 28 +NULL 31 +NULL 32 +NULL 33 +NULL 34 +NULL 35 +NULL 36 +NULL 37 +NULL 38 +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; +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 +explain select * from v1 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 +1 PRIMARY t1 ref t1_c2 t1_c2 5 const 8 Using index; FirstMatch(t1) +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 DEPENDENT SUBQUERY t1 ref t1_c2 t1_c2 5 const 8 Using where; 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 * @@ -439,41 +1102,107 @@ NULL 4 NULL 6 NULL 7 NULL 8 -rollback; +NULL 11 +NULL 12 +NULL 13 +NULL 14 +NULL 15 +NULL 16 +NULL 17 +NULL 18 +NULL 21 +NULL 22 +NULL 23 +NULL 24 +NULL 25 +NULL 26 +NULL 27 +NULL 28 +NULL 31 +NULL 32 +NULL 33 +NULL 34 +NULL 35 +NULL 36 +NULL 37 +NULL 38 +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); +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 +explain select * from t1 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 32 Using where +1 PRIMARY a ref t1_c2 t1_c2 10 test.t1.c2,test.t1.c1 1 Using index; FirstMatch(t1) +explain update t1 set c3=c3+110 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 t1 ALL t1_c2 NULL NULL NULL 32 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 +update t1 set c3=c3+110 where c2 in (select distinct a.c2 from t1 a where t1.c1=a.c1); +affected rows: 32 +info: Rows matched: 32 Changed: 32 Warnings: 0 select c3 from t1; c3 -11 -12 -13 -14 -15 -16 -17 -18 -rollback; -# -# update with a limit -# -start transaction; +111 +112 +113 +114 +115 +116 +117 +118 +121 +122 +123 +124 +125 +126 +127 +128 +131 +132 +133 +134 +135 +136 +137 +138 +141 +142 +143 +144 +145 +146 +147 +148 +truncate table t1; +insert into t1 select * from tmp; +# +# Update with a limit +# +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 +explain select * from t1 limit 2; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 32 +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 32 +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 32 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 * @@ -483,19 +1212,55 @@ NULL 5 NULL 6 NULL 7 NULL 8 -rollback; +NULL 11 +NULL 12 +NULL 13 +NULL 14 +NULL 15 +NULL 16 +NULL 17 +NULL 18 +NULL 21 +NULL 22 +NULL 23 +NULL 24 +NULL 25 +NULL 26 +NULL 27 +NULL 28 +NULL 31 +NULL 32 +NULL 33 +NULL 34 +NULL 35 +NULL 36 +NULL 37 +NULL 38 +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; +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 +explain select * from t1 order by c3 desc limit 2; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 32 Using filesort +explain update t1 +set c1=(select a.c3 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 2; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using filesort +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 32 Using where 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 @@ -503,22 +1268,62 @@ NULL 3 NULL 4 NULL 5 NULL 6 -2->7 7 * -2->8 8 * -rollback; -Test with an index on updated columns -create index t1_c3 on t1 (c3); +NULL 7 +NULL 8 +NULL 11 +NULL 12 +NULL 13 +NULL 14 +NULL 15 +NULL 16 +NULL 17 +NULL 18 +NULL 21 +NULL 22 +NULL 23 +NULL 24 +NULL 25 +NULL 26 +NULL 27 +NULL 28 +NULL 31 +NULL 32 +NULL 33 +NULL 34 +NULL 35 +NULL 36 +32->37 37 * +32->38 38 * +truncate table t1; +insert into t1 select * from tmp; +####################################### +# Test with a primary key # +####################################### +drop index t1_c2 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); -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 ; +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 +explain select * from t1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 32 +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 32 +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: 32 +info: Rows matched: 32 Changed: 32 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 * @@ -528,20 +1333,56 @@ concat(old_c1,'->',c1) c3 Changed 2->6 6 * 2->7 7 * 2->8 8 * -rollback; +11->11 11 +11->12 12 * +11->13 13 * +12->14 14 * +12->15 15 * +12->16 16 * +12->17 17 * +12->18 18 * +21->21 21 +21->22 22 * +21->23 23 * +22->24 24 * +22->25 25 * +22->26 26 * +22->27 27 * +22->28 28 * +31->31 31 +31->32 32 * +31->33 33 * +32->34 34 * +32->35 35 * +32->36 36 * +32->37 37 * +32->38 38 * +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 -where c1 <2 -and exists (select 'X' - from t1 a -where a.c1 = t1.c1); +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 +explain select * from t1 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 32 Using where +1 PRIMARY a ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) +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 32 Using where +1 PRIMARY a ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1) +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 * @@ -551,19 +1392,55 @@ NULL 5 NULL 6 NULL 7 NULL 8 -rollback; +NULL 11 +NULL 12 +NULL 13 +NULL 14 +NULL 15 +NULL 16 +NULL 17 +NULL 18 +NULL 21 +NULL 22 +NULL 23 +NULL 24 +NULL 25 +NULL 26 +NULL 27 +NULL 28 +NULL 31 +NULL 32 +NULL 33 +NULL 34 +NULL 35 +NULL 36 +NULL 37 +NULL 38 +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; +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 +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 +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 a index t1_c2 t1_c2 10 NULL 8 Using where; Using index; LooseScan -1 PRIMARY t1 ref t1_c2 t1_c2 5 test.a.c2 1 -start transaction; +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 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; +affected rows: 20 +info: Rows matched: 20 Changed: 20 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 @@ -573,13 +1450,57 @@ NULL 5 2->12 6 * 2->12 7 * 2->12 8 * -rollback; +NULL 11 +NULL 12 +11->21 13 * +NULL 14 +NULL 15 +12->22 16 * +12->22 17 * +12->22 18 * +NULL 21 +21->31 22 * +21->31 23 * +NULL 24 +22->32 25 * +22->32 26 * +22->32 27 * +22->32 28 * +NULL 31 +31->41 32 * +31->41 33 * +NULL 34 +32->42 35 * +32->42 36 * +32->42 37 * +32->42 38 * +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; +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 +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 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 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 +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: 20 +info: Rows matched: 20 Changed: 20 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 @@ -589,18 +1510,54 @@ NULL 5 2->12 6 * 2->12 7 * 2->12 8 * -rollback; +NULL 11 +NULL 12 +11->21 13 * +NULL 14 +NULL 15 +12->22 16 * +12->22 17 * +12->22 18 * +NULL 21 +21->31 22 * +21->31 23 * +NULL 24 +22->32 25 * +22->32 26 * +22->32 27 * +22->32 28 * +NULL 31 +31->41 32 * +31->41 33 * +NULL 34 +32->42 35 * +32->42 36 * +32->42 37 * +32->42 38 * +truncate table t1; +insert into t1 select * from tmp; # -Update using a view in subquery +# Update with a reference to view in subquery +# in settable value # -start transaction; -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; +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 +explain select * from t1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 32 +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 32 +2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 32 Using where +update t1 set c1=c1 +(select max(a.c2) from v1 a +where a.c1 = t1.c1); +affected rows: 32 +info: Rows matched: 32 Changed: 32 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 * @@ -610,19 +1567,53 @@ concat(old_c1,'->',c1) c3 Changed 2->4 6 * 2->4 7 * 2->4 8 * -rollback; +11->13 11 * +11->13 12 * +11->13 13 * +12->14 14 * +12->14 15 * +12->14 16 * +12->14 17 * +12->14 18 * +21->23 21 * +21->23 22 * +21->23 23 * +22->24 24 * +22->24 25 * +22->24 26 * +22->24 27 * +22->24 28 * +31->33 31 * +31->33 32 * +31->33 33 * +32->34 34 * +32->34 35 * +32->34 36 * +32->34 37 * +32->34 38 * +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; -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; +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 +explain select * from v1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 32 Using where +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 PRIMARY 4 NULL 29 Using where +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 32 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: 7 +info: Rows matched: 7 Changed: 7 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 @@ -632,20 +1623,55 @@ NULL 4 NULL 6 NULL 7 NULL 8 -rollback; +NULL 11 +11->24 12 * +NULL 13 +NULL 14 +12->27 15 * +NULL 16 +NULL 17 +NULL 18 +21->35 21 * +NULL 22 +NULL 23 +22->38 24 * +NULL 25 +NULL 26 +NULL 27 +NULL 28 +31->45 31 * +NULL 32 +NULL 33 +32->48 34 * +NULL 35 +NULL 36 +NULL 37 +NULL 38 +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 -where c1 <2 -and exists (select 'X' - from v1 a -where a.c1 = v1.c1); +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 +explain select * from v1 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 32 Using where +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) +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 32 Using where +2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 32 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; +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 * @@ -655,22 +1681,57 @@ NULL 5 NULL 6 NULL 7 NULL 8 -rollback; +NULL 11 +NULL 12 +NULL 13 +NULL 14 +NULL 15 +NULL 16 +NULL 17 +NULL 18 +NULL 21 +NULL 22 +NULL 23 +NULL 24 +NULL 25 +NULL 26 +NULL 27 +NULL 28 +NULL 31 +NULL 32 +NULL 33 +NULL 34 +NULL 35 +NULL 36 +NULL 37 +NULL 38 +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; +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 +explain select * from v1 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 32 Using where +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) +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 32 Using where +3 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 32 Using where +2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 32 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 * @@ -680,41 +1741,107 @@ NULL 4 NULL 6 NULL 7 NULL 8 -rollback; +NULL 11 +NULL 12 +NULL 13 +NULL 14 +NULL 15 +NULL 16 +NULL 17 +NULL 18 +NULL 21 +NULL 22 +NULL 23 +NULL 24 +NULL 25 +NULL 26 +NULL 27 +NULL 28 +NULL 31 +NULL 32 +NULL 33 +NULL 34 +NULL 35 +NULL 36 +NULL 37 +NULL 38 +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); +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 +explain select * from t1 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 +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 update t1 set c3=c3+110 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 32 +1 PRIMARY a ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1) +update t1 set c3=c3+110 where c2 in (select distinct a.c2 from t1 a where t1.c1=a.c1); +affected rows: 32 +info: Rows matched: 32 Changed: 32 Warnings: 0 select c3 from t1; c3 -11 -12 -13 -14 -15 -16 -17 -18 -rollback; -# -# update with a limit -# -start transaction; +111 +112 +113 +114 +115 +116 +117 +118 +121 +122 +123 +124 +125 +126 +127 +128 +131 +132 +133 +134 +135 +136 +137 +138 +141 +142 +143 +144 +145 +146 +147 +148 +truncate table t1; +insert into t1 select * from tmp; +# +# Update with a limit +# +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 +explain select * from t1 limit 2; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 32 +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 32 +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; +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 * @@ -724,19 +1851,55 @@ NULL 5 NULL 6 NULL 7 NULL 8 -rollback; +NULL 11 +NULL 12 +NULL 13 +NULL 14 +NULL 15 +NULL 16 +NULL 17 +NULL 18 +NULL 21 +NULL 22 +NULL 23 +NULL 24 +NULL 25 +NULL 26 +NULL 27 +NULL 28 +NULL 31 +NULL 32 +NULL 33 +NULL 34 +NULL 35 +NULL 36 +NULL 37 +NULL 38 +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; +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 +explain select * from t1 order by c3 desc limit 2; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index NULL PRIMARY 4 NULL 2 +explain update t1 +set c1=(select a.c3 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 2; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 index NULL PRIMARY 4 NULL 2 Using buffer +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) +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 @@ -744,127 +1907,7346 @@ NULL 3 NULL 4 NULL 5 NULL 6 -2->7 7 * -2->8 8 * -rollback; -Test with a primary key on updated columns -drop index t1_c3 on t1; -alter table t1 add primary key (c3); -# -# Update a with value from subquery on the same table, no search clause. ALL access -# -start transaction; -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 * -rollback; -# -# Update with search clause on the same table -# -start transaction; -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 -rollback; -# -# Update via RANGE or INDEX access if an index or a primary key exists -# -explain update t1 set c1=0 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 a index t1_c2 t1_c2 10 NULL 8 Using where; Using index; LooseScan -1 PRIMARY t1 ref t1_c2 t1_c2 5 test.a.c2 1 -start transaction; -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 * -rollback; -# -# 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; -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 * -rollback; -# -Update using a view in subquery -# -start transaction; -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 * -rollback; -# -# Update throw a view -# -start transaction; -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; +NULL 11 +NULL 12 +NULL 13 +NULL 14 +NULL 15 +NULL 16 +NULL 17 +NULL 18 +NULL 21 +NULL 22 +NULL 23 +NULL 24 +NULL 25 +NULL 26 +NULL 27 +NULL 28 +NULL 31 +NULL 32 +NULL 33 +NULL 34 +NULL 35 +NULL 36 +32->37 37 * +32->38 38 * +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 +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 +# 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 +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 +# 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 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 +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: 20 +info: Rows matched: 20 Changed: 20 Warnings: 0 +select c1,c2,c3 from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 0 +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 +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 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 +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 +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 +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: 3 +info: Rows matched: 3 Changed: 3 Warnings: 0 +select c1,c2,c3 from t1; +c1 c2 c3 +10 1 1 +10 2 2 +10 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 +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 +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 +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 +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 +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 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 +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 +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 +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 +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 +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 +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 +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; +####################################### +# # +# Engine Aria # +# # +####################################### +set default_storage_engine=Aria; +create table t1 (old_c1 integer, +old_c2 integer, +c1 integer, +c2 integer, +c3 integer); +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); +insert into t1 select NULL, NULL, c1+10,c2,c3+10 from t1; +insert into t1 select NULL, NULL, 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 table tmp as select * from t1; +####################################### +# Test without any index # +####################################### +# +# Update with value from subquery on the same table +# +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 +explain select * from t1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 32 +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 32 +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 32 Using where +update t1 set c1=(select a.c3 from t1 a where a.c3 = t1.c3); +affected rows: 32 +info: Rows matched: 32 Changed: 32 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 * +11->11 11 +11->12 12 * +11->13 13 * +12->14 14 * +12->15 15 * +12->16 16 * +12->17 17 * +12->18 18 * +21->21 21 +21->22 22 * +21->23 23 * +22->24 24 * +22->25 25 * +22->26 26 * +22->27 27 * +22->28 28 * +31->31 31 +31->32 32 * +31->33 33 * +32->34 34 * +32->35 35 * +32->36 36 * +32->37 37 * +32->38 38 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update 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 +explain select * from t1 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 32 Using where +1 PRIMARY a ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) +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 32 Using where +1 PRIMARY a ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1) +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 +NULL 11 +NULL 12 +NULL 13 +NULL 14 +NULL 15 +NULL 16 +NULL 17 +NULL 18 +NULL 21 +NULL 22 +NULL 23 +NULL 24 +NULL 25 +NULL 26 +NULL 27 +NULL 28 +NULL 31 +NULL 32 +NULL 33 +NULL 34 +NULL 35 +NULL 36 +NULL 37 +NULL 38 +truncate table t1; +insert into t1 select * from tmp; +# +# Update 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 +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 +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 32 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ALL NULL NULL NULL NULL 32 +update t1 set c1=c1+10 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 >= 3; +affected rows: 20 +info: Rows matched: 20 Changed: 20 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 * +NULL 11 +NULL 12 +11->21 13 * +NULL 14 +NULL 15 +12->22 16 * +12->22 17 * +12->22 18 * +NULL 21 +21->31 22 * +21->31 23 * +NULL 24 +22->32 25 * +22->32 26 * +22->32 27 * +22->32 28 * +NULL 31 +31->41 32 * +31->41 33 * +NULL 34 +32->42 35 * +32->42 36 * +32->42 37 * +32->42 38 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update 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 +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 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 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 +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: 20 +info: Rows matched: 20 Changed: 20 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 * +NULL 11 +NULL 12 +11->21 13 * +NULL 14 +NULL 15 +12->22 16 * +12->22 17 * +12->22 18 * +NULL 21 +21->31 22 * +21->31 23 * +NULL 24 +22->32 25 * +22->32 26 * +22->32 27 * +22->32 28 * +NULL 31 +31->41 32 * +31->41 33 * +NULL 34 +32->42 35 * +32->42 36 * +32->42 37 * +32->42 38 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update with a reference to view in subquery +# in settable value +# +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 +explain select * from t1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 32 +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 32 +2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 32 Using where +update t1 set c1=c1 +(select max(a.c2) from v1 a +where a.c1 = t1.c1); +affected rows: 32 +info: Rows matched: 32 Changed: 32 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 * +11->13 11 * +11->13 12 * +11->13 13 * +12->14 14 * +12->14 15 * +12->14 16 * +12->14 17 * +12->14 18 * +21->23 21 * +21->23 22 * +21->23 23 * +22->24 24 * +22->24 25 * +22->24 26 * +22->24 27 * +22->24 28 * +31->33 31 * +31->33 32 * +31->33 33 * +32->34 34 * +32->34 35 * +32->34 36 * +32->34 37 * +32->34 38 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update 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 +explain select * from v1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 32 Using where +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 32 Using where +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 32 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: 7 +info: Rows matched: 7 Changed: 7 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 +NULL 11 +11->24 12 * +NULL 13 +NULL 14 +12->27 15 * +NULL 16 +NULL 17 +NULL 18 +21->35 21 * +NULL 22 +NULL 23 +22->38 24 * +NULL 25 +NULL 26 +NULL 27 +NULL 28 +31->45 31 * +NULL 32 +NULL 33 +32->48 34 * +NULL 35 +NULL 36 +NULL 37 +NULL 38 +truncate table t1; +insert into t1 select * from tmp; +# +# Update view with 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 +explain select * from v1 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 32 Using where +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) +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 32 Using where +2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 32 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 +NULL 11 +NULL 12 +NULL 13 +NULL 14 +NULL 15 +NULL 16 +NULL 17 +NULL 18 +NULL 21 +NULL 22 +NULL 23 +NULL 24 +NULL 25 +NULL 26 +NULL 27 +NULL 28 +NULL 31 +NULL 32 +NULL 33 +NULL 34 +NULL 35 +NULL 36 +NULL 37 +NULL 38 +truncate table t1; +insert into t1 select * from tmp; +# +# Update view with EXISTS and 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 +explain select * from v1 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 32 Using where +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) +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 32 Using where +3 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 32 Using where +2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 32 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 +NULL 11 +NULL 12 +NULL 13 +NULL 14 +NULL 15 +NULL 16 +NULL 17 +NULL 18 +NULL 21 +NULL 22 +NULL 23 +NULL 24 +NULL 25 +NULL 26 +NULL 27 +NULL 28 +NULL 31 +NULL 32 +NULL 33 +NULL 34 +NULL 35 +NULL 36 +NULL 37 +NULL 38 +truncate table t1; +insert into t1 select * from tmp; +# +# Update with IN predicand over the updated table in WHERE +# +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 +explain select * from t1 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 32 +1 PRIMARY a ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) +explain update t1 set c3=c3+110 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 32 +1 PRIMARY a ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1) +update t1 set c3=c3+110 where c2 in (select distinct a.c2 from t1 a where t1.c1=a.c1); +affected rows: 32 +info: Rows matched: 32 Changed: 32 Warnings: 0 +select c3 from t1; +c3 +111 +112 +113 +114 +115 +116 +117 +118 +121 +122 +123 +124 +125 +126 +127 +128 +131 +132 +133 +134 +135 +136 +137 +138 +141 +142 +143 +144 +145 +146 +147 +148 +truncate table t1; +insert into t1 select * from tmp; +# +# Update with a limit +# +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 +explain select * from t1 limit 2; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 32 +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 32 +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 32 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 +NULL 11 +NULL 12 +NULL 13 +NULL 14 +NULL 15 +NULL 16 +NULL 17 +NULL 18 +NULL 21 +NULL 22 +NULL 23 +NULL 24 +NULL 25 +NULL 26 +NULL 27 +NULL 28 +NULL 31 +NULL 32 +NULL 33 +NULL 34 +NULL 35 +NULL 36 +NULL 37 +NULL 38 +truncate table t1; +insert into t1 select * from tmp; +# +# Update with a limit and an 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 +explain select * from t1 order by c3 desc limit 2; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 32 Using filesort +explain update t1 +set c1=(select a.c3 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 2; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using filesort +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 32 Using where +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 +NULL 7 +NULL 8 +NULL 11 +NULL 12 +NULL 13 +NULL 14 +NULL 15 +NULL 16 +NULL 17 +NULL 18 +NULL 21 +NULL 22 +NULL 23 +NULL 24 +NULL 25 +NULL 26 +NULL 27 +NULL 28 +NULL 31 +NULL 32 +NULL 33 +NULL 34 +NULL 35 +NULL 36 +32->37 37 * +32->38 38 * +truncate table t1; +insert into t1 select * from tmp; +####################################### +# Test with an index # +####################################### +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 +# +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 +explain select * from t1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 32 +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 32 +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 32 Using where +update t1 set c1=(select a.c3 from t1 a where a.c3 = t1.c3); +affected rows: 32 +info: Rows matched: 32 Changed: 32 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 * +11->11 11 +11->12 12 * +11->13 13 * +12->14 14 * +12->15 15 * +12->16 16 * +12->17 17 * +12->18 18 * +21->21 21 +21->22 22 * +21->23 23 * +22->24 24 * +22->25 25 * +22->26 26 * +22->27 27 * +22->28 28 * +31->31 31 +31->32 32 * +31->33 33 * +32->34 34 * +32->35 35 * +32->36 36 * +32->37 37 * +32->38 38 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update 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 +explain select * from t1 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 32 Using where +1 PRIMARY a index NULL t1_c2 10 NULL 32 Using where; Using index; FirstMatch(t1); Using join buffer (flat, BNL join) +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 32 Using where +1 PRIMARY a index NULL t1_c2 10 NULL 32 Using where; Using index; FirstMatch(t1) +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 +NULL 11 +NULL 12 +NULL 13 +NULL 14 +NULL 15 +NULL 16 +NULL 17 +NULL 18 +NULL 21 +NULL 22 +NULL 23 +NULL 24 +NULL 25 +NULL 26 +NULL 27 +NULL 28 +NULL 31 +NULL 32 +NULL 33 +NULL 34 +NULL 35 +NULL 36 +NULL 37 +NULL 38 +truncate table t1; +insert into t1 select * from tmp; +# +# Update 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 +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 range t1_c2 t1_c2 5 NULL 21 Using index condition +1 PRIMARY a ref t1_c2 t1_c2 5 test.t1.c2 5 Using index; FirstMatch(t1) +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 21 Using index condition +1 PRIMARY a ref t1_c2 t1_c2 5 test.t1.c2 5 Using index; FirstMatch(t1) +update t1 set c1=c1+10 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 >= 3; +affected rows: 20 +info: Rows matched: 20 Changed: 20 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 * +NULL 11 +NULL 12 +11->21 13 * +NULL 14 +NULL 15 +12->22 16 * +12->22 17 * +12->22 18 * +NULL 21 +21->31 22 * +21->31 23 * +NULL 24 +22->32 25 * +22->32 26 * +22->32 27 * +22->32 28 * +NULL 31 +31->41 32 * +31->41 33 * +NULL 34 +32->42 35 * +32->42 36 * +32->42 37 * +32->42 38 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update 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 +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 range t1_c2 t1_c2 5 NULL 21 Using index condition +1 PRIMARY a ref t1_c2 t1_c2 5 test.t1.c2 5 Using index; FirstMatch(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 range t1_c2 t1_c2 5 NULL 21 Using index condition +1 PRIMARY a ref t1_c2 t1_c2 5 test.t1.c2 5 Using index; FirstMatch(t1) +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: 20 +info: Rows matched: 20 Changed: 20 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 * +NULL 11 +NULL 12 +11->21 13 * +NULL 14 +NULL 15 +12->22 16 * +12->22 17 * +12->22 18 * +NULL 21 +21->31 22 * +21->31 23 * +NULL 24 +22->32 25 * +22->32 26 * +22->32 27 * +22->32 28 * +NULL 31 +31->41 32 * +31->41 33 * +NULL 34 +32->42 35 * +32->42 36 * +32->42 37 * +32->42 38 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update with a reference to view in subquery +# in settable value +# +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 +explain select * from t1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 32 +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 32 +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: 32 +info: Rows matched: 32 Changed: 32 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 * +11->13 11 * +11->13 12 * +11->13 13 * +12->14 14 * +12->14 15 * +12->14 16 * +12->14 17 * +12->14 18 * +21->23 21 * +21->23 22 * +21->23 23 * +22->24 24 * +22->24 25 * +22->24 26 * +22->24 27 * +22->24 28 * +31->33 31 * +31->33 32 * +31->33 33 * +32->34 34 * +32->34 35 * +32->34 36 * +32->34 37 * +32->34 38 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update 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 +explain select * from v1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref t1_c2 t1_c2 5 const 8 +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 8 Using where +2 DEPENDENT SUBQUERY a index NULL t1_c2 10 NULL 32 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: 7 +info: Rows matched: 7 Changed: 7 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 +NULL 11 +11->24 12 * +NULL 13 +NULL 14 +12->27 15 * +NULL 16 +NULL 17 +NULL 18 +21->35 21 * +NULL 22 +NULL 23 +22->38 24 * +NULL 25 +NULL 26 +NULL 27 +NULL 28 +31->45 31 * +NULL 32 +NULL 33 +32->48 34 * +NULL 35 +NULL 36 +NULL 37 +NULL 38 +truncate table t1; +insert into t1 select * from tmp; +# +# Update view with 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 +explain select * from v1 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 +1 PRIMARY t1 ref t1_c2 t1_c2 10 const,test.t1.c1 1 Using index; FirstMatch(t1) +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 DEPENDENT SUBQUERY t1 ref t1_c2 t1_c2 10 const,func 1 Using where; 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 +NULL 11 +NULL 12 +NULL 13 +NULL 14 +NULL 15 +NULL 16 +NULL 17 +NULL 18 +NULL 21 +NULL 22 +NULL 23 +NULL 24 +NULL 25 +NULL 26 +NULL 27 +NULL 28 +NULL 31 +NULL 32 +NULL 33 +NULL 34 +NULL 35 +NULL 36 +NULL 37 +NULL 38 +truncate table t1; +insert into t1 select * from tmp; +# +# Update view with EXISTS and 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 +explain select * from v1 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 +1 PRIMARY t1 ref t1_c2 t1_c2 5 const 8 Using index; FirstMatch(t1) +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 DEPENDENT SUBQUERY t1 ref t1_c2 t1_c2 5 const 8 Using where; 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 +NULL 11 +NULL 12 +NULL 13 +NULL 14 +NULL 15 +NULL 16 +NULL 17 +NULL 18 +NULL 21 +NULL 22 +NULL 23 +NULL 24 +NULL 25 +NULL 26 +NULL 27 +NULL 28 +NULL 31 +NULL 32 +NULL 33 +NULL 34 +NULL 35 +NULL 36 +NULL 37 +NULL 38 +truncate table t1; +insert into t1 select * from tmp; +# +# Update with IN predicand over the updated table in WHERE +# +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 +explain select * from t1 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 32 Using where +1 PRIMARY a ref t1_c2 t1_c2 10 test.t1.c2,test.t1.c1 1 Using index; FirstMatch(t1) +explain update t1 set c3=c3+110 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 32 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+110 where c2 in (select distinct a.c2 from t1 a where t1.c1=a.c1); +affected rows: 32 +info: Rows matched: 32 Changed: 32 Warnings: 0 +select c3 from t1; +c3 +111 +112 +113 +114 +115 +116 +117 +118 +121 +122 +123 +124 +125 +126 +127 +128 +131 +132 +133 +134 +135 +136 +137 +138 +141 +142 +143 +144 +145 +146 +147 +148 +truncate table t1; +insert into t1 select * from tmp; +# +# Update with a limit +# +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 +explain select * from t1 limit 2; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 32 +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 32 +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 32 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 +NULL 11 +NULL 12 +NULL 13 +NULL 14 +NULL 15 +NULL 16 +NULL 17 +NULL 18 +NULL 21 +NULL 22 +NULL 23 +NULL 24 +NULL 25 +NULL 26 +NULL 27 +NULL 28 +NULL 31 +NULL 32 +NULL 33 +NULL 34 +NULL 35 +NULL 36 +NULL 37 +NULL 38 +truncate table t1; +insert into t1 select * from tmp; +# +# Update with a limit and an 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 +explain select * from t1 order by c3 desc limit 2; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 32 Using filesort +explain update t1 +set c1=(select a.c3 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 2; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using filesort +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 32 Using where +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 +NULL 7 +NULL 8 +NULL 11 +NULL 12 +NULL 13 +NULL 14 +NULL 15 +NULL 16 +NULL 17 +NULL 18 +NULL 21 +NULL 22 +NULL 23 +NULL 24 +NULL 25 +NULL 26 +NULL 27 +NULL 28 +NULL 31 +NULL 32 +NULL 33 +NULL 34 +NULL 35 +NULL 36 +32->37 37 * +32->38 38 * +truncate table t1; +insert into t1 select * from tmp; +####################################### +# Test with a primary key # +####################################### +drop index t1_c2 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 +# +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 +explain select * from t1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 32 +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 32 +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: 32 +info: Rows matched: 32 Changed: 32 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 * +11->11 11 +11->12 12 * +11->13 13 * +12->14 14 * +12->15 15 * +12->16 16 * +12->17 17 * +12->18 18 * +21->21 21 +21->22 22 * +21->23 23 * +22->24 24 * +22->25 25 * +22->26 26 * +22->27 27 * +22->28 28 * +31->31 31 +31->32 32 * +31->33 33 * +32->34 34 * +32->35 35 * +32->36 36 * +32->37 37 * +32->38 38 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update 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 +explain select * from t1 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 32 Using where +1 PRIMARY a ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) +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 32 Using where +1 PRIMARY a ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1) +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 +NULL 11 +NULL 12 +NULL 13 +NULL 14 +NULL 15 +NULL 16 +NULL 17 +NULL 18 +NULL 21 +NULL 22 +NULL 23 +NULL 24 +NULL 25 +NULL 26 +NULL 27 +NULL 28 +NULL 31 +NULL 32 +NULL 33 +NULL 34 +NULL 35 +NULL 36 +NULL 37 +NULL 38 +truncate table t1; +insert into t1 select * from tmp; +# +# Update 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 +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 +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 32 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ALL NULL NULL NULL NULL 32 +update t1 set c1=c1+10 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 >= 3; +affected rows: 20 +info: Rows matched: 20 Changed: 20 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 * +NULL 11 +NULL 12 +11->21 13 * +NULL 14 +NULL 15 +12->22 16 * +12->22 17 * +12->22 18 * +NULL 21 +21->31 22 * +21->31 23 * +NULL 24 +22->32 25 * +22->32 26 * +22->32 27 * +22->32 28 * +NULL 31 +31->41 32 * +31->41 33 * +NULL 34 +32->42 35 * +32->42 36 * +32->42 37 * +32->42 38 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update 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 +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 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 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 +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: 20 +info: Rows matched: 20 Changed: 20 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 * +NULL 11 +NULL 12 +11->21 13 * +NULL 14 +NULL 15 +12->22 16 * +12->22 17 * +12->22 18 * +NULL 21 +21->31 22 * +21->31 23 * +NULL 24 +22->32 25 * +22->32 26 * +22->32 27 * +22->32 28 * +NULL 31 +31->41 32 * +31->41 33 * +NULL 34 +32->42 35 * +32->42 36 * +32->42 37 * +32->42 38 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update with a reference to view in subquery +# in settable value +# +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 +explain select * from t1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 32 +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 32 +2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 32 Using where +update t1 set c1=c1 +(select max(a.c2) from v1 a +where a.c1 = t1.c1); +affected rows: 32 +info: Rows matched: 32 Changed: 32 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 * +11->13 11 * +11->13 12 * +11->13 13 * +12->14 14 * +12->14 15 * +12->14 16 * +12->14 17 * +12->14 18 * +21->23 21 * +21->23 22 * +21->23 23 * +22->24 24 * +22->24 25 * +22->24 26 * +22->24 27 * +22->24 28 * +31->33 31 * +31->33 32 * +31->33 33 * +32->34 34 * +32->34 35 * +32->34 36 * +32->34 37 * +32->34 38 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update 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 +explain select * from v1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 32 Using where +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 PRIMARY 4 NULL 30 Using index condition; Using where +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 32 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: 7 +info: Rows matched: 7 Changed: 7 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 +NULL 11 +11->24 12 * +NULL 13 +NULL 14 +12->27 15 * +NULL 16 +NULL 17 +NULL 18 +21->35 21 * +NULL 22 +NULL 23 +22->38 24 * +NULL 25 +NULL 26 +NULL 27 +NULL 28 +31->45 31 * +NULL 32 +NULL 33 +32->48 34 * +NULL 35 +NULL 36 +NULL 37 +NULL 38 +truncate table t1; +insert into t1 select * from tmp; +# +# Update view with 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 +explain select * from v1 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 32 Using where +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) +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 32 Using where +2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 32 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 +NULL 11 +NULL 12 +NULL 13 +NULL 14 +NULL 15 +NULL 16 +NULL 17 +NULL 18 +NULL 21 +NULL 22 +NULL 23 +NULL 24 +NULL 25 +NULL 26 +NULL 27 +NULL 28 +NULL 31 +NULL 32 +NULL 33 +NULL 34 +NULL 35 +NULL 36 +NULL 37 +NULL 38 +truncate table t1; +insert into t1 select * from tmp; +# +# Update view with EXISTS and 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 +explain select * from v1 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 32 Using where +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) +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 32 Using where +3 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 32 Using where +2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 32 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 +NULL 11 +NULL 12 +NULL 13 +NULL 14 +NULL 15 +NULL 16 +NULL 17 +NULL 18 +NULL 21 +NULL 22 +NULL 23 +NULL 24 +NULL 25 +NULL 26 +NULL 27 +NULL 28 +NULL 31 +NULL 32 +NULL 33 +NULL 34 +NULL 35 +NULL 36 +NULL 37 +NULL 38 +truncate table t1; +insert into t1 select * from tmp; +# +# Update with IN predicand over the updated table in WHERE +# +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 +explain select * from t1 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 32 +1 PRIMARY a ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) +explain update t1 set c3=c3+110 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 32 +1 PRIMARY a ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1) +update t1 set c3=c3+110 where c2 in (select distinct a.c2 from t1 a where t1.c1=a.c1); +affected rows: 32 +info: Rows matched: 32 Changed: 32 Warnings: 0 +select c3 from t1; +c3 +111 +112 +113 +114 +115 +116 +117 +118 +121 +122 +123 +124 +125 +126 +127 +128 +131 +132 +133 +134 +135 +136 +137 +138 +141 +142 +143 +144 +145 +146 +147 +148 +truncate table t1; +insert into t1 select * from tmp; +# +# Update with a limit +# +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 +explain select * from t1 limit 2; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 32 +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 32 +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 +NULL 11 +NULL 12 +NULL 13 +NULL 14 +NULL 15 +NULL 16 +NULL 17 +NULL 18 +NULL 21 +NULL 22 +NULL 23 +NULL 24 +NULL 25 +NULL 26 +NULL 27 +NULL 28 +NULL 31 +NULL 32 +NULL 33 +NULL 34 +NULL 35 +NULL 36 +NULL 37 +NULL 38 +truncate table t1; +insert into t1 select * from tmp; +# +# Update with a limit and an 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 +explain select * from t1 order by c3 desc limit 2; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index NULL PRIMARY 4 NULL 2 +explain update t1 +set c1=(select a.c3 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 2; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 index NULL PRIMARY 4 NULL 2 Using buffer +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) +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 +NULL 7 +NULL 8 +NULL 11 +NULL 12 +NULL 13 +NULL 14 +NULL 15 +NULL 16 +NULL 17 +NULL 18 +NULL 21 +NULL 22 +NULL 23 +NULL 24 +NULL 25 +NULL 26 +NULL 27 +NULL 28 +NULL 31 +NULL 32 +NULL 33 +NULL 34 +NULL 35 +NULL 36 +32->37 37 * +32->38 38 * +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 +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 +# 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 +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 +# 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 +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 +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: 20 +info: Rows matched: 20 Changed: 20 Warnings: 0 +select c1,c2,c3 from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 0 +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 +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 +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 +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 +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 +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: 3 +info: Rows matched: 3 Changed: 3 Warnings: 0 +select c1,c2,c3 from t1; +c1 c2 c3 +10 1 1 +10 2 2 +10 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 +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 +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 +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 +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 1 +2 1 4 +2 2 2 +2 2 5 +2 3 3 +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 +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 +11 2 12 +11 3 13 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 1 +2 1 11 +2 1 14 +2 1 4 +2 2 2 +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 +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 +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 +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 +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 +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 +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 +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; +####################################### +# # +# Engine MyISAM # +# # +####################################### +set default_storage_engine=MyISAM; +create table t1 (old_c1 integer, +old_c2 integer, +c1 integer, +c2 integer, +c3 integer); +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); +insert into t1 select NULL, NULL, c1+10,c2,c3+10 from t1; +insert into t1 select NULL, NULL, 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 table tmp as select * from t1; +####################################### +# Test without any index # +####################################### +# +# Update with value from subquery on the same table +# +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 +explain select * from t1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 32 +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 32 +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 32 Using where +update t1 set c1=(select a.c3 from t1 a where a.c3 = t1.c3); +affected rows: 32 +info: Rows matched: 32 Changed: 32 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 * +11->11 11 +11->12 12 * +11->13 13 * +12->14 14 * +12->15 15 * +12->16 16 * +12->17 17 * +12->18 18 * +21->21 21 +21->22 22 * +21->23 23 * +22->24 24 * +22->25 25 * +22->26 26 * +22->27 27 * +22->28 28 * +31->31 31 +31->32 32 * +31->33 33 * +32->34 34 * +32->35 35 * +32->36 36 * +32->37 37 * +32->38 38 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update 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 +explain select * from t1 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 32 Using where +1 PRIMARY a ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) +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 32 Using where +1 PRIMARY a ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1) +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 +NULL 11 +NULL 12 +NULL 13 +NULL 14 +NULL 15 +NULL 16 +NULL 17 +NULL 18 +NULL 21 +NULL 22 +NULL 23 +NULL 24 +NULL 25 +NULL 26 +NULL 27 +NULL 28 +NULL 31 +NULL 32 +NULL 33 +NULL 34 +NULL 35 +NULL 36 +NULL 37 +NULL 38 +truncate table t1; +insert into t1 select * from tmp; +# +# Update 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 +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 +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 32 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ALL NULL NULL NULL NULL 32 +update t1 set c1=c1+10 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 >= 3; +affected rows: 20 +info: Rows matched: 20 Changed: 20 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 * +NULL 11 +NULL 12 +11->21 13 * +NULL 14 +NULL 15 +12->22 16 * +12->22 17 * +12->22 18 * +NULL 21 +21->31 22 * +21->31 23 * +NULL 24 +22->32 25 * +22->32 26 * +22->32 27 * +22->32 28 * +NULL 31 +31->41 32 * +31->41 33 * +NULL 34 +32->42 35 * +32->42 36 * +32->42 37 * +32->42 38 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update 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 +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 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 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 +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: 20 +info: Rows matched: 20 Changed: 20 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 * +NULL 11 +NULL 12 +11->21 13 * +NULL 14 +NULL 15 +12->22 16 * +12->22 17 * +12->22 18 * +NULL 21 +21->31 22 * +21->31 23 * +NULL 24 +22->32 25 * +22->32 26 * +22->32 27 * +22->32 28 * +NULL 31 +31->41 32 * +31->41 33 * +NULL 34 +32->42 35 * +32->42 36 * +32->42 37 * +32->42 38 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update with a reference to view in subquery +# in settable value +# +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 +explain select * from t1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 32 +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 32 +2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 32 Using where +update t1 set c1=c1 +(select max(a.c2) from v1 a +where a.c1 = t1.c1); +affected rows: 32 +info: Rows matched: 32 Changed: 32 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 * +11->13 11 * +11->13 12 * +11->13 13 * +12->14 14 * +12->14 15 * +12->14 16 * +12->14 17 * +12->14 18 * +21->23 21 * +21->23 22 * +21->23 23 * +22->24 24 * +22->24 25 * +22->24 26 * +22->24 27 * +22->24 28 * +31->33 31 * +31->33 32 * +31->33 33 * +32->34 34 * +32->34 35 * +32->34 36 * +32->34 37 * +32->34 38 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update 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 +explain select * from v1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 32 Using where +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 32 Using where +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 32 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: 7 +info: Rows matched: 7 Changed: 7 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 +NULL 11 +11->24 12 * +NULL 13 +NULL 14 +12->27 15 * +NULL 16 +NULL 17 +NULL 18 +21->35 21 * +NULL 22 +NULL 23 +22->38 24 * +NULL 25 +NULL 26 +NULL 27 +NULL 28 +31->45 31 * +NULL 32 +NULL 33 +32->48 34 * +NULL 35 +NULL 36 +NULL 37 +NULL 38 +truncate table t1; +insert into t1 select * from tmp; +# +# Update view with 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 +explain select * from v1 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 32 Using where +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) +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 32 Using where +2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 32 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 +NULL 11 +NULL 12 +NULL 13 +NULL 14 +NULL 15 +NULL 16 +NULL 17 +NULL 18 +NULL 21 +NULL 22 +NULL 23 +NULL 24 +NULL 25 +NULL 26 +NULL 27 +NULL 28 +NULL 31 +NULL 32 +NULL 33 +NULL 34 +NULL 35 +NULL 36 +NULL 37 +NULL 38 +truncate table t1; +insert into t1 select * from tmp; +# +# Update view with EXISTS and 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 +explain select * from v1 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 32 Using where +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) +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 32 Using where +3 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 32 Using where +2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 32 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 +NULL 11 +NULL 12 +NULL 13 +NULL 14 +NULL 15 +NULL 16 +NULL 17 +NULL 18 +NULL 21 +NULL 22 +NULL 23 +NULL 24 +NULL 25 +NULL 26 +NULL 27 +NULL 28 +NULL 31 +NULL 32 +NULL 33 +NULL 34 +NULL 35 +NULL 36 +NULL 37 +NULL 38 +truncate table t1; +insert into t1 select * from tmp; +# +# Update with IN predicand over the updated table in WHERE +# +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 +explain select * from t1 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 32 +1 PRIMARY a ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) +explain update t1 set c3=c3+110 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 32 +1 PRIMARY a ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1) +update t1 set c3=c3+110 where c2 in (select distinct a.c2 from t1 a where t1.c1=a.c1); +affected rows: 32 +info: Rows matched: 32 Changed: 32 Warnings: 0 +select c3 from t1; +c3 +111 +112 +113 +114 +115 +116 +117 +118 +121 +122 +123 +124 +125 +126 +127 +128 +131 +132 +133 +134 +135 +136 +137 +138 +141 +142 +143 +144 +145 +146 +147 +148 +truncate table t1; +insert into t1 select * from tmp; +# +# Update with a limit +# +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 +explain select * from t1 limit 2; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 32 +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 32 +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 32 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 +NULL 11 +NULL 12 +NULL 13 +NULL 14 +NULL 15 +NULL 16 +NULL 17 +NULL 18 +NULL 21 +NULL 22 +NULL 23 +NULL 24 +NULL 25 +NULL 26 +NULL 27 +NULL 28 +NULL 31 +NULL 32 +NULL 33 +NULL 34 +NULL 35 +NULL 36 +NULL 37 +NULL 38 +truncate table t1; +insert into t1 select * from tmp; +# +# Update with a limit and an 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 +explain select * from t1 order by c3 desc limit 2; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 32 Using filesort +explain update t1 +set c1=(select a.c3 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 2; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using filesort +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 32 Using where +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 +NULL 7 +NULL 8 +NULL 11 +NULL 12 +NULL 13 +NULL 14 +NULL 15 +NULL 16 +NULL 17 +NULL 18 +NULL 21 +NULL 22 +NULL 23 +NULL 24 +NULL 25 +NULL 26 +NULL 27 +NULL 28 +NULL 31 +NULL 32 +NULL 33 +NULL 34 +NULL 35 +NULL 36 +32->37 37 * +32->38 38 * +truncate table t1; +insert into t1 select * from tmp; +####################################### +# Test with an index # +####################################### +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 +# +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 +explain select * from t1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 32 +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 32 +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 32 Using where +update t1 set c1=(select a.c3 from t1 a where a.c3 = t1.c3); +affected rows: 32 +info: Rows matched: 32 Changed: 32 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 * +11->11 11 +11->12 12 * +11->13 13 * +12->14 14 * +12->15 15 * +12->16 16 * +12->17 17 * +12->18 18 * +21->21 21 +21->22 22 * +21->23 23 * +22->24 24 * +22->25 25 * +22->26 26 * +22->27 27 * +22->28 28 * +31->31 31 +31->32 32 * +31->33 33 * +32->34 34 * +32->35 35 * +32->36 36 * +32->37 37 * +32->38 38 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update 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 +explain select * from t1 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 32 Using where +1 PRIMARY a index NULL t1_c2 10 NULL 32 Using where; Using index; FirstMatch(t1); Using join buffer (flat, BNL join) +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 32 Using where +1 PRIMARY a index NULL t1_c2 10 NULL 32 Using where; Using index; FirstMatch(t1) +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 +NULL 11 +NULL 12 +NULL 13 +NULL 14 +NULL 15 +NULL 16 +NULL 17 +NULL 18 +NULL 21 +NULL 22 +NULL 23 +NULL 24 +NULL 25 +NULL 26 +NULL 27 +NULL 28 +NULL 31 +NULL 32 +NULL 33 +NULL 34 +NULL 35 +NULL 36 +NULL 37 +NULL 38 +truncate table t1; +insert into t1 select * from tmp; +# +# Update 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 +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 a ref t1_c2 t1_c2 5 test.t1.c2 5 Using index; FirstMatch(t1) +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 32 Using where +1 PRIMARY a ref t1_c2 t1_c2 5 test.t1.c2 5 Using index; FirstMatch(t1) +update t1 set c1=c1+10 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 >= 3; +affected rows: 20 +info: Rows matched: 20 Changed: 20 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 * +NULL 11 +NULL 12 +11->21 13 * +NULL 14 +NULL 15 +12->22 16 * +12->22 17 * +12->22 18 * +NULL 21 +21->31 22 * +21->31 23 * +NULL 24 +22->32 25 * +22->32 26 * +22->32 27 * +22->32 28 * +NULL 31 +31->41 32 * +31->41 33 * +NULL 34 +32->42 35 * +32->42 36 * +32->42 37 * +32->42 38 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update 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 +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 a ref t1_c2 t1_c2 5 test.t1.c2 5 Using index; FirstMatch(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 32 Using where; Using filesort +1 PRIMARY a ref t1_c2 t1_c2 5 test.t1.c2 5 Using index; FirstMatch(t1) +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: 20 +info: Rows matched: 20 Changed: 20 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 * +NULL 11 +NULL 12 +11->21 13 * +NULL 14 +NULL 15 +12->22 16 * +12->22 17 * +12->22 18 * +NULL 21 +21->31 22 * +21->31 23 * +NULL 24 +22->32 25 * +22->32 26 * +22->32 27 * +22->32 28 * +NULL 31 +31->41 32 * +31->41 33 * +NULL 34 +32->42 35 * +32->42 36 * +32->42 37 * +32->42 38 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update with a reference to view in subquery +# in settable value +# +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 +explain select * from t1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 32 +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 32 +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: 32 +info: Rows matched: 32 Changed: 32 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 * +11->13 11 * +11->13 12 * +11->13 13 * +12->14 14 * +12->14 15 * +12->14 16 * +12->14 17 * +12->14 18 * +21->23 21 * +21->23 22 * +21->23 23 * +22->24 24 * +22->24 25 * +22->24 26 * +22->24 27 * +22->24 28 * +31->33 31 * +31->33 32 * +31->33 33 * +32->34 34 * +32->34 35 * +32->34 36 * +32->34 37 * +32->34 38 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update 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 +explain select * from v1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref t1_c2 t1_c2 5 const 8 +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 8 Using where +2 DEPENDENT SUBQUERY a index NULL t1_c2 10 NULL 32 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: 7 +info: Rows matched: 7 Changed: 7 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 +NULL 11 +11->24 12 * +NULL 13 +NULL 14 +12->27 15 * +NULL 16 +NULL 17 +NULL 18 +21->35 21 * +NULL 22 +NULL 23 +22->38 24 * +NULL 25 +NULL 26 +NULL 27 +NULL 28 +31->45 31 * +NULL 32 +NULL 33 +32->48 34 * +NULL 35 +NULL 36 +NULL 37 +NULL 38 +truncate table t1; +insert into t1 select * from tmp; +# +# Update view with 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 +explain select * from v1 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 +1 PRIMARY t1 ref t1_c2 t1_c2 10 const,test.t1.c1 1 Using index; FirstMatch(t1) +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 DEPENDENT SUBQUERY t1 ref t1_c2 t1_c2 10 const,func 1 Using where; 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 +NULL 11 +NULL 12 +NULL 13 +NULL 14 +NULL 15 +NULL 16 +NULL 17 +NULL 18 +NULL 21 +NULL 22 +NULL 23 +NULL 24 +NULL 25 +NULL 26 +NULL 27 +NULL 28 +NULL 31 +NULL 32 +NULL 33 +NULL 34 +NULL 35 +NULL 36 +NULL 37 +NULL 38 +truncate table t1; +insert into t1 select * from tmp; +# +# Update view with EXISTS and 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 +explain select * from v1 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 +1 PRIMARY t1 ref t1_c2 t1_c2 5 const 8 Using index; FirstMatch(t1) +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 DEPENDENT SUBQUERY t1 ref t1_c2 t1_c2 5 const 8 Using where; 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 +NULL 11 +NULL 12 +NULL 13 +NULL 14 +NULL 15 +NULL 16 +NULL 17 +NULL 18 +NULL 21 +NULL 22 +NULL 23 +NULL 24 +NULL 25 +NULL 26 +NULL 27 +NULL 28 +NULL 31 +NULL 32 +NULL 33 +NULL 34 +NULL 35 +NULL 36 +NULL 37 +NULL 38 +truncate table t1; +insert into t1 select * from tmp; +# +# Update with IN predicand over the updated table in WHERE +# +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 +explain select * from t1 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 32 Using where +1 PRIMARY a ref t1_c2 t1_c2 10 test.t1.c2,test.t1.c1 1 Using index; FirstMatch(t1) +explain update t1 set c3=c3+110 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 32 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+110 where c2 in (select distinct a.c2 from t1 a where t1.c1=a.c1); +affected rows: 32 +info: Rows matched: 32 Changed: 32 Warnings: 0 +select c3 from t1; +c3 +111 +112 +113 +114 +115 +116 +117 +118 +121 +122 +123 +124 +125 +126 +127 +128 +131 +132 +133 +134 +135 +136 +137 +138 +141 +142 +143 +144 +145 +146 +147 +148 +truncate table t1; +insert into t1 select * from tmp; +# +# Update with a limit +# +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 +explain select * from t1 limit 2; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 32 +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 32 +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 32 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 +NULL 11 +NULL 12 +NULL 13 +NULL 14 +NULL 15 +NULL 16 +NULL 17 +NULL 18 +NULL 21 +NULL 22 +NULL 23 +NULL 24 +NULL 25 +NULL 26 +NULL 27 +NULL 28 +NULL 31 +NULL 32 +NULL 33 +NULL 34 +NULL 35 +NULL 36 +NULL 37 +NULL 38 +truncate table t1; +insert into t1 select * from tmp; +# +# Update with a limit and an 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 +explain select * from t1 order by c3 desc limit 2; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 32 Using filesort +explain update t1 +set c1=(select a.c3 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 2; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using filesort +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 32 Using where +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 +NULL 7 +NULL 8 +NULL 11 +NULL 12 +NULL 13 +NULL 14 +NULL 15 +NULL 16 +NULL 17 +NULL 18 +NULL 21 +NULL 22 +NULL 23 +NULL 24 +NULL 25 +NULL 26 +NULL 27 +NULL 28 +NULL 31 +NULL 32 +NULL 33 +NULL 34 +NULL 35 +NULL 36 +32->37 37 * +32->38 38 * +truncate table t1; +insert into t1 select * from tmp; +####################################### +# Test with a primary key # +####################################### +drop index t1_c2 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 +# +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 +explain select * from t1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 32 +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 32 +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: 32 +info: Rows matched: 32 Changed: 32 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 * +11->11 11 +11->12 12 * +11->13 13 * +12->14 14 * +12->15 15 * +12->16 16 * +12->17 17 * +12->18 18 * +21->21 21 +21->22 22 * +21->23 23 * +22->24 24 * +22->25 25 * +22->26 26 * +22->27 27 * +22->28 28 * +31->31 31 +31->32 32 * +31->33 33 * +32->34 34 * +32->35 35 * +32->36 36 * +32->37 37 * +32->38 38 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update 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 +explain select * from t1 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 32 Using where +1 PRIMARY a ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) +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 32 Using where +1 PRIMARY a ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1) +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 +NULL 11 +NULL 12 +NULL 13 +NULL 14 +NULL 15 +NULL 16 +NULL 17 +NULL 18 +NULL 21 +NULL 22 +NULL 23 +NULL 24 +NULL 25 +NULL 26 +NULL 27 +NULL 28 +NULL 31 +NULL 32 +NULL 33 +NULL 34 +NULL 35 +NULL 36 +NULL 37 +NULL 38 +truncate table t1; +insert into t1 select * from tmp; +# +# Update 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 +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 +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 32 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ALL NULL NULL NULL NULL 32 +update t1 set c1=c1+10 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 >= 3; +affected rows: 20 +info: Rows matched: 20 Changed: 20 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 * +NULL 11 +NULL 12 +11->21 13 * +NULL 14 +NULL 15 +12->22 16 * +12->22 17 * +12->22 18 * +NULL 21 +21->31 22 * +21->31 23 * +NULL 24 +22->32 25 * +22->32 26 * +22->32 27 * +22->32 28 * +NULL 31 +31->41 32 * +31->41 33 * +NULL 34 +32->42 35 * +32->42 36 * +32->42 37 * +32->42 38 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update 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 +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 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 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 +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: 20 +info: Rows matched: 20 Changed: 20 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 * +NULL 11 +NULL 12 +11->21 13 * +NULL 14 +NULL 15 +12->22 16 * +12->22 17 * +12->22 18 * +NULL 21 +21->31 22 * +21->31 23 * +NULL 24 +22->32 25 * +22->32 26 * +22->32 27 * +22->32 28 * +NULL 31 +31->41 32 * +31->41 33 * +NULL 34 +32->42 35 * +32->42 36 * +32->42 37 * +32->42 38 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update with a reference to view in subquery +# in settable value +# +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 +explain select * from t1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 32 +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 32 +2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 32 Using where +update t1 set c1=c1 +(select max(a.c2) from v1 a +where a.c1 = t1.c1); +affected rows: 32 +info: Rows matched: 32 Changed: 32 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 * +11->13 11 * +11->13 12 * +11->13 13 * +12->14 14 * +12->14 15 * +12->14 16 * +12->14 17 * +12->14 18 * +21->23 21 * +21->23 22 * +21->23 23 * +22->24 24 * +22->24 25 * +22->24 26 * +22->24 27 * +22->24 28 * +31->33 31 * +31->33 32 * +31->33 33 * +32->34 34 * +32->34 35 * +32->34 36 * +32->34 37 * +32->34 38 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update 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 +explain select * from v1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 32 Using where +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 NULL NULL NULL 32 Using where +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 32 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: 7 +info: Rows matched: 7 Changed: 7 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 +NULL 11 +11->24 12 * +NULL 13 +NULL 14 +12->27 15 * +NULL 16 +NULL 17 +NULL 18 +21->35 21 * +NULL 22 +NULL 23 +22->38 24 * +NULL 25 +NULL 26 +NULL 27 +NULL 28 +31->45 31 * +NULL 32 +NULL 33 +32->48 34 * +NULL 35 +NULL 36 +NULL 37 +NULL 38 +truncate table t1; +insert into t1 select * from tmp; +# +# Update view with 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 +explain select * from v1 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 32 Using where +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) +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 32 Using where +2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 32 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 +NULL 11 +NULL 12 +NULL 13 +NULL 14 +NULL 15 +NULL 16 +NULL 17 +NULL 18 +NULL 21 +NULL 22 +NULL 23 +NULL 24 +NULL 25 +NULL 26 +NULL 27 +NULL 28 +NULL 31 +NULL 32 +NULL 33 +NULL 34 +NULL 35 +NULL 36 +NULL 37 +NULL 38 +truncate table t1; +insert into t1 select * from tmp; +# +# Update view with EXISTS and 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 +explain select * from v1 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 32 Using where +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) +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 32 Using where +3 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 32 Using where +2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 32 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 +NULL 11 +NULL 12 +NULL 13 +NULL 14 +NULL 15 +NULL 16 +NULL 17 +NULL 18 +NULL 21 +NULL 22 +NULL 23 +NULL 24 +NULL 25 +NULL 26 +NULL 27 +NULL 28 +NULL 31 +NULL 32 +NULL 33 +NULL 34 +NULL 35 +NULL 36 +NULL 37 +NULL 38 +truncate table t1; +insert into t1 select * from tmp; +# +# Update with IN predicand over the updated table in WHERE +# +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 +explain select * from t1 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 32 +1 PRIMARY a ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) +explain update t1 set c3=c3+110 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 32 +1 PRIMARY a ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1) +update t1 set c3=c3+110 where c2 in (select distinct a.c2 from t1 a where t1.c1=a.c1); +affected rows: 32 +info: Rows matched: 32 Changed: 32 Warnings: 0 +select c3 from t1; +c3 +111 +112 +113 +114 +115 +116 +117 +118 +121 +122 +123 +124 +125 +126 +127 +128 +131 +132 +133 +134 +135 +136 +137 +138 +141 +142 +143 +144 +145 +146 +147 +148 +truncate table t1; +insert into t1 select * from tmp; +# +# Update with a limit +# +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 +explain select * from t1 limit 2; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 32 +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 32 +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 +NULL 11 +NULL 12 +NULL 13 +NULL 14 +NULL 15 +NULL 16 +NULL 17 +NULL 18 +NULL 21 +NULL 22 +NULL 23 +NULL 24 +NULL 25 +NULL 26 +NULL 27 +NULL 28 +NULL 31 +NULL 32 +NULL 33 +NULL 34 +NULL 35 +NULL 36 +NULL 37 +NULL 38 +truncate table t1; +insert into t1 select * from tmp; +# +# Update with a limit and an 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 +explain select * from t1 order by c3 desc limit 2; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index NULL PRIMARY 4 NULL 2 +explain update t1 +set c1=(select a.c3 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 2; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 index NULL PRIMARY 4 NULL 2 Using buffer +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) +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 +NULL 7 +NULL 8 +NULL 11 +NULL 12 +NULL 13 +NULL 14 +NULL 15 +NULL 16 +NULL 17 +NULL 18 +NULL 21 +NULL 22 +NULL 23 +NULL 24 +NULL 25 +NULL 26 +NULL 27 +NULL 28 +NULL 31 +NULL 32 +NULL 33 +NULL 34 +NULL 35 +NULL 36 +32->37 37 * +32->38 38 * +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 +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 +# 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 +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 +# 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 +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 +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: 20 +info: Rows matched: 20 Changed: 20 Warnings: 0 +select c1,c2,c3 from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 0 +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 +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 +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 +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 +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 +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: 3 +info: Rows matched: 3 Changed: 3 Warnings: 0 +select c1,c2,c3 from t1; +c1 c2 c3 +10 1 1 +10 2 2 +10 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 +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 +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 +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 +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 1 +2 1 4 +2 2 2 +2 2 5 +2 3 3 +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 +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 +11 2 12 +11 3 13 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 1 +2 1 11 +2 1 14 +2 1 4 +2 2 2 +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 +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 +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 +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 +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 +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 +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 +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; +####################################### +# # +# Engine MEMORY # +# # +####################################### +set default_storage_engine=MEMORY; +create table t1 (old_c1 integer, +old_c2 integer, +c1 integer, +c2 integer, +c3 integer); +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); +insert into t1 select NULL, NULL, c1+10,c2,c3+10 from t1; +insert into t1 select NULL, NULL, 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 table tmp as select * from t1; +####################################### +# Test without any index # +####################################### +# +# Update with value from subquery on the same table +# +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 +explain select * from t1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 32 +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 32 +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 32 Using where +update t1 set c1=(select a.c3 from t1 a where a.c3 = t1.c3); +affected rows: 32 +info: Rows matched: 32 Changed: 32 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 * +11->11 11 +11->12 12 * +11->13 13 * +12->14 14 * +12->15 15 * +12->16 16 * +12->17 17 * +12->18 18 * +21->21 21 +21->22 22 * +21->23 23 * +22->24 24 * +22->25 25 * +22->26 26 * +22->27 27 * +22->28 28 * +31->31 31 +31->32 32 * +31->33 33 * +32->34 34 * +32->35 35 * +32->36 36 * +32->37 37 * +32->38 38 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update 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 +explain select * from t1 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 32 Using where +1 PRIMARY a ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) +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 32 Using where +1 PRIMARY a ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1) +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 +NULL 11 +NULL 12 +NULL 13 +NULL 14 +NULL 15 +NULL 16 +NULL 17 +NULL 18 +NULL 21 +NULL 22 +NULL 23 +NULL 24 +NULL 25 +NULL 26 +NULL 27 +NULL 28 +NULL 31 +NULL 32 +NULL 33 +NULL 34 +NULL 35 +NULL 36 +NULL 37 +NULL 38 +truncate table t1; +insert into t1 select * from tmp; +# +# Update 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 +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 +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 32 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ALL NULL NULL NULL NULL 32 +update t1 set c1=c1+10 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 >= 3; +affected rows: 20 +info: Rows matched: 20 Changed: 20 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 * +NULL 11 +NULL 12 +11->21 13 * +NULL 14 +NULL 15 +12->22 16 * +12->22 17 * +12->22 18 * +NULL 21 +21->31 22 * +21->31 23 * +NULL 24 +22->32 25 * +22->32 26 * +22->32 27 * +22->32 28 * +NULL 31 +31->41 32 * +31->41 33 * +NULL 34 +32->42 35 * +32->42 36 * +32->42 37 * +32->42 38 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update 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 +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 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 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 +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: 20 +info: Rows matched: 20 Changed: 20 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 * +NULL 11 +NULL 12 +11->21 13 * +NULL 14 +NULL 15 +12->22 16 * +12->22 17 * +12->22 18 * +NULL 21 +21->31 22 * +21->31 23 * +NULL 24 +22->32 25 * +22->32 26 * +22->32 27 * +22->32 28 * +NULL 31 +31->41 32 * +31->41 33 * +NULL 34 +32->42 35 * +32->42 36 * +32->42 37 * +32->42 38 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update with a reference to view in subquery +# in settable value +# +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 +explain select * from t1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 32 +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 32 +2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 32 Using where +update t1 set c1=c1 +(select max(a.c2) from v1 a +where a.c1 = t1.c1); +affected rows: 32 +info: Rows matched: 32 Changed: 32 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 * +11->13 11 * +11->13 12 * +11->13 13 * +12->14 14 * +12->14 15 * +12->14 16 * +12->14 17 * +12->14 18 * +21->23 21 * +21->23 22 * +21->23 23 * +22->24 24 * +22->24 25 * +22->24 26 * +22->24 27 * +22->24 28 * +31->33 31 * +31->33 32 * +31->33 33 * +32->34 34 * +32->34 35 * +32->34 36 * +32->34 37 * +32->34 38 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update 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 +explain select * from v1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 32 Using where +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 32 Using where +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 32 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: 7 +info: Rows matched: 7 Changed: 7 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 +NULL 11 +11->24 12 * +NULL 13 +NULL 14 +12->27 15 * +NULL 16 +NULL 17 +NULL 18 +21->35 21 * +NULL 22 +NULL 23 +22->38 24 * +NULL 25 +NULL 26 +NULL 27 +NULL 28 +31->45 31 * +NULL 32 +NULL 33 +32->48 34 * +NULL 35 +NULL 36 +NULL 37 +NULL 38 +truncate table t1; +insert into t1 select * from tmp; +# +# Update view with 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 +explain select * from v1 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 32 Using where +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) +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 32 Using where +2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 32 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 +NULL 11 +NULL 12 +NULL 13 +NULL 14 +NULL 15 +NULL 16 +NULL 17 +NULL 18 +NULL 21 +NULL 22 +NULL 23 +NULL 24 +NULL 25 +NULL 26 +NULL 27 +NULL 28 +NULL 31 +NULL 32 +NULL 33 +NULL 34 +NULL 35 +NULL 36 +NULL 37 +NULL 38 +truncate table t1; +insert into t1 select * from tmp; +# +# Update view with EXISTS and 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 +explain select * from v1 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 32 Using where +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) +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 32 Using where +3 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 32 Using where +2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 32 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 +NULL 11 +NULL 12 +NULL 13 +NULL 14 +NULL 15 +NULL 16 +NULL 17 +NULL 18 +NULL 21 +NULL 22 +NULL 23 +NULL 24 +NULL 25 +NULL 26 +NULL 27 +NULL 28 +NULL 31 +NULL 32 +NULL 33 +NULL 34 +NULL 35 +NULL 36 +NULL 37 +NULL 38 +truncate table t1; +insert into t1 select * from tmp; +# +# Update with IN predicand over the updated table in WHERE +# +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 +explain select * from t1 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 32 +1 PRIMARY a ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) +explain update t1 set c3=c3+110 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 32 +1 PRIMARY a ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1) +update t1 set c3=c3+110 where c2 in (select distinct a.c2 from t1 a where t1.c1=a.c1); +affected rows: 32 +info: Rows matched: 32 Changed: 32 Warnings: 0 +select c3 from t1; +c3 +111 +112 +113 +114 +115 +116 +117 +118 +121 +122 +123 +124 +125 +126 +127 +128 +131 +132 +133 +134 +135 +136 +137 +138 +141 +142 +143 +144 +145 +146 +147 +148 +truncate table t1; +insert into t1 select * from tmp; +# +# Update with a limit +# +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 +explain select * from t1 limit 2; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 32 +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 32 +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 32 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 +NULL 11 +NULL 12 +NULL 13 +NULL 14 +NULL 15 +NULL 16 +NULL 17 +NULL 18 +NULL 21 +NULL 22 +NULL 23 +NULL 24 +NULL 25 +NULL 26 +NULL 27 +NULL 28 +NULL 31 +NULL 32 +NULL 33 +NULL 34 +NULL 35 +NULL 36 +NULL 37 +NULL 38 +truncate table t1; +insert into t1 select * from tmp; +# +# Update with a limit and an 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 +explain select * from t1 order by c3 desc limit 2; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 32 Using filesort +explain update t1 +set c1=(select a.c3 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 2; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using filesort +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 32 Using where +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 +NULL 7 +NULL 8 +NULL 11 +NULL 12 +NULL 13 +NULL 14 +NULL 15 +NULL 16 +NULL 17 +NULL 18 +NULL 21 +NULL 22 +NULL 23 +NULL 24 +NULL 25 +NULL 26 +NULL 27 +NULL 28 +NULL 31 +NULL 32 +NULL 33 +NULL 34 +NULL 35 +NULL 36 +32->37 37 * +32->38 38 * +truncate table t1; +insert into t1 select * from tmp; +####################################### +# Test with an index # +####################################### +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 +# +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Operation failed +explain select * from t1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 32 +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 32 +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 32 Using where +update t1 set c1=(select a.c3 from t1 a where a.c3 = t1.c3); +affected rows: 32 +info: Rows matched: 32 Changed: 32 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 * +11->11 11 +11->12 12 * +11->13 13 * +12->14 14 * +12->15 15 * +12->16 16 * +12->17 17 * +12->18 18 * +21->21 21 +21->22 22 * +21->23 23 * +22->24 24 * +22->25 25 * +22->26 26 * +22->27 27 * +22->28 28 * +31->31 31 +31->32 32 * +31->33 33 * +32->34 34 * +32->35 35 * +32->36 36 * +32->37 37 * +32->38 38 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update 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 +explain select * from t1 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 32 Using where +1 PRIMARY a ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) +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 32 Using where +1 PRIMARY a ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1) +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 +NULL 11 +NULL 12 +NULL 13 +NULL 14 +NULL 15 +NULL 16 +NULL 17 +NULL 18 +NULL 21 +NULL 22 +NULL 23 +NULL 24 +NULL 25 +NULL 26 +NULL 27 +NULL 28 +NULL 31 +NULL 32 +NULL 33 +NULL 34 +NULL 35 +NULL 36 +NULL 37 +NULL 38 +truncate table t1; +insert into t1 select * from tmp; +# +# Update 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 +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 +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 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 +update t1 set c1=c1+10 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 >= 3; +affected rows: 20 +info: Rows matched: 20 Changed: 20 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 * +NULL 11 +NULL 12 +11->21 13 * +NULL 14 +NULL 15 +12->22 16 * +12->22 17 * +12->22 18 * +NULL 21 +21->31 22 * +21->31 23 * +NULL 24 +22->32 25 * +22->32 26 * +22->32 27 * +22->32 28 * +NULL 31 +31->41 32 * +31->41 33 * +NULL 34 +32->42 35 * +32->42 36 * +32->42 37 * +32->42 38 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update with order by +# +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Operation failed +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 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 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 +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: 20 +info: Rows matched: 20 Changed: 20 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 * +NULL 11 +NULL 12 +11->21 13 * +NULL 14 +NULL 15 +12->22 16 * +12->22 17 * +12->22 18 * +NULL 21 +21->31 22 * +21->31 23 * +NULL 24 +22->32 25 * +22->32 26 * +22->32 27 * +22->32 28 * +NULL 31 +31->41 32 * +31->41 33 * +NULL 34 +32->42 35 * +32->42 36 * +32->42 37 * +32->42 38 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update with a reference to view in subquery +# in settable value +# +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Operation failed +explain select * from t1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 32 +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 32 +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: 32 +info: Rows matched: 32 Changed: 32 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 * +11->13 11 * +11->13 12 * +11->13 13 * +12->14 14 * +12->14 15 * +12->14 16 * +12->14 17 * +12->14 18 * +21->23 21 * +21->23 22 * +21->23 23 * +22->24 24 * +22->24 25 * +22->24 26 * +22->24 27 * +22->24 28 * +31->33 31 * +31->33 32 * +31->33 33 * +32->34 34 * +32->34 35 * +32->34 36 * +32->34 37 * +32->34 38 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update view +# +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Operation failed +explain select * from v1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL t1_c2 NULL NULL NULL 32 Using where +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 32 Using where +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 32 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: 7 +info: Rows matched: 7 Changed: 7 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 +NULL 11 +11->24 12 * +NULL 13 +NULL 14 +12->27 15 * +NULL 16 +NULL 17 +NULL 18 +21->35 21 * +NULL 22 +NULL 23 +22->38 24 * +NULL 25 +NULL 26 +NULL 27 +NULL 28 +31->45 31 * +NULL 32 +NULL 33 +32->48 34 * +NULL 35 +NULL 36 +NULL 37 +NULL 38 +truncate table t1; +insert into t1 select * from tmp; +# +# Update view with 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 +explain select * from v1 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 32 Using where +1 PRIMARY t1 ref t1_c2 t1_c2 10 const,test.t1.c1 2 FirstMatch(t1) +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 32 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 +NULL 11 +NULL 12 +NULL 13 +NULL 14 +NULL 15 +NULL 16 +NULL 17 +NULL 18 +NULL 21 +NULL 22 +NULL 23 +NULL 24 +NULL 25 +NULL 26 +NULL 27 +NULL 28 +NULL 31 +NULL 32 +NULL 33 +NULL 34 +NULL 35 +NULL 36 +NULL 37 +NULL 38 +truncate table t1; +insert into t1 select * from tmp; +# +# Update view with EXISTS and 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 +explain select * from v1 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 32 Using where +1 PRIMARY t1 ALL t1_c2 NULL NULL NULL 32 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) +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 32 Using where +3 DEPENDENT SUBQUERY t1 ALL t1_c2 NULL NULL NULL 32 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 +NULL 11 +NULL 12 +NULL 13 +NULL 14 +NULL 15 +NULL 16 +NULL 17 +NULL 18 +NULL 21 +NULL 22 +NULL 23 +NULL 24 +NULL 25 +NULL 26 +NULL 27 +NULL 28 +NULL 31 +NULL 32 +NULL 33 +NULL 34 +NULL 35 +NULL 36 +NULL 37 +NULL 38 +truncate table t1; +insert into t1 select * from tmp; +# +# Update with IN predicand over the updated table in WHERE +# +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Operation failed +explain select * from t1 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 32 Using where +1 PRIMARY a ref t1_c2 t1_c2 10 test.t1.c2,test.t1.c1 2 FirstMatch(t1) +explain update t1 set c3=c3+110 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 32 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+110 where c2 in (select distinct a.c2 from t1 a where t1.c1=a.c1); +affected rows: 32 +info: Rows matched: 32 Changed: 32 Warnings: 0 +select c3 from t1; +c3 +111 +112 +113 +114 +115 +116 +117 +118 +121 +122 +123 +124 +125 +126 +127 +128 +131 +132 +133 +134 +135 +136 +137 +138 +141 +142 +143 +144 +145 +146 +147 +148 +truncate table t1; +insert into t1 select * from tmp; +# +# Update with a limit +# +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Operation failed +explain select * from t1 limit 2; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 32 +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 32 +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 32 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 +NULL 11 +NULL 12 +NULL 13 +NULL 14 +NULL 15 +NULL 16 +NULL 17 +NULL 18 +NULL 21 +NULL 22 +NULL 23 +NULL 24 +NULL 25 +NULL 26 +NULL 27 +NULL 28 +NULL 31 +NULL 32 +NULL 33 +NULL 34 +NULL 35 +NULL 36 +NULL 37 +NULL 38 +truncate table t1; +insert into t1 select * from tmp; +# +# Update with a limit and an order by +# +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Operation failed +explain select * from t1 order by c3 desc limit 2; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 32 Using filesort +explain update t1 +set c1=(select a.c3 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 2; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using filesort +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 32 Using where +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 +NULL 7 +NULL 8 +NULL 11 +NULL 12 +NULL 13 +NULL 14 +NULL 15 +NULL 16 +NULL 17 +NULL 18 +NULL 21 +NULL 22 +NULL 23 +NULL 24 +NULL 25 +NULL 26 +NULL 27 +NULL 28 +NULL 31 +NULL 32 +NULL 33 +NULL 34 +NULL 35 +NULL 36 +32->37 37 * +32->38 38 * +truncate table t1; +insert into t1 select * from tmp; +####################################### +# Test with a primary key # +####################################### +drop index t1_c2 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 note The storage engine for the table doesn't support analyze +# +# Update with value from subquery on the same table +# +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 +explain select * from t1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 32 +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 32 +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: 32 +info: Rows matched: 32 Changed: 32 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 * +11->11 11 +11->12 12 * +11->13 13 * +12->14 14 * +12->15 15 * +12->16 16 * +12->17 17 * +12->18 18 * +21->21 21 +21->22 22 * +21->23 23 * +22->24 24 * +22->25 25 * +22->26 26 * +22->27 27 * +22->28 28 * +31->31 31 +31->32 32 * +31->33 33 * +32->34 34 * +32->35 35 * +32->36 36 * +32->37 37 * +32->38 38 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update 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 +explain select * from t1 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 32 Using where +1 PRIMARY a ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) +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 32 Using where +1 PRIMARY a ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1) +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 +NULL 11 +NULL 12 +NULL 13 +NULL 14 +NULL 15 +NULL 16 +NULL 17 +NULL 18 +NULL 21 +NULL 22 +NULL 23 +NULL 24 +NULL 25 +NULL 26 +NULL 27 +NULL 28 +NULL 31 +NULL 32 +NULL 33 +NULL 34 +NULL 35 +NULL 36 +NULL 37 +NULL 38 +truncate table t1; +insert into t1 select * from tmp; +# +# Update 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 +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 +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 32 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED a ALL NULL NULL NULL NULL 32 +update t1 set c1=c1+10 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 >= 3; +affected rows: 20 +info: Rows matched: 20 Changed: 20 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 * +NULL 11 +NULL 12 +11->21 13 * +NULL 14 +NULL 15 +12->22 16 * +12->22 17 * +12->22 18 * +NULL 21 +21->31 22 * +21->31 23 * +NULL 24 +22->32 25 * +22->32 26 * +22->32 27 * +22->32 28 * +NULL 31 +31->41 32 * +31->41 33 * +NULL 34 +32->42 35 * +32->42 36 * +32->42 37 * +32->42 38 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update 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 +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 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 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 +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: 20 +info: Rows matched: 20 Changed: 20 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 * +NULL 11 +NULL 12 +11->21 13 * +NULL 14 +NULL 15 +12->22 16 * +12->22 17 * +12->22 18 * +NULL 21 +21->31 22 * +21->31 23 * +NULL 24 +22->32 25 * +22->32 26 * +22->32 27 * +22->32 28 * +NULL 31 +31->41 32 * +31->41 33 * +NULL 34 +32->42 35 * +32->42 36 * +32->42 37 * +32->42 38 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update with a reference to view in subquery +# in settable value +# +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 +explain select * from t1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 32 +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 32 +2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 32 Using where +update t1 set c1=c1 +(select max(a.c2) from v1 a +where a.c1 = t1.c1); +affected rows: 32 +info: Rows matched: 32 Changed: 32 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 * +11->13 11 * +11->13 12 * +11->13 13 * +12->14 14 * +12->14 15 * +12->14 16 * +12->14 17 * +12->14 18 * +21->23 21 * +21->23 22 * +21->23 23 * +22->24 24 * +22->24 25 * +22->24 26 * +22->24 27 * +22->24 28 * +31->33 31 * +31->33 32 * +31->33 33 * +32->34 34 * +32->34 35 * +32->34 36 * +32->34 37 * +32->34 38 * +truncate table t1; +insert into t1 select * from tmp; +# +# Update 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 +explain select * from v1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 32 Using where +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 NULL NULL NULL 32 Using where +2 DEPENDENT SUBQUERY a ALL NULL NULL NULL NULL 32 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: 7 +info: Rows matched: 7 Changed: 7 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 @@ -874,20 +9256,55 @@ NULL 4 NULL 6 NULL 7 NULL 8 -rollback; +NULL 11 +11->24 12 * +NULL 13 +NULL 14 +12->27 15 * +NULL 16 +NULL 17 +NULL 18 +21->35 21 * +NULL 22 +NULL 23 +22->38 24 * +NULL 25 +NULL 26 +NULL 27 +NULL 28 +31->45 31 * +NULL 32 +NULL 33 +32->48 34 * +NULL 35 +NULL 36 +NULL 37 +NULL 38 +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 -where c1 <2 -and exists (select 'X' - from v1 a -where a.c1 = v1.c1); +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 +explain select * from v1 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 32 Using where +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) +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 32 Using where +2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 32 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; +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 * @@ -897,22 +9314,57 @@ NULL 5 NULL 6 NULL 7 NULL 8 -rollback; +NULL 11 +NULL 12 +NULL 13 +NULL 14 +NULL 15 +NULL 16 +NULL 17 +NULL 18 +NULL 21 +NULL 22 +NULL 23 +NULL 24 +NULL 25 +NULL 26 +NULL 27 +NULL 28 +NULL 31 +NULL 32 +NULL 33 +NULL 34 +NULL 35 +NULL 36 +NULL 37 +NULL 38 +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; +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 +explain select * from v1 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 32 Using where +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1); Using join buffer (flat, BNL join) +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 32 Using where +3 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 32 Using where +2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 32 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 * @@ -922,41 +9374,107 @@ NULL 4 NULL 6 NULL 7 NULL 8 -rollback; +NULL 11 +NULL 12 +NULL 13 +NULL 14 +NULL 15 +NULL 16 +NULL 17 +NULL 18 +NULL 21 +NULL 22 +NULL 23 +NULL 24 +NULL 25 +NULL 26 +NULL 27 +NULL 28 +NULL 31 +NULL 32 +NULL 33 +NULL 34 +NULL 35 +NULL 36 +NULL 37 +NULL 38 +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); +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 +explain select * from t1 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 +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 update t1 set c3=c3+110 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 32 +1 PRIMARY a ALL NULL NULL NULL NULL 32 Using where; FirstMatch(t1) +update t1 set c3=c3+110 where c2 in (select distinct a.c2 from t1 a where t1.c1=a.c1); +affected rows: 32 +info: Rows matched: 32 Changed: 32 Warnings: 0 select c3 from t1; c3 -11 -14 -12 -15 -13 -16 -17 -18 -rollback; -# -# update with a limit -# -start transaction; +111 +112 +113 +114 +115 +116 +117 +118 +121 +122 +123 +124 +125 +126 +127 +128 +131 +132 +133 +134 +135 +136 +137 +138 +141 +142 +143 +144 +145 +146 +147 +148 +truncate table t1; +insert into t1 select * from tmp; +# +# Update with a limit +# +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 +explain select * from t1 limit 2; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 32 +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 32 +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; +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 * @@ -966,19 +9484,55 @@ NULL 5 NULL 6 NULL 7 NULL 8 -rollback; +NULL 11 +NULL 12 +NULL 13 +NULL 14 +NULL 15 +NULL 16 +NULL 17 +NULL 18 +NULL 21 +NULL 22 +NULL 23 +NULL 24 +NULL 25 +NULL 26 +NULL 27 +NULL 28 +NULL 31 +NULL 32 +NULL 33 +NULL 34 +NULL 35 +NULL 36 +NULL 37 +NULL 38 +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; +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 +explain select * from t1 order by c3 desc limit 2; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 32 Using filesort +explain update t1 +set c1=(select a.c3 from t1 a where a.c3 = t1.c3) +order by c3 desc limit 2; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 32 Using filesort +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) +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 @@ -986,58 +9540,357 @@ NULL 3 NULL 4 NULL 5 NULL 6 -2->7 7 * -2->8 8 * -rollback; +NULL 7 +NULL 8 +NULL 11 +NULL 12 +NULL 13 +NULL 14 +NULL 15 +NULL 16 +NULL 17 +NULL 18 +NULL 21 +NULL 22 +NULL 23 +NULL 24 +NULL 25 +NULL 26 +NULL 27 +NULL 28 +NULL 31 +NULL 32 +NULL 33 +NULL 34 +NULL 35 +NULL 36 +32->37 37 * +32->38 38 * +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 +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 +# 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 +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 +# 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; -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 +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 +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: 20 +info: Rows matched: 20 Changed: 20 Warnings: 0 +select c1,c2,c3 from t1; +c1 c2 c3 +1 1 1 +1 2 2 +1 3 0 +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 +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 0 +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 +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 +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 +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 +update t1 set c1=10 +where c1 <2 and exists (select 'X' from t1 a where a.c1 = t1.c1 + 10); +affected rows: 3 +info: Rows matched: 3 Changed: 3 Warnings: 0 +select c1,c2,c3 from t1; +c1 c2 c3 +10 1 1 +10 2 2 +10 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 +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 +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 +truncate table t1; +insert into t1 select * from tmp; # # Check call of after trigger # @@ -1050,126 +9903,218 @@ 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 +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 1 +2 1 4 +2 2 2 +2 2 5 +2 3 3 +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 +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 3 3 +11 2 12 +11 3 13 +12 2 15 +12 3 16 +12 4 17 +12 5 18 +2 1 1 +2 1 11 +2 1 14 +2 1 4 +2 2 2 +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 +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 +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 +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 +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 +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 +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 -rollback; +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 +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)) 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'); -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=@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; @@ -1189,11 +10134,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..ec27fa4 100644 --- a/mysql-test/main/update_use_source.test +++ b/mysql-test/main/update_use_source.test @@ -2,221 +2,55 @@ --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 ;/ - -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 @save_default_engine=@@default_storage_engine; + +--echo ####################################### +--echo # # +--echo # Engine InnoDB # +--echo # # +--echo ####################################### +set global innodb_stats_persistent=1; +set default_storage_engine=InnoDB; --source include/update_use_source.inc - ---echo Test with an index on updated columns -create index t1_c2 on t1 (c2,c1); +--source include/update_use_source_ext.inc + +--echo ####################################### +--echo # # +--echo # Engine Aria # +--echo # # +--echo ####################################### +set default_storage_engine=Aria; --source include/update_use_source.inc - ---echo Test with an index on updated columns -create index t1_c3 on t1 (c3); +--source include/update_use_source_ext.inc + +--echo ####################################### +--echo # # +--echo # Engine MyISAM # +--echo # # +--echo ####################################### +set default_storage_engine=MyISAM; --source include/update_use_source.inc - ---echo Test with a primary key on updated columns -drop index t1_c3 on t1; -alter table t1 add primary key (c3); +--source include/update_use_source_ext.inc + +--echo ####################################### +--echo # # +--echo # Engine MEMORY # +--echo # # +--echo ####################################### +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 +66,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 900348d..ed385f8 100644 --- a/mysql-test/suite/json/r/json_table.result +++ b/mysql-test/suite/json/r/json_table.result @@ -1146,3 +1146,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 982922f..5a8fe98 100644 --- a/mysql-test/suite/json/t/json_table.test +++ b/mysql-test/suite/json/t/json_table.test @@ -997,3 +997,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..ad17f0f 100644 --- a/storage/connect/mysql-test/connect/r/upd.result +++ b/storage/connect/mysql-test/connect/r/upd.result @@ -1627,3 +1627,159 @@ 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 t2 ALL NULL NULL NULL NULL 10 Using where; FirstMatch(t1) +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 a ALL NULL NULL NULL NULL 6 Using where; FirstMatch(t1) +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 t2 ALL NULL NULL NULL NULL 9 Using where; FirstMatch(t1) +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 a ALL NULL NULL NULL NULL 4 Using where; FirstMatch(t1) +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 #
participants (1)
-
IgorBabaev