diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index 59bae19123001aee2f63f42adb42658f18383e6a..7c9b43f23b9208ab6b17cc4762d0e3d47910b8e6 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -1066,7 +1066,8 @@ TABLE_LIST *find_table_in_list(TABLE_LIST *table,
                                st_table_list *TABLE_LIST::*link,
                                const char *db_name,
                                const char *table_name);
-TABLE_LIST *unique_table(THD *thd, TABLE_LIST *table, TABLE_LIST *table_list);
+TABLE_LIST *unique_table(THD *thd, TABLE_LIST *table, TABLE_LIST *table_list,
+                         bool check_alias);
 TABLE **find_temporary_table(THD *thd, const char *db, const char *table_name);
 bool close_temporary_table(THD *thd, const char *db, const char *table_name);
 void close_temporary(TABLE *table, bool delete_table);
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 630d135be48b2547a922d29e7488b61ac447b45b..86cb9f77703ba6ec125c76a7fd5faafef0550cdd 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -796,6 +796,7 @@ TABLE_LIST *find_table_in_list(TABLE_LIST *table,
     thd                   thread handle
     table                 table which should be checked
     table_list            list of tables
+    check_alias           whether to check tables' aliases
 
   NOTE: to exclude derived tables from check we use following mechanism:
     a) during derived table processing set THD::derived_tables_processing
