diff --git a/mysql-test/include/update_use_source.inc b/mysql-test/include/update_use_source.inc
new file mode 100644
index 0000000..864b58e
--- /dev/null
+++ b/mysql-test/include/update_use_source.inc
@@ -0,0 +1,147 @@
+# 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 #
+
+start transaction;
+--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;
+--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;
+--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;
+--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;
+
+--echo #
+--echo # Update throw a view
+--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 #
+
+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;
+
+--echo #
+--echo # Update through  a view and using the view in subquery
+--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;
+
+--echo #
+--echo # Update of the index or primary key (c3)
+--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;
+
+--echo #
+--echo # update with a limit
+--echo #
+
+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;
+
+--echo #
+--echo # update with a limit and an order by
+--echo #
+
+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;
diff --git a/mysql-test/r/lowercase_view.result b/mysql-test/r/lowercase_view.result
index 6ccfe29..a52c45f 100644
--- a/mysql-test/r/lowercase_view.result
+++ b/mysql-test/r/lowercase_view.result
@@ -15,12 +15,6 @@ create table t2aA (col1 int);
 create view v1Aa as select * from t1aA;
 create view v2aA as select * from v1aA;
 create view v3Aa as select v2Aa.col1 from v2aA,t2Aa where v2Aa.col1 = t2aA.col1;
-update v2aA set col1 = (select max(col1) from v1Aa);
-ERROR HY000: The definition of table 'v1Aa' prevents operation UPDATE on table 'v2aA'
-update v2Aa set col1 = (select max(col1) from t1Aa);
-ERROR HY000: The definition of table 'v2Aa' prevents operation UPDATE on table 'v2Aa'
-update v2aA set col1 = (select max(col1) from v2Aa);
-ERROR HY000: Table 'v2aA' is specified twice, both as a target for 'UPDATE' and as a separate source for data
 update v2aA,t2Aa set v2Aa.col1 = (select max(col1) from v1aA) where v2aA.col1 = t2aA.col1;
 ERROR HY000: The definition of table 'v1aA' prevents operation UPDATE on table 'v2aA'
 update t1aA,t2Aa set t1Aa.col1 = (select max(col1) from v1Aa) where t1aA.col1 = t2aA.col1;
diff --git a/mysql-test/r/merge.result b/mysql-test/r/merge.result
index f55251a..afea085 100644
--- a/mysql-test/r/merge.result
+++ b/mysql-test/r/merge.result
@@ -3714,34 +3714,6 @@ insert into m1 (a) values ((select max(a) from v1));
 ERROR HY000: The definition of table 'v1' prevents operation INSERT on table 'm1'
 insert into m1 (a) values ((select max(a) from tmp, v1));
 ERROR HY000: The definition of table 'v1' prevents operation INSERT on table 'm1'
-update m1 set a = ((select max(a) from m1));
-ERROR HY000: Table 'm1' is specified twice, both as a target for 'UPDATE' and as a separate source for data
-update m1 set a = ((select max(a) from m2));
-ERROR HY000: Table 'm1' is specified twice, both as a target for 'UPDATE' and as a separate source for data
-update m1 set a = ((select max(a) from t1));
-ERROR HY000: Table 'm1' is specified twice, both as a target for 'UPDATE' and as a separate source for data
-update m1 set a = ((select max(a) from t2));
-ERROR HY000: Table 'm1' is specified twice, both as a target for 'UPDATE' and as a separate source for data
-update m1 set a = ((select max(a) from t3, m1));
-ERROR HY000: Table 'm1' is specified twice, both as a target for 'UPDATE' and as a separate source for data
-update m1 set a = ((select max(a) from t3, m2));
-ERROR HY000: Table 'm1' is specified twice, both as a target for 'UPDATE' and as a separate source for data
-update m1 set a = ((select max(a) from t3, t1));
-ERROR HY000: Table 'm1' is specified twice, both as a target for 'UPDATE' and as a separate source for data
-update m1 set a = ((select max(a) from t3, t2));
-ERROR HY000: Table 'm1' is specified twice, both as a target for 'UPDATE' and as a separate source for data
-update m1 set a = ((select max(a) from tmp, m1));
-ERROR HY000: Table 'm1' is specified twice, both as a target for 'UPDATE' and as a separate source for data
-update m1 set a = ((select max(a) from tmp, m2));
-ERROR HY000: Table 'm1' is specified twice, both as a target for 'UPDATE' and as a separate source for data
-update m1 set a = ((select max(a) from tmp, t1));
-ERROR HY000: Table 'm1' is specified twice, both as a target for 'UPDATE' and as a separate source for data
-update m1 set a = ((select max(a) from tmp, t2));
-ERROR HY000: Table 'm1' is specified twice, both as a target for 'UPDATE' and as a separate source for data
-update m1 set a = ((select max(a) from v1));
-ERROR HY000: The definition of table 'v1' prevents operation UPDATE on table 'm1'
-update m1 set a = ((select max(a) from tmp, v1));
-ERROR HY000: The definition of table 'v1' prevents operation UPDATE on table 'm1'
 drop view v1;
 drop temporary table tmp;
 drop table t1, t2, t3, m1, m2;
diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result
index 9f07b1f..79a5073 100644
--- a/mysql-test/r/subselect.result
+++ b/mysql-test/r/subselect.result
@@ -583,8 +583,6 @@ a	b
 0	10
 1	11
 2	12
-update t1 set b= (select b from t1);
-ERROR HY000: Table 't1' is specified twice, both as a target for 'UPDATE' and as a separate source for data
 update t1 set b= (select b from t2);
 ERROR 21000: Subquery returns more than 1 row
 update t1 set b= (select b from t2 where t1.a = t2.a);
diff --git a/mysql-test/r/subselect_no_exists_to_in.result b/mysql-test/r/subselect_no_exists_to_in.result
index e4b57d9..e5baa0d 100644
--- a/mysql-test/r/subselect_no_exists_to_in.result
+++ b/mysql-test/r/subselect_no_exists_to_in.result
@@ -587,8 +587,6 @@ a	b
 0	10
 1	11
 2	12
-update t1 set b= (select b from t1);
-ERROR HY000: Table 't1' is specified twice, both as a target for 'UPDATE' and as a separate source for data
 update t1 set b= (select b from t2);
 ERROR 21000: Subquery returns more than 1 row
 update t1 set b= (select b from t2 where t1.a = t2.a);
diff --git a/mysql-test/r/subselect_no_mat.result b/mysql-test/r/subselect_no_mat.result
index 2208277..eb312c1 100644
--- a/mysql-test/r/subselect_no_mat.result
+++ b/mysql-test/r/subselect_no_mat.result
@@ -590,8 +590,6 @@ a	b
 0	10
 1	11
 2	12
-update t1 set b= (select b from t1);
-ERROR HY000: Table 't1' is specified twice, both as a target for 'UPDATE' and as a separate source for data
 update t1 set b= (select b from t2);
 ERROR 21000: Subquery returns more than 1 row
 update t1 set b= (select b from t2 where t1.a = t2.a);
diff --git a/mysql-test/r/subselect_no_opts.result b/mysql-test/r/subselect_no_opts.result
index 5f71700..7110ceb 100644
--- a/mysql-test/r/subselect_no_opts.result
+++ b/mysql-test/r/subselect_no_opts.result
@@ -586,8 +586,6 @@ a	b
 0	10
 1	11
 2	12
-update t1 set b= (select b from t1);
-ERROR HY000: Table 't1' is specified twice, both as a target for 'UPDATE' and as a separate source for data
 update t1 set b= (select b from t2);
 ERROR 21000: Subquery returns more than 1 row
 update t1 set b= (select b from t2 where t1.a = t2.a);
diff --git a/mysql-test/r/subselect_no_scache.result b/mysql-test/r/subselect_no_scache.result
index 8500fa2..5d000c7 100644
--- a/mysql-test/r/subselect_no_scache.result
+++ b/mysql-test/r/subselect_no_scache.result
@@ -589,8 +589,6 @@ a	b
 0	10
 1	11
 2	12
-update t1 set b= (select b from t1);
-ERROR HY000: Table 't1' is specified twice, both as a target for 'UPDATE' and as a separate source for data
 update t1 set b= (select b from t2);
 ERROR 21000: Subquery returns more than 1 row
 update t1 set b= (select b from t2 where t1.a = t2.a);
diff --git a/mysql-test/r/subselect_no_semijoin.result b/mysql-test/r/subselect_no_semijoin.result
index 48bf9ce..7474fd8 100644
--- a/mysql-test/r/subselect_no_semijoin.result
+++ b/mysql-test/r/subselect_no_semijoin.result
@@ -586,8 +586,6 @@ a	b
 0	10
 1	11
 2	12
-update t1 set b= (select b from t1);
-ERROR HY000: Table 't1' is specified twice, both as a target for 'UPDATE' and as a separate source for data
 update t1 set b= (select b from t2);
 ERROR 21000: Subquery returns more than 1 row
 update t1 set b= (select b from t2 where t1.a = t2.a);
