diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result
index c41434336e52f23f0a3397093aa6d72ddbf3b04c..80b536bcac6079de9c28c2b90ce48165072d3a15 100644
--- a/mysql-test/r/subselect.result
+++ b/mysql-test/r/subselect.result
@@ -1151,3 +1151,16 @@ INSERT INTO t1 VALUES (1,0,NULL,NULL),(2,0,NULL,NULL);
 SELECT DISTINCT REF_ID FROM t1 WHERE ID= (SELECT DISTINCT REF_ID FROM t1 WHERE ID=2);
 REF_ID
 DROP TABLE t1;
+create table t1 (a int, b int);
+create table t2 (a int, b int);
+insert into t1 values (1,0), (2,0), (3,0);
+insert into t2 values (1,1), (2,1), (3,1), (2,2);
+update ignore t1 set b=(select b from t2 where t1.a=t2.a);
+Warnings:
+Error	1240	Subselect returns more than 1 record
+select * from t1;
+a	b
+1	1
+2	NULL
+3	1
+drop table t1, t2;
diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test
index 1528f53ff0d60681def4be25e931d4f236b222dd..0131c807b6889e03b191c981671d1be59136458b 100644
--- a/mysql-test/t/subselect.test
+++ b/mysql-test/t/subselect.test
@@ -732,3 +732,17 @@ CREATE TABLE t1 (
 INSERT INTO t1 VALUES (1,0,NULL,NULL),(2,0,NULL,NULL);
 SELECT DISTINCT REF_ID FROM t1 WHERE ID= (SELECT DISTINCT REF_ID FROM t1 WHERE ID=2);
 DROP TABLE t1;
+
+#
+# uninterruptable update
+#
+create table t1 (a int, b int);
+create table t2 (a int, b int);
+
+insert into t1 values (1,0), (2,0), (3,0);
+insert into t2 values (1,1), (2,1), (3,1), (2,2);
+
+update ignore t1 set b=(select b from t2 where t1.a=t2.a);
+select * from t1;
+
+drop table t1, t2;
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index 11f218341bd5a2cc61b4cf5ece4c529e03007b24..cd78edfee7b5824fed8d33221fe040700432ca37 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -824,6 +824,8 @@ int subselect_single_select_engine::exec()
 {
   DBUG_ENTER("subselect_single_select_engine::exec");
   char const *save_where= join->thd->where;
+  SELECT_LEX_NODE *save_select= join->thd->lex.current_select;
+  join->thd->lex.current_select= select_lex;
   if (!optimized)
   {
     optimized=1;
@@ -831,6 +833,7 @@ int subselect_single_select_engine::exec()
     {
       join->thd->where= save_where;
       executed= 1;
+      join->thd->lex.current_select= save_select;
       DBUG_RETURN(join->error?join->error:1);
     }
   }
@@ -839,6 +842,7 @@ int subselect_single_select_engine::exec()
     if (join->reinit())
     {
       join->thd->where= save_where;
+      join->thd->lex.current_select= save_select;
       DBUG_RETURN(1);
     }
     item->reset();
@@ -846,15 +850,14 @@ int subselect_single_select_engine::exec()
   }
   if (!executed)
   {
-    SELECT_LEX_NODE *save_select= join->thd->lex.current_select;
-    join->thd->lex.current_select= select_lex;
     join->exec();
-    join->thd->lex.current_select= save_select;
     executed= 1;
     join->thd->where= save_where;
+    join->thd->lex.current_select= save_select;
     DBUG_RETURN(join->error||thd->is_fatal_error);
   }
   join->thd->where= save_where;
+  join->thd->lex.current_select= save_select;
   DBUG_RETURN(0);
 }
 
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 68fa0cca2d56af2838a37f08fa390db417d69b56..ed4d683a9d5fdb6bbc6e23bd88e45fe521d2aeb6 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -1818,15 +1818,23 @@ extern "C" int my_message_sql(uint error, const char *str,
 {
   THD *thd;
   DBUG_ENTER("my_message_sql");
-  DBUG_PRINT("error",("Message: '%s'",str));
-  if ((thd=current_thd))
+  DBUG_PRINT("error", ("Message: '%s'", str));
+  if ((thd= current_thd))
   {
-    NET *net= &thd->net;
-    net->report_error= 1;
-    if (!net->last_error[0])			// Return only first message
+    if (thd->lex.current_select->no_error && !thd->is_fatal_error)
     {
-      strmake(net->last_error,str,sizeof(net->last_error)-1);
-      net->last_errno=error ? error : ER_UNKNOWN_ERROR;
+      DBUG_PRINT("error", ("above error converted to warning"));
+      push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, error, str);
+    }
+    else
+    {
+      NET *net= &thd->net;
+      net->report_error= 1;
+      if (!net->last_error[0])			// Return only first message
+      {
+	strmake(net->last_error, str, sizeof(net->last_error)-1);
+	net->last_errno= error ? error : ER_UNKNOWN_ERROR;
+      }
     }
   }
   else
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index bc9ad4f36b06bdd84a2dc20dff1609c62a32b807..78f981d77593d9453048a366aef71d1c6296d980 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -122,6 +122,7 @@ LEX *lex_start(THD *thd, uchar *buf,uint length)
   lex->yacc_yyss=lex->yacc_yyvs=0;
   lex->ignore_space=test(thd->variables.sql_mode & MODE_IGNORE_SPACE);
   lex->sql_command=SQLCOM_END;
+  lex->duplicates= DUP_ERROR;
   return lex;
 }
 
@@ -965,7 +966,7 @@ void st_select_lex_node::init_query()
 {
   options= 0;
   linkage= UNSPECIFIED_TYPE;
-  no_table_names_allowed= uncacheable= dependent= 0;
+  no_error= no_table_names_allowed= uncacheable= dependent= 0;
   ref_pointer_array= 0;
 }
 
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index 6226fbe1bb592414ca053bfba67352afbe375946..4844cb95f8616963b91ac0e2d93c580269cfdf3f 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -212,6 +212,7 @@ class st_select_lex_node {
   bool dependent;	/* dependent from outer select subselect */
   bool uncacheable;     /* result of this query can't be cached */
   bool no_table_names_allowed; /* used for global order by */
+  bool no_error; /* suppress error message (convert it to warnings) */
 
   static void *operator new(size_t size)
   {
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index b8eb9e19cc79fb1b300d2a514396e91be2648901..02e502f0ba6818164f5a0bc36cbb553d8776f39e 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -436,6 +436,9 @@ JOIN::optimize()
     DBUG_RETURN(0);
   optimized= 1;
 
+  // Ignore errors of execution if option IGNORE present
+  if (thd->lex.duplicates == DUP_IGNORE)
+    thd->lex.current_select->no_error= 1;
 #ifdef HAVE_REF_TO_FIELDS			// Not done yet
   /* Add HAVING to WHERE if possible */
   if (having && !group_list && !sum_func_count)