@@ -823,10 +824,11 @@ TABLE_LIST *find_table_in_list(TABLE_LIST *table,
     0 if table is unique
 */
 
-TABLE_LIST* unique_table(THD *thd, TABLE_LIST *table, TABLE_LIST *table_list)
+TABLE_LIST* unique_table(THD *thd, TABLE_LIST *table, TABLE_LIST *table_list,
+                         bool check_alias)
 {
   TABLE_LIST *res;
-  const char *d_name, *t_name;
+  const char *d_name, *t_name, *t_alias;
   DBUG_ENTER("unique_table");
   DBUG_PRINT("enter", ("table alias: %s", table->alias));
 
@@ -854,6 +856,7 @@ TABLE_LIST* unique_table(THD *thd, TABLE_LIST *table, TABLE_LIST *table_list)
   }
   d_name= table->db;
   t_name= table->table_name;
+  t_alias= table->alias;
 
   DBUG_PRINT("info", ("real table: %s.%s", d_name, t_name));
   for (;;)
@@ -861,6 +864,8 @@ TABLE_LIST* unique_table(THD *thd, TABLE_LIST *table, TABLE_LIST *table_list)
     if (((! (res= find_table_in_global_list(table_list, d_name, t_name))) &&
          (! (res= mysql_lock_have_duplicate(thd, table, table_list)))) ||
         ((!res->table || res->table != table->table) &&
+         (!check_alias || !(lower_case_table_names ?
+          strcasecmp(t_alias, res->alias) : strcmp(t_alias, res->alias))) &&
          res->select_lex && !res->select_lex->exclude_from_table_unique_test &&
          !res->prelocking_placeholder))
       break;
diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc
index 749ee04493b7cf29732e2da5687e72bc446c33b9..fe89f0f28f00170492781a6712952517e5bd160b 100644
--- a/sql/sql_delete.cc
+++ b/sql/sql_delete.cc
@@ -371,7 +371,7 @@ bool mysql_prepare_delete(THD *thd, TABLE_LIST *table_list, Item **conds)
   }
   {
     TABLE_LIST *duplicate;
-    if ((duplicate= unique_table(thd, table_list, table_list->next_global)))
+    if ((duplicate= unique_table(thd, table_list, table_list->next_global, 0)))
     {
       update_non_unique_table_error(table_list, "DELETE", duplicate);
       DBUG_RETURN(TRUE);
@@ -468,7 +468,7 @@ bool mysql_multi_delete_prepare(THD *thd)
     {
       TABLE_LIST *duplicate;
       if ((duplicate= unique_table(thd, target_tbl->correspondent_table,
-                                   lex->query_tables)))
+                                   lex->query_tables, 0)))
       {
         update_non_unique_table_error(target_tbl->correspondent_table,
                                       "DELETE", duplicate);
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index f1edfb9d7878b65ef32e64691e79d640a154eac8..e625aec4dde98e003743c4fe9d75fbdd1615299e 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -1043,7 +1043,7 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
   {
     Item *fake_conds= 0;
     TABLE_LIST *duplicate;
-    if ((duplicate= unique_table(thd, table_list, table_list->next_global)))
+    if ((duplicate= unique_table(thd, table_list, table_list->next_global, 1)))
     {
       update_non_unique_table_error(table_list, "INSERT", duplicate);
       DBUG_RETURN(TRUE);
@@ -2423,7 +2423,7 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
     query
   */
   if (!(lex->current_select->options & OPTION_BUFFER_RESULT) &&
-      unique_table(thd, table_list, table_list->next_global))
+      unique_table(thd, table_list, table_list->next_global, 0))
   {
     /* Using same table for INSERT and SELECT */
     lex->current_select->options|= OPTION_BUFFER_RESULT;
diff --git a/sql/sql_load.cc b/sql/sql_load.cc
index 8aa3f96fb95482728159a054e2be851d9c130d84..4da861b83492822a0423eb74ec28c741ec1f2b8b 100644
--- a/sql/sql_load.cc
+++ b/sql/sql_load.cc
@@ -176,7 +176,7 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
     table is marked to be 'used for insert' in which case we should never
     mark this table as as 'const table' (ie, one that has only one row).
   */
-  if (unique_table(thd, table_list, table_list->next_global))
+  if (unique_table(thd, table_list, table_list->next_global, 0))
   {
     my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->table_name);
     DBUG_RETURN(TRUE);
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 614e2ce7b7260faae1b5ea8a188d7db5d34a2200..9e63fd7eb8d392287fda65712be10a32b5ed980d 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -2988,7 +2988,7 @@ mysql_execute_command(THD *thd)
         if (!(create_info.options & HA_LEX_CREATE_TMP_TABLE))
         {
           TABLE_LIST *duplicate;
-          if ((duplicate= unique_table(thd, create_table, select_tables)))
+          if ((duplicate= unique_table(thd, create_table, select_tables, 0)))
           {
             update_non_unique_table_error(create_table, "CREATE", duplicate);
             res= 1;
@@ -3004,7 +3004,7 @@ mysql_execute_command(THD *thd)
                tab= tab->next_local)
           {
             TABLE_LIST *duplicate;
-            if ((duplicate= unique_table(thd, tab, select_tables)))
+            if ((duplicate= unique_table(thd, tab, select_tables, 0)))
             {
               update_non_unique_table_error(tab, "CREATE", duplicate);
               res= 1;
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index 4858184557b7935ac0b4983c403e1668cc72cb50..89af15289701358fc262fea06d2d92d857a86792 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -640,7 +640,7 @@ bool mysql_prepare_update(THD *thd, TABLE_LIST *table_list,
   /* Check that we are not using table that we are updating in a sub select */
   {
     TABLE_LIST *duplicate;
-    if ((duplicate= unique_table(thd, table_list, table_list->next_global)))
+    if ((duplicate= unique_table(thd, table_list, table_list->next_global, 0)))
     {
       update_non_unique_table_error(table_list, "UPDATE", duplicate);
       my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->table_name);
@@ -867,7 +867,7 @@ reopen_tables:
         tl->lock_type != TL_READ_NO_INSERT)
     {
       TABLE_LIST *duplicate;
-      if ((duplicate= unique_table(thd, tl, table_list)))
+      if ((duplicate= unique_table(thd, tl, table_list, 0)))
       {
         update_non_unique_table_error(table_list, "UPDATE", duplicate);
         DBUG_RETURN(TRUE);
@@ -1086,7 +1086,7 @@ static bool safe_update_on_fly(THD *thd, JOIN_TAB *join_tab,
                                List<Item> *fields)
 {
   TABLE *table= join_tab->table;
-  if (unique_table(thd, table_ref, all_tables))
+  if (unique_table(thd, table_ref, all_tables, 0))
     return 0;
   switch (join_tab->type) {
   case JT_SYSTEM: