--- a/sql/sql_view.cc	Thu Mar 22 20:12:41 2007
+++ b/sql/sql_view.cc	Mon Apr 16 00:57:52 2007
@@ -1177,8 +1177,9 @@
       - VIEW SELECT allow merging
       - VIEW used in subquery or command support MERGE algorithm
     */
+    SELECT_LEX *table_select_lex= table->select_lex;
     if (view_is_mergeable &&
-        (table->select_lex->master_unit() != &old_lex->unit ||
+        (table_select_lex->master_unit() != &old_lex->unit ||
          old_lex->can_use_merged()) &&
         !old_lex->can_not_use_merged())
     {
@@ -1201,9 +1202,9 @@
       /* prepare view context */
       lex->select_lex.context.resolve_in_table_list_only(view_main_select_tables);
       lex->select_lex.context.outer_context= 0;
-      lex->select_lex.context.select_lex= table->select_lex;
+      lex->select_lex.context.select_lex= table_select_lex;
       lex->select_lex.select_n_having_items+=
-        table->select_lex->select_n_having_items;
+        table_select_lex->select_n_having_items;
 
       /*
         Tables of the main select of the view should be marked as belonging
@@ -1212,7 +1213,7 @@
         with unions).
       */
       for (tbl= lex->select_lex.get_table_list(); tbl; tbl= tbl->next_local)
-        tbl->select_lex= table->select_lex;
+        tbl->select_lex= table_select_lex;
 
       {
         if (view_main_select_tables->next_local)
@@ -1249,7 +1250,7 @@
 
         NOTE: we do not support UNION here, so we take only one select
       */
-      SELECT_LEX_NODE *end_unit= table->select_lex->slave;
+      SELECT_LEX_NODE *end_unit= table_select_lex->slave;
       SELECT_LEX_UNIT *next_unit;
       for (SELECT_LEX_UNIT *unit= lex->select_lex.first_inner_unit();
            unit;
@@ -1259,17 +1260,51 @@
           break;
         SELECT_LEX_NODE *save_slave= unit->slave;
         next_unit= unit->next_unit();
-        unit->include_down(table->select_lex);
+        unit->include_down(table_select_lex);
         unit->slave= save_slave; // fix include_down initialisation
       }
 
+      if (table_select_lex->linkage == UNION_TYPE
+          && table_select_lex->master_unit()->global_parameters == table_select_lex)
+      {
+        /*
+          Special case, if the view is used in an outer union, we must take care
+          not to push the order by conditions to the union.
+          If this is the last part of the outer union and if it was not contained
+          in braces, then global_parameters will point to this select_lex.
+          We can simply point them to the fake_select_lex, which exists for every
+          union
+        */
+        DBUG_ASSERT(table_select_lex->master_unit()->fake_select_lex);
+        table_select_lex->master_unit()->global_parameters=
+          table_select_lex->master_unit()->fake_select_lex;
+
+        /*
+          Any existing "order by" and "limit" belongs to the union.
+          Since global_parameters pointed to this select_lex, this is
+          the last part of the union
+        */
+        SELECT_LEX *global_lex= table_select_lex->master_unit()->global_parameters;
+        global_lex->order_list.push_back(&table_select_lex->order_list);
+        table_select_lex->init_order(); // will empty the list
+        global_lex->select_limit=   table_select_lex->select_limit;
+        global_lex->offset_limit=   table_select_lex->offset_limit;
+        global_lex->explicit_limit= table_select_lex->explicit_limit;
+        table_select_lex->select_limit=   0;
+        table_select_lex->offset_limit=   0;
+        table_select_lex->explicit_limit= 0;
+
+        // braces = true allows the union to ignore the order by, if no limit exists.
+        table_select_lex->set_braces(TRUE);
+      }
+      table_select_lex->order_list.push_back(&lex->select_lex.order_list);
+
       /*
-	This SELECT_LEX will be linked in global SELECT_LEX list
-	to make it processed by mysql_handle_derived(),
-	but it will not be included to SELECT_LEX tree, because it
-	will not be executed
+        This SELECT_LEX will be linked in global SELECT_LEX list
+        to make it processed by mysql_handle_derived(),
+        but it will not be included to SELECT_LEX tree, because it
+        will not be executed
       */
-      table->select_lex->order_list.push_back(&lex->select_lex.order_list);
       goto ok;
     }
 
--- a/mysql-test/t/view.test	Thu Mar  8 17:42:33 2007
+++ b/mysql-test/t/view.test	Mon Apr 16 01:10:49 2007
@@ -3204,3 +3204,87 @@
 DROP table t1,t2;
 
 --echo End of 5.0 tests.
+
+#
+#BUG#27786 Select from a view as part of a union could cause errors
+#
+# An "order by" of the view could incorrectly apply to the UNION
+# if the view was not in braces
+# 
+
+create table t1 (a int);
+insert into t1 values (10), (20), (20), (30);
+create table t2 (a int);
+insert into t2 values (5), (50);
+create table t3 (a int);
+insert into t3 values (10), (50);
+
+create view v1 as select a from t1 order by a;
+create view v2 as select a from t1 order by a desc;
+create view v3 as select a from t1 order by a limit 2;
+create view v4 as select a from t1 order by a desc limit 2;
+
+select a from t2 UNION select * from v1;
+select a from t2 UNION select * from v1 order by 1;
+select a from t2 UNION select * from v1 order by a desc;
+select a from t2 UNION select * from v1 order by a limit 2;
+select a from t2 UNION select * from v1 order by 1 desc limit 2;
+# "group by" still applies to the view
+# 10 is NOT grouped
+select a from t3 UNION ALL select * from v1;
+select a from t3 UNION ALL select * from v1 group by a;
+select a from t3 UNION ALL select * from v1 group by a order by 1;
+
+select * from v1 UNION select a from t2;
+select * from v1 UNION select a from t2 order by 1;
+select * from v1 UNION select a from t2 order by a desc;
+select * from v1 UNION select a from t2 order by a limit 2;
+select * from v1 UNION select a from t2 order by 1 desc limit 2;
+
+select * from v1 UNION select a from v1;
+select * from v1 UNION select a from v1 order by 1;
+select * from v1 UNION select a from v1 order by a desc;
+select * from v1 UNION select a from v1 order by a limit 2;
+select * from v1 UNION select a from v1 order by 1 desc limit 2;
+
+
+select a from t2 UNION select * from v2 order by 1;
+select a from t2 UNION select * from v2 order by a desc;
+select a from t2 UNION select * from v2 order by a limit 2;
+select a from t2 UNION select * from v2 order by 1 desc limit 2;
+
+select a from t3 UNION ALL select * from v2 order by 1;
+select a from t3 UNION ALL select * from v2 group by a order by 1;
+select a from t3 UNION ALL select * from v2 group by a order by a desc;
+
+select * from v2 UNION select a from v2 order by 1;
+select * from v2 UNION select a from v2 order by a desc;
+select * from v2 UNION select a from v2 order by a limit 2;
+select * from v2 UNION select a from v2 order by 1 desc limit 2;
+
+
+select a from t2 UNION select * from v3 order by 1;
+select a from t2 UNION select * from v3 order by a desc;
+select a from t2 UNION select * from v3 order by a limit 2;
+select a from t2 UNION select * from v3 order by 1 desc limit 2;
+
+select * from v3 UNION select a from v3 order by 1;
+select * from v3 UNION select a from v3 order by a desc;
+select * from v3 UNION select a from v3 order by a limit 2;
+select * from v3 UNION select a from v3 order by 1 desc limit 2;
+
+
+select a from t2 UNION select * from v4 order by 1;
+select a from t2 UNION select * from v4 order by a desc;
+select a from t2 UNION select * from v4 order by a limit 2;
+select a from t2 UNION select * from v4 order by 1 desc limit 2;
+
+select * from v4 UNION select a from v4 order by 1;
+select * from v4 UNION select a from v4 order by a desc;
+select * from v4 UNION select a from v4 order by a limit 2;
+select * from v4 UNION select a from v4 order by 1 desc limit 2;
+
+
+
+drop table t1,t2,t3;
+drop view v1,v2,v3,v4;
--- a/mysql-test/r/view.result	Fri Mar  9 09:37:05 2007
+++ b/mysql-test/r/view.result	Mon Apr 16 01:11:03 2007
@@ -3310,3 +3310,252 @@
 DROP VIEW v1;
 DROP table t1,t2;
 End of 5.0 tests.
+create table t1 (a int);
+insert into t1 values (10), (20), (20), (30);
+create table t2 (a int);
+insert into t2 values (5), (50);
+create table t3 (a int);
+insert into t3 values (10), (50);
+create view v1 as select a from t1 order by a;
+create view v2 as select a from t1 order by a desc;
+create view v3 as select a from t1 order by a limit 2;
+create view v4 as select a from t1 order by a desc limit 2;
+select a from t2 UNION select * from v1;
+a
+5
+50
+10
+20
+30
+select a from t2 UNION select * from v1 order by 1;
+a
+5
+10
+20
+30
+50
+select a from t2 UNION select * from v1 order by a desc;
+a
+50
+30
+20
+10
+5
+select a from t2 UNION select * from v1 order by a limit 2;
+a
+5
+10
+select a from t2 UNION select * from v1 order by 1 desc limit 2;
+a
+50
+30
+select a from t3 UNION ALL select * from v1;
+a
+10
+50
+10
+20
+20
+30
+select a from t3 UNION ALL select * from v1 group by a;
+a
+10
+50
+10
+20
+30
+select a from t3 UNION ALL select * from v1 group by a order by 1;
+a
+10
+10
+20
+30
+50
+select * from v1 UNION select a from t2;
+a
+10
+20
+30
+5
+50
+select * from v1 UNION select a from t2 order by 1;
+a
+5
+10
+20
+30
+50
+select * from v1 UNION select a from t2 order by a desc;
+a
+50
+30
+20
+10
+5
+select * from v1 UNION select a from t2 order by a limit 2;
+a
+5
+10
+select * from v1 UNION select a from t2 order by 1 desc limit 2;
+a
+50
+30
+select * from v1 UNION select a from v1;
+a
+10
+20
+30
+select * from v1 UNION select a from v1 order by 1;
+a
+10
+20
+30
+select * from v1 UNION select a from v1 order by a desc;
+a
+30
+20
+10
+select * from v1 UNION select a from v1 order by a limit 2;
+a
+10
+20
+select * from v1 UNION select a from v1 order by 1 desc limit 2;
+a
+30
+20
+select a from t2 UNION select * from v2 order by 1;
+a
+5
+10
+20
+30
+50
+select a from t2 UNION select * from v2 order by a desc;
+a
+50
+30
+20
+10
+5
+select a from t2 UNION select * from v2 order by a limit 2;
+a
+5
+10
+select a from t2 UNION select * from v2 order by 1 desc limit 2;
+a
+50
+30
+select a from t3 UNION ALL select * from v2 order by 1;
+a
+10
+10
+20
+20
+30
+50
+select a from t3 UNION ALL select * from v2 group by a order by 1;
+a
+10
+10
+20
+30
+50
+select a from t3 UNION ALL select * from v2 group by a order by a desc;
+a
+50
+30
+20
+10
+10
+select * from v2 UNION select a from v2 order by 1;
+a
+10
+20
+30
+select * from v2 UNION select a from v2 order by a desc;
+a
+30
+20
+10
+select * from v2 UNION select a from v2 order by a limit 2;
+a
+10
+20
+select * from v2 UNION select a from v2 order by 1 desc limit 2;
+a
+30
+20
+select a from t2 UNION select * from v3 order by 1;
+a
+5
+10
+20
+50
+select a from t2 UNION select * from v3 order by a desc;
+a
+50
+20
+10
+5
+select a from t2 UNION select * from v3 order by a limit 2;
+a
+5
+10
+select a from t2 UNION select * from v3 order by 1 desc limit 2;
+a
+50
+20
+select * from v3 UNION select a from v3 order by 1;
+a
+10
+20
+select * from v3 UNION select a from v3 order by a desc;
+a
+20
+10
+select * from v3 UNION select a from v3 order by a limit 2;
+a
+10
+20
+select * from v3 UNION select a from v3 order by 1 desc limit 2;
+a
+20
+10
+select a from t2 UNION select * from v4 order by 1;
+a
+5
+20
+30
+50
+select a from t2 UNION select * from v4 order by a desc;
+a
+50
+30
+20
+5
+select a from t2 UNION select * from v4 order by a limit 2;
+a
+5
+20
+select a from t2 UNION select * from v4 order by 1 desc limit 2;
+a
+50
+30
+select * from v4 UNION select a from v4 order by 1;
+a
+20
+30
+select * from v4 UNION select a from v4 order by a desc;
+a
+30
+20
+select * from v4 UNION select a from v4 order by a limit 2;
+a
+20
+30
+select * from v4 UNION select a from v4 order by 1 desc limit 2;
+a
+30
+20
+drop table t1,t2,t3;
+drop view v1,v2,v3,v4;
