=== modified file 'mysql-test/r/having.result'
--- mysql-test/r/having.result	2014-05-09 10:35:11 +0000
+++ mysql-test/r/having.result	2015-01-13 18:38:17 +0000
@@ -677,4 +677,35 @@
 c1	c2
 x	x
 DROP TABLE t1,t2;
+#
+# Bug MDEV-7301: Unknown column quoted with backticks in HAVING clause when using function.
+# Bug#16221433 MYSQL REJECTS QUERY DUE TO BAD RESOLUTION OF NAMES IN HAVING; VIEW UNREADABLE
+#
+CREATE TABLE `t1` (
+`id` int(11) NOT NULL,
+`title` varchar(45) DEFAULT NULL,
+PRIMARY KEY (`id`)
+) DEFAULT CHARSET=utf8;
+INSERT INTO `t1` VALUES ('1', 'Just for fun');
+INSERT INTO `t1` VALUES ('2', 'Wait until a sunhine');
+INSERT INTO `t1` VALUES ('3', 'Take a new turn');
+SELECT `id`, SHA1(`title`) AS `column_1`
+FROM `t1`
+HAVING `column_1` LIKE '8%';
+id	column_1
+1	80a12660d24a72460e5e292fe33f870276d7f40a
+expected 1 row(s) returned
+SELECT `id`, SHA1(`title`) AS `column_1`
+FROM `t1`
+HAVING UPPER(column_1) LIKE '8%';
+id	column_1
+1	80a12660d24a72460e5e292fe33f870276d7f40a
+expected -- 1 row(s) returned
+SELECT `id`, SHA1(`title`) AS `column_1`
+FROM `t1`
+HAVING UPPER(`column_1`) LIKE '8%';
+id	column_1
+1	80a12660d24a72460e5e292fe33f870276d7f40a
+expected -- 1 row(s) returned not ER_BAD_FIELD_ERROR
+drop table t1;
 End of 10.0 tests

=== modified file 'mysql-test/t/having.test'
--- mysql-test/t/having.test	2014-05-09 10:35:11 +0000
+++ mysql-test/t/having.test	2015-01-13 18:38:17 +0000
@@ -707,5 +707,40 @@
 
 DROP TABLE t1,t2;
 
+--echo #
+--echo # Bug MDEV-7301: Unknown column quoted with backticks in HAVING clause when using function.
+--echo # Bug#16221433 MYSQL REJECTS QUERY DUE TO BAD RESOLUTION OF NAMES IN HAVING; VIEW UNREADABLE
+--echo #
+
+CREATE TABLE `t1` (
+  `id` int(11) NOT NULL,
+  `title` varchar(45) DEFAULT NULL,
+  PRIMARY KEY (`id`)
+) DEFAULT CHARSET=utf8;
+
+INSERT INTO `t1` VALUES ('1', 'Just for fun');
+INSERT INTO `t1` VALUES ('2', 'Wait until a sunhine');
+INSERT INTO `t1` VALUES ('3', 'Take a new turn');
+
+SELECT `id`, SHA1(`title`) AS `column_1`
+FROM `t1`
+HAVING `column_1` LIKE '8%';
+
+--echo expected 1 row(s) returned
+
+SELECT `id`, SHA1(`title`) AS `column_1`
+FROM `t1`
+HAVING UPPER(column_1) LIKE '8%';
+
+--echo expected -- 1 row(s) returned
+
+SELECT `id`, SHA1(`title`) AS `column_1`
+FROM `t1`
+HAVING UPPER(`column_1`) LIKE '8%';
+
+--echo expected -- 1 row(s) returned not ER_BAD_FIELD_ERROR
+
+drop table t1;
+
 --echo End of 10.0 tests
 

=== modified file 'sql/item.cc'
--- sql/item.cc	2014-10-09 08:30:11 +0000
+++ sql/item.cc	2015-01-13 18:38:17 +0000
@@ -5129,11 +5129,20 @@
     table_list= (cached_table ? cached_table :
                  from_field != view_ref_found ?
                  from_field->table->pos_in_table_list : 0);
-    if (!outer_fixed && table_list && table_list->select_lex &&
-        context->select_lex &&
+    /*
+      We should resolve this as an outer field reference if
+      1. we haven't done it before, and
+      2. the select_lex of the table that contains this field is
+         different from the select_lex of the current name resolution
+         context.
+      3. is_merged_child_of
+      4. is_outer_table
+    */
+    if (!outer_fixed &&                                                     // 1
+	table_list && table_list->select_lex && context->select_lex &&      // 2
         table_list->select_lex != context->select_lex &&
-        !context->select_lex->is_merged_child_of(table_list->select_lex) &&
-        is_outer_table(table_list, context->select_lex))
+	!context->select_lex->is_merged_child_of(table_list->select_lex) && // 3
+	is_outer_table(table_list, context->select_lex))                    // 4
     {
       int ret;
       if ((ret= fix_outer_field(thd, &from_field, reference)) < 0)

=== modified file 'sql/sql_parse.cc'
--- sql/sql_parse.cc	2014-11-03 16:47:37 +0000
+++ sql/sql_parse.cc	2015-01-13 18:38:17 +0000
@@ -7163,6 +7163,9 @@
     left_op->first_leaf_for_name_resolution();
   on_context->last_name_resolution_table=
     right_op->last_leaf_for_name_resolution();
+  // Save join nest's context in right_op, to find it later in view merging.
+  DBUG_ASSERT(right_op->context_of_embedding == NULL);
+  right_op->context_of_embedding= on_context;
   return thd->lex->push_context(on_context);
 }
 

=== modified file 'sql/sql_view.cc'
--- sql/sql_view.cc	2014-09-30 17:31:14 +0000
+++ sql/sql_view.cc	2015-01-13 18:38:17 +0000
@@ -1011,7 +1011,33 @@
   DBUG_RETURN(error);
 }
 
+/**
+   Go through a list of tables and join nests, recursively, and if they have
+   the name_resolution_context which points to removed_select, repoint it to
+   parent_select.
+   The select_lex pointer of the join nest is also repointed.
 
+   @param  join_list  List of tables and join nests
+   @param  removed_select  select_lex which is removed (merged into
+   parent_lex)
+   @param  parent_select
+ */
+void repoint_contexts_of_join_nests(List<TABLE_LIST> join_list,
+                                    SELECT_LEX *removed_select,
+                                    SELECT_LEX *parent_select)
+{
+  List_iterator_fast<TABLE_LIST> ti(join_list);
+  TABLE_LIST *tbl;
+  while ((tbl= ti++))
+  {
+    if (tbl->context_of_embedding &&
+        tbl->context_of_embedding->select_lex == removed_select)
+      tbl->context_of_embedding->select_lex= parent_select;
+    if (tbl->nested_join)
+      repoint_contexts_of_join_nests(tbl->nested_join->join_list,
+                                     removed_select, parent_select);
+  }
+}
 
 /*
   read VIEW .frm and create structures
@@ -1510,6 +1536,14 @@
       /* prepare view context */
       lex->select_lex.context.resolve_in_table_list_only(view_main_select_tables);
       lex->select_lex.context.outer_context= 0;
+      /*
+        Correct all name resolution contexts which point to the view's
+        select_lex.
+      */
+      repoint_contexts_of_join_nests(view_select->top_join_list,
+                                     view_select,
+                                     table->select_lex);
+
       lex->select_lex.select_n_having_items+=
         table->select_lex->select_n_having_items;
 

=== modified file 'sql/table.h'
--- sql/table.h	2014-11-13 12:40:11 +0000
+++ sql/table.h	2015-01-13 18:38:17 +0000
@@ -1665,6 +1665,7 @@
   4) jtbm semi-join (jtbm_subselect != NULL)
 */
 
+struct Name_resolution_context;
 struct LEX;
 class Index_hint;
 struct TABLE_LIST
@@ -1706,6 +1707,13 @@
   char		*db, *alias, *table_name, *schema_table_name;
   char          *option;                /* Used by cache index  */
   Item		*on_expr;		/* Used with outer join */
+  /**
+     Context which should be used to resolve identifiers contained in the ON
+     condition of the embedding join nest.
+     @todo When name resolution contexts are created after parsing, we should
+     be able to store this in the embedding join nest instead.
+  */
+  Name_resolution_context *context_of_embedding;
 
   Item          *sj_on_expr;
   /*

=== modified file 'sql/sql_yacc.yy'
--- sql/sql_yacc.yy	2014-11-19 16:23:39 +0000
+++ sql/sql_yacc.yy	2015-01-13 19:47:09 +0000
@@ -10105,7 +10105,8 @@
                parse it out. If we hijack the input stream with
                remember_name we may get quoted or escaped names.
             */
-            else if ($2->type() != Item::FIELD_ITEM)
+            else if ($2->type() != Item::FIELD_ITEM &&
+                     $2->type() != Item::REF_ITEM /* For HAVING */ )
               $2->set_name($1, (uint) ($3 - $1), thd->charset());
             $$= $2;
           }