diff --git a/mysql-test/r/update_use_source.result b/mysql-test/r/update_use_source.result
new file mode 100644
index 0000000..7ea1436
--- /dev/null
+++ b/mysql-test/r/update_use_source.result
@@ -0,0 +1,1075 @@
+create table t1 (old_c1 integer, old_c2 integer,c1 integer, c2 integer, c3 integer) engine=InnoDb;
+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);
+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 ;
+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	t1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using buffer
+2	DEPENDENT SUBQUERY	a	ALL	NULL	NULL	NULL	NULL	8	Using where
+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;
+concat(old_c1,'->',c1)	c3	Changed
+NULL	1	 
+NULL	2	 
+NULL	3	 
+NULL	4	 
+2->17	5	*
+NULL	6	 
+NULL	7	 
+NULL	8	 
+rollback;
+#
+# Update through a view and using the 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);
+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	 
+rollback;
+#
+# Update through  a view and using the view in subquery
+#
+start transaction;
+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	 
+rollback;
+#
+# Update of the index or primary key (c3)
+#
+start transaction;
+explain update t1 set c3=c3+10 where c2 in (select distinct a.c2 from t1 a where t1.c1=a.c1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using buffer
+2	DEPENDENT SUBQUERY	a	ALL	NULL	NULL	NULL	NULL	8	Using where
+update t1 set c3=c3+10 where c2 in (select distinct a.c2 from t1 a where t1.c1=a.c1);
+affected rows: 8
+info: Rows matched: 8  Changed: 8  Warnings: 0
+select c3 from t1;
+c3
+11
+12
+13
+14
+15
+16
+17
+18
+rollback;
+#
+# update with a limit
+#
+start transaction;
+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	 
+rollback;
+#
+# update with a limit and an order by
+#
+start transaction;
+update t1
+set c1=(select a.c3
+from t1 a
+where a.c3 = t1.c3)
+order by c3 desc limit 2;
+affected rows: 2
+info: Rows matched: 2  Changed: 2  Warnings: 0
+select concat(old_c1,'->',c1),c3, case when c1 != old_c1 then '*' else ' ' end "Changed" from t1 ;
+concat(old_c1,'->',c1)	c3	Changed
+NULL	1	 
+NULL	2	 
+NULL	3	 
+NULL	4	 
+NULL	5	 
+NULL	6	 
+2->7	7	*
+2->8	8	*
+rollback;
+Test with an index on updated columns
+create index t1_c2 on t1 (c2,c1);
+#
+# 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	t1	range	t1_c2	t1_c2	5	NULL	2	Using where; Using buffer
+2	DEPENDENT SUBQUERY	a	ref	t1_c2	t1_c2	5	test.t1.c2	4	Using index
+start transaction;
+update t1 set c1=c1+10 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 >= 3;
+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;
+concat(old_c1,'->',c1)	c3	Changed
+NULL	1	 
+NULL	2	 
+NULL	3	 
+NULL	4	 
+2->17	5	*
+NULL	6	 
+NULL	7	 
+NULL	8	 
+rollback;
+#
+# Update through a view and using the 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);
+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	 
+rollback;
+#
+# Update through  a view and using the view in subquery
+#
+start transaction;
+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	 
+rollback;
+#
+# Update of the index or primary key (c3)
+#
+start transaction;
+explain update t1 set c3=c3+10 where c2 in (select distinct a.c2 from t1 a where t1.c1=a.c1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using buffer
+2	DEPENDENT SUBQUERY	a	index_subquery	t1_c2	t1_c2	10	func,test.t1.c1	1	Using index; Using where
+update t1 set c3=c3+10 where c2 in (select distinct a.c2 from t1 a where t1.c1=a.c1);
+affected rows: 8
+info: Rows matched: 8  Changed: 8  Warnings: 0
+select c3 from t1;
+c3
+11
+12
+13
+14
+15
+16
+17
+18
+rollback;
+#
+# update with a limit
+#
+start transaction;
+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	 
+rollback;
+#
+# update with a limit and an order by
+#
+start transaction;
+update t1
+set c1=(select a.c3
+from t1 a
+where a.c3 = t1.c3)
+order by c3 desc limit 2;
+affected rows: 2
+info: Rows matched: 2  Changed: 2  Warnings: 0
+select concat(old_c1,'->',c1),c3, case when c1 != old_c1 then '*' else ' ' end "Changed" from t1 ;
+concat(old_c1,'->',c1)	c3	Changed
+NULL	1	 
+NULL	2	 
+NULL	3	 
+NULL	4	 
+NULL	5	 
+NULL	6	 
+2->7	7	*
+2->8	8	*
+rollback;
+Test with an index on updated columns
+create index t1_c3 on t1 (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	t1	range	t1_c2	t1_c2	5	NULL	2	Using where; Using buffer
+2	DEPENDENT SUBQUERY	a	ref	t1_c2	t1_c2	5	test.t1.c2	1	Using index
+start transaction;
+update t1 set c1=c1+10 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 >= 3;
+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;
+concat(old_c1,'->',c1)	c3	Changed
+NULL	1	 
+NULL	2	 
+NULL	3	 
+NULL	4	 
+2->17	5	*
+NULL	6	 
+NULL	7	 
+NULL	8	 
+rollback;
+#
+# Update through a view and using the 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);
+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	 
+rollback;
+#
+# Update through  a view and using the view in subquery
+#
+start transaction;
+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	 
+rollback;
+#
+# Update of the index or primary key (c3)
+#
+start transaction;
+explain update t1 set c3=c3+10 where c2 in (select distinct a.c2 from t1 a where t1.c1=a.c1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using buffer
+2	DEPENDENT SUBQUERY	a	index_subquery	t1_c2	t1_c2	10	func,test.t1.c1	1	Using index; Using where
+update t1 set c3=c3+10 where c2 in (select distinct a.c2 from t1 a where t1.c1=a.c1);
+affected rows: 8
+info: Rows matched: 8  Changed: 8  Warnings: 0
+select c3 from t1;
+c3
+11
+12
+13
+14
+15
+16
+17
+18
+rollback;
+#
+# update with a limit
+#
+start transaction;
+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	 
+rollback;
+#
+# update with a limit and an order by
+#
+start transaction;
+update t1
+set c1=(select a.c3
+from t1 a
+where a.c3 = t1.c3)
+order by c3 desc limit 2;
+affected rows: 2
+info: Rows matched: 2  Changed: 2  Warnings: 0
+select concat(old_c1,'->',c1),c3, case when c1 != old_c1 then '*' else ' ' end "Changed" from t1 ;
+concat(old_c1,'->',c1)	c3	Changed
+NULL	1	 
+NULL	2	 
+NULL	3	 
+NULL	4	 
+NULL	5	 
+NULL	6	 
+2->7	7	*
+2->8	8	*
+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	t1	range	t1_c2	t1_c2	5	NULL	2	Using where; Using buffer
+2	DEPENDENT SUBQUERY	a	ref	t1_c2	t1_c2	5	test.t1.c2	1	Using index
+start transaction;
+update t1 set c1=c1+10 where exists (select 'X' from t1 a where a.c2 = t1.c2) and c2 >= 3;
+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;
+concat(old_c1,'->',c1)	c3	Changed
+NULL	1	 
+NULL	2	 
+NULL	3	 
+NULL	4	 
+2->17	5	*
+NULL	6	 
+NULL	7	 
+NULL	8	 
+rollback;
+#
+# Update through a view and using the 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);
+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	 
+rollback;
+#
+# Update through  a view and using the view in subquery
+#
+start transaction;
+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	 
+rollback;
+#
+# Update of the index or primary key (c3)
+#
+start transaction;
+explain update t1 set c3=c3+10 where c2 in (select distinct a.c2 from t1 a where t1.c1=a.c1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	t1	index	NULL	PRIMARY	4	NULL	8	Using where; Using buffer
+2	DEPENDENT SUBQUERY	a	index_subquery	t1_c2	t1_c2	10	func,test.t1.c1	1	Using index; Using where
+update t1 set c3=c3+10 where c2 in (select distinct a.c2 from t1 a where t1.c1=a.c1);
+affected rows: 8
+info: Rows matched: 8  Changed: 8  Warnings: 0
+select c3 from t1;
+c3
+11
+14
+12
+15
+13
+16
+17
+18
+rollback;
+#
+# update with a limit
+#
+start transaction;
+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	 
+rollback;
+#
+# update with a limit and an order by
+#
+start transaction;
+update t1
+set c1=(select a.c3
+from t1 a
+where a.c3 = t1.c3)
+order by c3 desc limit 2;
+affected rows: 2
+info: Rows matched: 2  Changed: 2  Warnings: 0
+select concat(old_c1,'->',c1),c3, case when c1 != old_c1 then '*' else ' ' end "Changed" from t1 ;
+concat(old_c1,'->',c1)	c3	Changed
+NULL	1	 
+NULL	2	 
+NULL	3	 
+NULL	4	 
+NULL	5	 
+NULL	6	 
+2->7	7	*
+2->8	8	*
+rollback;
+# 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
+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;
+ERROR 23000: Duplicate entry '0' for key 'PRIMARY'
+rollback;
+# 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 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);
+affected rows: 0
+info: Rows matched: 3  Changed: 0  Warnings: 0
+rollback;
+#
+# 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
+#
+# Check error if delete 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;
+ERROR HY000: Table 't1' is specified twice, both as a target for 'UPDATE' and as a separate source for data
+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 ;
+c1	c2	c3
+1	1	1
+2	2	2
+3	3	3
+2	1	4
+2	2	5
+2	3	6
+2	4	7
+2	5	8
+rollback;
+drop table t1;
diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result
index 721ad05..4d83eb0 100644
--- a/mysql-test/r/view.result
+++ b/mysql-test/r/view.result
@@ -943,12 +943,6 @@ create table t3 (col1 datetime not null);
 create view v1 as select * from t1;
 create view v2 as select * from v1;
 create view v3 as select v2.col1 from v2,t2 where v2.col1 = t2.col1;
-update v2 set col1 = (select max(col1) from v1);
-ERROR HY000: The definition of table 'v1' prevents operation UPDATE on table 'v2'
-update v2 set col1 = (select max(col1) from t1);
-ERROR HY000: The definition of table 'v2' prevents operation UPDATE on table 'v2'
-update v2 set col1 = (select max(col1) from v2);
-ERROR HY000: Table 'v2' is specified twice, both as a target for 'UPDATE' and as a separate source for data
 update v2,t2 set v2.col1 = (select max(col1) from v1) where v2.col1 = t2.col1;
 ERROR HY000: The definition of table 'v1' prevents operation UPDATE on table 'v2'
 update t1,t2 set t1.col1 = (select max(col1) from v1) where t1.col1 = t2.col1;
@@ -2024,8 +2018,6 @@ create view v1 as select f59, f60 from t1 where f59 in
 (select f59 from t1);
 update v1 set f60=2345;
 ERROR HY000: The target table v1 of the UPDATE is not updatable
-update t1 set f60=(select max(f60) from v1);
-ERROR HY000: The definition of table 'v1' prevents operation UPDATE on table 't1'
 drop view v1;
 drop table t1;
 create table t1 (s1 int);
diff --git a/mysql-test/t/lowercase_view.test b/mysql-test/t/lowercase_view.test
index 4c91383..b6a7ef6 100644
--- a/mysql-test/t/lowercase_view.test
+++ b/mysql-test/t/lowercase_view.test
@@ -24,12 +24,6 @@ create view v1Aa as select * from t1aA;
 create view v2aA as select * from v1aA;
 create view v3Aa as select v2Aa.col1 from v2aA,t2Aa where v2Aa.col1 = t2aA.col1;
 -- error 1443
-update v2aA set col1 = (select max(col1) from v1Aa);
--- error 1443
-update v2Aa set col1 = (select max(col1) from t1Aa);
--- error 1093
-update v2aA set col1 = (select max(col1) from v2Aa);
--- error 1443
 update v2aA,t2Aa set v2Aa.col1 = (select max(col1) from v1aA) where v2aA.col1 = t2aA.col1;
 -- error 1443
 update t1aA,t2Aa set t1Aa.col1 = (select max(col1) from v1Aa) where t1aA.col1 = t2aA.col1;
@@ -65,6 +59,7 @@ update t2Aa,v2aA set v2Aa.col1 = (select max(col1) from v2aA) where v2Aa.col1 =
 update t2Aa,t1Aa set t1aA.col1 = (select max(col1) from v2aA) where t1Aa.col1 = t2aA.col1;
 -- error 1443
 update t2Aa,v1Aa set v1aA.col1 = (select max(col1) from v2Aa) where v1Aa.col1 = t2aA.col1;
+# MDEV 12874 : Next four tests continue to failed because updates are converted to multiupdate
 -- error 1443
 update v3aA set v3Aa.col1 = (select max(col1) from v1aA);
 -- error 1443
diff --git a/mysql-test/t/merge.test b/mysql-test/t/merge.test
index 95c78ca..4a747e0 100644
--- a/mysql-test/t/merge.test
+++ b/mysql-test/t/merge.test
@@ -2731,39 +2731,6 @@ insert into m1 (a) values ((select max(a) from v1));
 --error ER_VIEW_PREVENT_UPDATE
 insert into m1 (a) values ((select max(a) from tmp, v1));
 
-
---error ER_UPDATE_TABLE_USED
-update m1 set a = ((select max(a) from m1));
---error ER_UPDATE_TABLE_USED
-update m1 set a = ((select max(a) from m2));
---error ER_UPDATE_TABLE_USED
-update m1 set a = ((select max(a) from t1));
---error ER_UPDATE_TABLE_USED
-update m1 set a = ((select max(a) from t2));
-
---error ER_UPDATE_TABLE_USED
-update m1 set a = ((select max(a) from t3, m1));
---error ER_UPDATE_TABLE_USED
-update m1 set a = ((select max(a) from t3, m2));
---error ER_UPDATE_TABLE_USED
-update m1 set a = ((select max(a) from t3, t1));
---error ER_UPDATE_TABLE_USED
-update m1 set a = ((select max(a) from t3, t2));
-
---error ER_UPDATE_TABLE_USED
-update m1 set a = ((select max(a) from tmp, m1));
---error ER_UPDATE_TABLE_USED
-update m1 set a = ((select max(a) from tmp, m2));
---error ER_UPDATE_TABLE_USED
-update m1 set a = ((select max(a) from tmp, t1));
---error ER_UPDATE_TABLE_USED
-update m1 set a = ((select max(a) from tmp, t2));
- 
---error ER_VIEW_PREVENT_UPDATE
-update m1 set a = ((select max(a) from v1));
---error ER_VIEW_PREVENT_UPDATE
-update m1 set a = ((select max(a) from tmp, v1));
-
 drop view v1;
 drop temporary table tmp;
 drop table t1, t2, t3, m1, m2;
diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test
index 4d4a3f2..2efbe05 100644
--- a/mysql-test/t/subselect.test
+++ b/mysql-test/t/subselect.test
@@ -325,8 +325,6 @@ create table t2 (a int NOT NULL, b int, primary key (a));
 insert into t1 values (0, 10),(1, 11),(2, 12);
 insert into t2 values (1, 21),(2, 22),(3, 23);
 select * from t1;
--- error ER_UPDATE_TABLE_USED
-update t1 set b= (select b from t1);
 -- error ER_SUBQUERY_NO_1_ROW
 update t1 set b= (select b from t2);
 update t1 set b= (select b from t2 where t1.a = t2.a);
diff --git a/mysql-test/t/update_use_source.test b/mysql-test/t/update_use_source.test
new file mode 100644
index 0000000..930a93d
--- /dev/null
+++ b/mysql-test/t/update_use_source.test
@@ -0,0 +1,127 @@
+--source include/have_innodb.inc
+
+create table t1 (old_c1 integer, old_c2 integer,c1 integer, c2 integer, c3 integer) engine=InnoDb;
+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
+--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.inc
+
+--echo Test with an index on updated columns
+create index t1_c3 on t1 (c3);
+--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.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 # 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 error if delete with order by and after trigger
+--echo #
+
+--error ER_UPDATE_TABLE_USED
+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;
+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;
diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test
index a9d6d9c..25f8afb 100644
--- a/mysql-test/t/view.test
+++ b/mysql-test/t/view.test
@@ -865,12 +865,6 @@ create view v1 as select * from t1;
 create view v2 as select * from v1;
 create view v3 as select v2.col1 from v2,t2 where v2.col1 = t2.col1;
 -- error ER_VIEW_PREVENT_UPDATE
-update v2 set col1 = (select max(col1) from v1);
--- error ER_VIEW_PREVENT_UPDATE
-update v2 set col1 = (select max(col1) from t1);
--- error ER_UPDATE_TABLE_USED
-update v2 set col1 = (select max(col1) from v2);
--- error ER_VIEW_PREVENT_UPDATE
 update v2,t2 set v2.col1 = (select max(col1) from v1) where v2.col1 = t2.col1;
 -- error ER_VIEW_PREVENT_UPDATE
 update t1,t2 set t1.col1 = (select max(col1) from v1) where t1.col1 = t2.col1;
@@ -1803,8 +1797,6 @@ create view v1 as select f59, f60 from t1 where f59 in
          (select f59 from t1);
 -- error ER_NON_UPDATABLE_TABLE
 update v1 set f60=2345;
--- error ER_VIEW_PREVENT_UPDATE
-update t1 set f60=(select max(f60) from v1);
 drop view v1;
 drop table t1;
 
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index 997ff2a..e3e5fbb 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -1468,8 +1468,7 @@ static int mysql_test_update(Prepared_statement *stmt,
   table_list->register_want_access(SELECT_ACL);
 #endif
   if (setup_fields(thd, Ref_ptr_array(),
-                   stmt->lex->value_list, MARK_COLUMNS_NONE, 0, 0) ||
-      check_unique_table(thd, table_list))
+                   stmt->lex->value_list, MARK_COLUMNS_NONE, 0, 0))
     goto error;
   /* TODO: here we should send types of placeholders to the client. */
   DBUG_RETURN(0);
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index 568dd40..bc7e84b 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -222,6 +222,127 @@ static void prepare_record_for_error_message(int error, TABLE *table)
 }
 
 
+static int check_update_status(TABLE *table, int error, ha_rows *updated,
+                               bool ignore)
+{
+  if (!error)
+  {
+    (*updated)++;
+    return 0;
+  }
+
+  if (error == HA_ERR_RECORD_IS_THE_SAME)
+    return 0;
+
+  if (!ignore || table->file->is_fatal_error(error, HA_CHECK_ALL))
+  {
+    /*
+      If (ignore && error is ignorable) we don't have to
+      do anything; otherwise...
+    */
+    myf flags= 0;
+
+    if (table->file->is_fatal_error(error, HA_CHECK_ALL))
+      flags|= ME_FATALERROR; /* Other handler errors are fatal */
+
+    prepare_record_for_error_message(error, table);
+    table->file->print_error(error, MYF(flags));
+    return 1;
+  }
+  return 0;
+}
+
+static int send_update_to_engine(TABLE *table, ha_rows *limit,
+                                 ha_rows *updated, bool will_batch,
+                                 uint *dup_key_found)
+{
+  int error;
+  if (will_batch)
+  {
+    /*
+      Typically a batched handler can execute the batched jobs when:
+      1) When specifically told to do so
+      2) When it is not a good idea to batch anymore
+      3) When it is necessary to send batch for other reasons
+          (One such reason is when READ's must be performed)
+
+      1) is covered by exec_bulk_update calls.
+      2) and 3) is handled by the bulk_update_row method.
+
+      bulk_update_row can execute the updates including the one
+      defined in the bulk_update_row or not including the row
+      in the call. This is up to the handler implementation and can
+      vary from call to call.
+
+      The dup_key_found reports the number of duplicate keys found
+      in those updates actually executed. It only reports those if
+      the extra call with HA_EXTRA_IGNORE_DUP_KEY have been issued.
+      If this hasn't been issued it returns an error code and can
+      ignore this number. Thus any handler that implements batching
+      for UPDATE IGNORE must also handle this extra call properly.
+
+      If a duplicate key is found on the record included in this
+      call then it should be included in the count of dup_key_found
+      and error should be set to 0 (only if these errors are ignored).
+    */
+    error= table->file->ha_bulk_update_row(table->record[1],
+                                           table->record[0],
+                                           dup_key_found);
+    (*limit)+= *dup_key_found;
+    (*updated)-= *dup_key_found;
+  }
+  else
+  {
+    error= table->file->ha_update_row(table->record[1],
+                                      table->record[0]);
+  }
+  return error;
+}
+
+static int check_eof_or_limit(TABLE *table, ha_rows *limit, bool will_batch,
+                              bool using_limit, uint *dup_key_found,
+                              ha_rows *updated)
+{
+  int error;
+  if (!--(*limit) && using_limit)
+  {
+    /*
+      We have reached end-of-file in most common situations where no
+      batching has occurred and if batching was supposed to occur but
+      no updates were made and finally when the batch execution was
+      performed without error and without finding any duplicate keys.
+      If the batched updates were performed with errors we need to
+      check and if no error but duplicate key's found we need to
+      continue since those are not counted for in limit.
+    */
+    if (will_batch &&
+        ((error= table->file->exec_bulk_update(dup_key_found)) ||
+          *dup_key_found))
+    {
+      if (error)
+      {
+        /*
+          The handler should not report error of duplicate keys if they
+          are ignored. This is a requirement on batching handlers.
+        */
+        prepare_record_for_error_message(error, table);
+        table->file->print_error(error, MYF(0));
+        return 1;
+      }
+      /*
+        Either an error was found and we are ignoring errors or there
+        were duplicate keys found. In both cases we need to correct
+        the counters and continue the loop.
+      */
+      *limit= *dup_key_found; //limit is 0 when we get here so need to +
+      (*updated)-= *dup_key_found;
+    }
+    else
+      return -1; // Simulate end of file
+  }
+  return 0;
+}
+
 /*
   Process usual UPDATE
 
@@ -278,6 +399,7 @@ int mysql_update(THD *thd,
   killed_state killed_status= NOT_KILLED;
   Update_plan query_plan(thd->mem_root);
   Explain_update *explain;
+  IO_CACHE tempfile_newdata;
   query_plan.index= MAX_KEY;
   query_plan.using_filesort= FALSE;
   DBUG_ENTER("mysql_update");
@@ -365,8 +487,7 @@ int mysql_update(THD *thd,
     DBUG_RETURN(1);				/* purecov: inspected */
   }
 
-  if (check_unique_table(thd, table_list))
-    DBUG_RETURN(TRUE);
+  TABLE_LIST *update_source_table=unique_table(thd, table_list, table_list->next_global, 0);
 
   switch_to_nullable_trigger_fields(fields, table);
   switch_to_nullable_trigger_fields(values, table);
@@ -502,7 +623,7 @@ int mysql_update(THD *thd,
   query_plan.select= select;
   query_plan.possible_keys= select? select->possible_keys: key_map(0);
   
-  if (used_key_is_modified || order ||
+  if (used_key_is_modified || order || update_source_table ||
       partition_key_modified(table, table->write_set))
   {
     if (order && need_sort)
@@ -539,6 +660,14 @@ int mysql_update(THD *thd,
     */
     if (query_plan.using_filesort)
     {
+      if (update_source_table && table->triggers &&
+          table->triggers->has_triggers(TRG_EVENT_UPDATE, TRG_ACTION_AFTER))
+      {
+        update_non_unique_table_error(table_list, "UPDATE",
+                                      update_source_table);
+        goto err;
+      }
+
       /*
 	Doing an ORDER BY;  Let filesort find and sort the rows we are going
 	to update
@@ -729,7 +858,15 @@ int mysql_update(THD *thd,
     the table handler is returning all columns OR if
     if all updated columns are read
   */
-  can_compare_record= records_are_comparable(table);
+  if (!update_source_table)
+    can_compare_record= records_are_comparable(table);
+  else
+  {
+    can_compare_record= FALSE;
+    if (open_cached_file(&tempfile_newdata, mysql_tmpdir, TEMP_PREFIX,
+                         DISK_BUFFER_SIZE, MYF(MY_WME)))
+      goto err;
+  }
   explain->tracker.on_scan_init();
 
   while (!(error=info.read_record(&info)) && !thd->killed)
@@ -768,70 +905,27 @@ int mysql_update(THD *thd,
             break;
           }
         }
-        if (will_batch)
+        if (update_source_table)
         {
-          /*
-            Typically a batched handler can execute the batched jobs when:
-            1) When specifically told to do so
-            2) When it is not a good idea to batch anymore
-            3) When it is necessary to send batch for other reasons
-               (One such reason is when READ's must be performed)
-
-            1) is covered by exec_bulk_update calls.
-            2) and 3) is handled by the bulk_update_row method.
-            
-            bulk_update_row can execute the updates including the one
-            defined in the bulk_update_row or not including the row
-            in the call. This is up to the handler implementation and can
-            vary from call to call.
-
-            The dup_key_found reports the number of duplicate keys found
-            in those updates actually executed. It only reports those if
-            the extra call with HA_EXTRA_IGNORE_DUP_KEY have been issued.
-            If this hasn't been issued it returns an error code and can
-            ignore this number. Thus any handler that implements batching
-            for UPDATE IGNORE must also handle this extra call properly.
-
-            If a duplicate key is found on the record included in this
-            call then it should be included in the count of dup_key_found
-            and error should be set to 0 (only if these errors are ignored).
-          */
-          error= table->file->ha_bulk_update_row(table->record[1],
-                                                 table->record[0],
-                                                 &dup_key_found);
-          limit+= dup_key_found;
-          updated-= dup_key_found;
+          // Store new data to update later.
+          if ((my_b_write(&tempfile_newdata, table->record[0],
+                          table->s->reclength)))
+          {
+            error= 1;
+            break;
+          }
+          continue;
         }
         else
         {
-          /* Non-batched update */
-	  error= table->file->ha_update_row(table->record[1],
-                                            table->record[0]);
+          error= send_update_to_engine(table, &limit, &updated, will_batch,
+                                       &dup_key_found);
         }
-        if (!error || error == HA_ERR_RECORD_IS_THE_SAME)
-	{
-          if (error != HA_ERR_RECORD_IS_THE_SAME)
-            updated++;
-          else
-            error= 0;
-	}
- 	else if (!ignore ||
-                 table->file->is_fatal_error(error, HA_CHECK_ALL))
-	{
-          /*
-            If (ignore && error is ignorable) we don't have to
-            do anything; otherwise...
-          */
-          myf flags= 0;
 
-          if (table->file->is_fatal_error(error, HA_CHECK_ALL))
-            flags|= ME_FATALERROR; /* Other handler errors are fatal */
-
-          prepare_record_for_error_message(error, table);
-	  table->file->print_error(error,MYF(flags));
-	  error= 1;
-	  break;
-	}
+        if ((error= check_update_status(table, error, &updated, ignore)))
+        {
+          break;
+        }
       }
 
       if (table->triggers &&
@@ -842,59 +936,24 @@ int mysql_update(THD *thd,
         break;
       }
 
-      if (!--limit && using_limit)
-      {
-        /*
-          We have reached end-of-file in most common situations where no
-          batching has occurred and if batching was supposed to occur but
-          no updates were made and finally when the batch execution was
-          performed without error and without finding any duplicate keys.
-          If the batched updates were performed with errors we need to
-          check and if no error but duplicate key's found we need to
-          continue since those are not counted for in limit.
-        */
-        if (will_batch &&
-            ((error= table->file->exec_bulk_update(&dup_key_found)) ||
-             dup_key_found))
-        {
- 	  if (error)
-          {
-            /* purecov: begin inspected */
-            /*
-              The handler should not report error of duplicate keys if they
-              are ignored. This is a requirement on batching handlers.
-            */
-            prepare_record_for_error_message(error, table);
-            table->file->print_error(error,MYF(0));
-            error= 1;
-            break;
-            /* purecov: end */
-          }
-          /*
-            Either an error was found and we are ignoring errors or there
-            were duplicate keys found. In both cases we need to correct
-            the counters and continue the loop.
-          */
-          limit= dup_key_found; //limit is 0 when we get here so need to +
-          updated-= dup_key_found;
-        }
-        else
-        {
-	  error= -1;				// Simulate end of file
-	  break;
-        }
-      }
+      if ((error= check_eof_or_limit(table, &limit, will_batch, using_limit,
+                                     &dup_key_found, &updated)))
+        break;
     }
+
     /*
       Don't try unlocking the row if skip_record reported an error since in
       this case the transaction might have been rolled back already.
     */
-    else if (!thd->is_error())
-      table->file->unlock_row();
     else
     {
-      error= 1;
-      break;
+      if (!thd->is_error())
+        table->file->unlock_row();
+      else
+      {
+        error= 1;
+        break;
+      }
     }
     thd->get_stmt_da()->inc_current_row_for_warning();
     if (thd->is_error())
@@ -903,6 +962,76 @@ int mysql_update(THD *thd,
       break;
     }
   }
+
+  if (update_source_table)
+  {
+    if (error > 0 || thd->is_error())
+    {
+      close_cached_file(&tempfile_newdata);
+      goto err;
+    }
+    if (found > 0)
+    {
+      end_read_record(&info);
+      if (!file_sort && reinit_io_cache(&select->file, READ_CACHE ,0L ,0 ,0))
+      {
+        error= 1;
+        close_cached_file(&tempfile_newdata);
+        goto err;
+      }
+
+      table->file->ha_end_keyread();
+
+      if (reinit_io_cache(&tempfile_newdata, READ_CACHE, 0L, 0, 0) ||
+          init_read_record(&info, thd, table, select, file_sort, 0, 1, FALSE))
+      {
+        error= 1;
+        close_cached_file(&tempfile_newdata);
+        goto err;
+      }
+
+      while (!(error= info.read_record(&info)) && !thd->killed)
+      {
+        explain->tracker.on_record_read();
+        table->file->position(table->record[0]);
+        store_record(table, record[1]);
+        if (my_b_read(&tempfile_newdata, table->record[0],
+                      table->s->reclength))
+        {
+          error= 1;
+          break;
+        }
+
+        error= send_update_to_engine(table, &limit, &updated, will_batch,
+                                     &dup_key_found);
+        if ((error= check_update_status(table, error, &updated, ignore)))
+        {
+          break;
+        }
+
+        if (table->triggers &&
+            table->triggers->process_triggers(thd, TRG_EVENT_UPDATE,
+                                              TRG_ACTION_AFTER, TRUE))
+        {
+          error= 1;
+          break;
+        }
+
+        if ((error= check_eof_or_limit(table, &limit, will_batch, using_limit,
+                                       &dup_key_found, &updated)))
+          break;
+
+        thd->get_stmt_da()->inc_current_row_for_warning();
+        if (thd->is_error())
+        {
+          error= 1;
+          break;
+        }
+      }
+    }
+    close_cached_file(&tempfile_newdata);
+  }
+
   ANALYZE_STOP_TRACKING(&explain->command_tracker);
   table->auto_increment_field_not_null= FALSE;
   dup_key_found= 0;
@@ -1110,26 +1239,6 @@ bool mysql_prepare_update(THD *thd, TABLE_LIST *table_list,
   DBUG_RETURN(FALSE);
 }
 
-/**
-  Check that we are not using table that we are updating in a sub select
-
-  @param thd             Thread handle
-  @param table_list      List of table with first to check
-
-  @retval TRUE  Error
-  @retval FALSE OK
-*/
-bool check_unique_table(THD *thd, TABLE_LIST *table_list)
-{
-  TABLE_LIST *duplicate;
-  DBUG_ENTER("check_unique_table");
-  if ((duplicate= unique_table(thd, table_list, table_list->next_global, 0)))
-  {
-    update_non_unique_table_error(table_list, "UPDATE", duplicate);
-    DBUG_RETURN(TRUE);
-  }
-  DBUG_RETURN(FALSE);
-}
 
 /***************************************************************************
   Update multiple tables from join 
