diff --git a/sql/item.cc b/sql/item.cc
index 4a04dc93a54e8f9abcd389aebde98d61a88f0085..62f7823d1e3faa3f0a06ce2bbe0a27b34ac98da2 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -23,7 +23,7 @@
 #include <m_ctype.h>
 #include "my_dir.h"
 
-static void mark_as_dependent(SELECT_LEX *last, SELECT_LEX_NODE *current,
+static void mark_as_dependent(SELECT_LEX *last, SELECT_LEX *current,
 			      Item_ident *item);
 
 /*****************************************************************************
@@ -809,7 +809,7 @@ bool Item_ref_null_helper::get_date(TIME *ltime, bool fuzzydate)
     item - item which should be marked
 */
 
-static void mark_as_dependent(SELECT_LEX *last, SELECT_LEX_NODE *current,
+static void mark_as_dependent(SELECT_LEX *last, SELECT_LEX *current,
 			      Item_ident *item)
 {
   // store pointer on SELECT_LEX from wich item is dependent
@@ -1413,7 +1413,7 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference)
   if (((*ref)->with_sum_func && name &&
        (depended_from ||
 	!(thd->lex.current_select->linkage != GLOBAL_OPTIONS_TYPE &&
-	  thd->lex.current_select->select_lex()->having_fix_field))) ||
+	  thd->lex.current_select->having_fix_field))) ||
       !(*ref)->fixed)
   {
     my_error(ER_ILLEGAL_REFERENCE, MYF(0), name, 
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index f29ac3b3c9c5dfe90a6585cf928fd61977796bce..d295e5c826171bbea56cc1cc1b0256acabb9851f 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -336,8 +336,8 @@ Item_exists_subselect::Item_exists_subselect(THD *thd,
 
 bool Item_in_subselect::test_limit(SELECT_LEX_UNIT *unit)
 {
-  if (unit->global_parameters == unit &&
-      unit->global_parameters->test_limit())
+  if (unit->fake_select_lex &&
+      unit->fake_select_lex->test_limit())
     return(1);
 
   SELECT_LEX *sl= unit->first_select();
@@ -495,7 +495,8 @@ Item_in_subselect::single_value_transformer(JOIN *join,
     SELECT_LEX_UNIT *unit= select_lex->master_unit();
     substitution= optimizer= new Item_in_optimizer(left_expr, this);
 
-    SELECT_LEX_NODE *current= thd->lex.current_select, *up;
+    SELECT_LEX *current= thd->lex.current_select, *up;
+
     thd->lex.current_select= up= current->return_after_parsing();
     //optimizer never use Item **ref => we can pass 0 as parameter
     if (!optimizer || optimizer->fix_left(thd, up->get_table_list(), 0))
@@ -658,7 +659,7 @@ Item_in_subselect::row_value_transformer(JOIN *join,
     SELECT_LEX_UNIT *unit= select_lex->master_unit();
     substitution= optimizer= new Item_in_optimizer(left_expr, this);
 
-    SELECT_LEX_NODE *current= thd->lex.current_select, *up;
+    SELECT_LEX *current= thd->lex.current_select, *up;
     thd->lex.current_select= up= current->return_after_parsing();
     //optimizer never use Item **ref => we can pass 0 as parameter
     if (!optimizer || optimizer->fix_left(thd, up->get_table_list(), 0))
@@ -771,7 +772,7 @@ int subselect_single_select_engine::prepare()
   if (prepared)
     return 0;
   prepared= 1;
-  SELECT_LEX_NODE *save_select= thd->lex.current_select;
+  SELECT_LEX *save_select= thd->lex.current_select;
   thd->lex.current_select= select_lex;
   if (join->prepare(&select_lex->ref_pointer_array,
 		    (TABLE_LIST*) select_lex->table_list.first,
@@ -876,7 +877,7 @@ 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;
+  SELECT_LEX *save_select= join->thd->lex.current_select;
   join->thd->lex.current_select= select_lex;
   if (!optimized)
   {
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index 67dffb35724d6b45ca1e0cb9d4b24bc65b805f63..4353427675975548ba8199c203770179a2345155 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -1114,7 +1114,7 @@ void Item_sum_count_distinct::make_unique()
 bool Item_sum_count_distinct::setup(THD *thd)
 {
   List<Item> list;
-  SELECT_LEX *select_lex= current_lex->current_select->select_lex();
+  SELECT_LEX *select_lex= current_lex->current_select;
   if (select_lex->linkage == GLOBAL_OPTIONS_TYPE)
     return 1;
     
@@ -1607,7 +1607,7 @@ Item_func_group_concat::Item_func_group_concat(bool is_distinct,
   original= 0;
   quick_group= 0;
   mark_as_sum_func();
-  SELECT_LEX *select_lex= current_lex->current_select->select_lex();
+  SELECT_LEX *select_lex= current_lex->current_select;
   order= 0;
     
   arg_show_fields= arg_count_field= is_select->elements;
@@ -1786,7 +1786,7 @@ Item_func_group_concat::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
 bool Item_func_group_concat::setup(THD *thd)
 {
   List<Item> list;
-  SELECT_LEX *select_lex= current_lex->current_select->select_lex();
+  SELECT_LEX *select_lex= current_lex->current_select;
 
   if (select_lex->linkage == GLOBAL_OPTIONS_TYPE)
     return 1;
diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc
index ebb09b99df7de9f1c1bb4e8056c312f643d0019b..876c4f9e67047cf861eb1e9a6f4160aefe06d6b4 100644
--- a/sql/sql_delete.cc
+++ b/sql/sql_delete.cc
@@ -304,7 +304,7 @@ multi_delete::initialize_tables(JOIN *join)
 				  table->file->ref_length,
 				  MEM_STRIP_BUF_SIZE);
   }
-  init_ftfuncs(thd, thd->lex.current_select->select_lex(), 1);
+  init_ftfuncs(thd, thd->lex.current_select, 1);
   DBUG_RETURN(thd->is_fatal_error != 0);
 }
 
diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc
index 0f8b9b96455a0ecfded7f78679ab893442a5dc59..92e37f95f0eda01a147ea68492003e22e0330cbc 100644
--- a/sql/sql_derived.cc
+++ b/sql/sql_derived.cc
@@ -74,7 +74,7 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit,
   bool is_union= select_cursor->next_select() && 
     select_cursor->next_select()->linkage == UNION_TYPE;
   bool is_subsel= select_cursor->first_inner_unit() ? 1: 0;
-  SELECT_LEX_NODE *save_current_select= lex->current_select;
+  SELECT_LEX *save_current_select= lex->current_select;
   DBUG_ENTER("mysql_derived");
   
   /*
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index 9b372f6eedaae84cfbae516adc1b4f3432571fd8..8e3d6df054089c51aa327050b1eb69b798666a29 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -966,27 +966,17 @@ void st_select_lex_node::init_query()
   options= 0;
   linkage= UNSPECIFIED_TYPE;
   no_table_names_allowed= uncacheable= dependent= 0;
-  ref_pointer_array= 0;
-  cond_count= 0;
 }
 
 void st_select_lex_node::init_select()
 {
-  order_list.elements= 0;
-  order_list.first= 0;
-  order_list.next= (byte**) &order_list.first;
-  select_limit= HA_POS_ERROR;
-  offset_limit= 0;
-  select_items= 0;
-  with_sum_func= 0;
-  parsing_place= SELECT_LEX_NODE::NO_MATTER;
 }
 
 void st_select_lex_unit::init_query()
 {
   st_select_lex_node::init_query();
   linkage= GLOBAL_OPTIONS_TYPE;
-  global_parameters= this;
+  global_parameters= first_select();
   select_limit_cnt= HA_POS_ERROR;
   offset_limit_cnt= 0;
   union_option= 0;
@@ -994,6 +984,7 @@ void st_select_lex_unit::init_query()
   item= 0;
   union_result= 0;
   table= 0;
+  fake_select_lex= 0;
 }
 
 void st_select_lex::init_query()
@@ -1005,7 +996,8 @@ void st_select_lex::init_query()
   where= 0;
   olap= UNSPECIFIED_OLAP_TYPE;
   insert_select= having_fix_field= 0;
-  with_wild= 0;
+  cond_count= with_wild= 0;
+  ref_pointer_array= 0;
 }
 
 void st_select_lex::init_select()
@@ -1027,6 +1019,14 @@ void st_select_lex::init_select()
   ftfunc_list_alloc.empty();
   ftfunc_list= &ftfunc_list_alloc;
   linkage= UNSPECIFIED_TYPE;
+  order_list.elements= 0;
+  order_list.first= 0;
+  order_list.next= (byte**) &order_list.first;
+  select_limit= HA_POS_ERROR;
+  offset_limit= 0;
+  select_items= 0;
+  with_sum_func= 0;
+  parsing_place= SELECT_LEX_NODE::NO_MATTER;
 }
 
 /*
@@ -1044,6 +1044,23 @@ void st_select_lex_node::include_down(st_select_lex_node *upper)
   slave= 0;
 }
 
+/*
+  include on level down (but do not link)
+  
+  SYNOPSYS
+    st_select_lex_node::include_standalone()
+    upper - reference on node underr which this node should be included
+    ref - references on reference on this node
+*/
+void st_select_lex_node::include_standalone(st_select_lex_node *upper,
+					    st_select_lex_node **ref)
+{
+  next= 0;
+  prev= ref;
+  master= upper;
+  slave= 0;
+}
+
 /* include neighbour (on same level) */
 void st_select_lex_node::include_neighbour(st_select_lex_node *before)
 {
@@ -1125,33 +1142,6 @@ void st_select_lex_unit::exclude_level()
     (*prev)= next;
 }
 
-st_select_lex* st_select_lex_node::select_lex()
-{
-  DBUG_ENTER("st_select_lex_node::select_lex (never should be called)");
-  DBUG_ASSERT(0);
-  DBUG_RETURN(0);
-}
-
-bool st_select_lex_node::add_item_to_list(THD *thd, Item *item)
-{
-  return 1;
-}
-
-bool st_select_lex_node::add_group_to_list(THD *thd, Item *item, bool asc)
-{
-  return 1;
-}
-
-bool st_select_lex_node::add_order_to_list(THD *thd, Item *item, bool asc)
-{
-  return add_to_list(thd, order_list, item, asc);
-}
-
-bool st_select_lex_node::add_ftfunc_to_list(Item_func_match *func)
-{
-  return 1;
-}
-
 /*
   st_select_lex_node::mark_as_dependent mark all st_select_lex struct from 
   this to 'last' as dependent
@@ -1165,31 +1155,26 @@ bool st_select_lex_node::add_ftfunc_to_list(Item_func_match *func)
 
 */
 
-void st_select_lex_node::mark_as_dependent(SELECT_LEX *last)
+void st_select_lex::mark_as_dependent(SELECT_LEX *last)
 {
   /*
     Mark all selects from resolved to 1 before select where was
     found table as depended (of select where was found table)
   */
-  for (SELECT_LEX_NODE *s= this;
+  for (SELECT_LEX *s= this;
        s &&s != last;
        s= s->outer_select())
     if ( !s->dependent )
     {
       // Select is dependent of outer select
       s->dependent= 1;
-      if (s->linkage != GLOBAL_OPTIONS_TYPE)
-      { 
-	//s is st_select_lex*
-
-	s->master_unit()->dependent= 1;
-	//Tables will be reopened many times
-	for (TABLE_LIST *tbl=
-	       s->get_table_list();
-	     tbl;
-	     tbl= tbl->next)
-	  tbl->shared= 1;
-      }
+      s->master_unit()->dependent= 1;
+      //Tables will be reopened many times
+      for (TABLE_LIST *tbl=
+	     s->get_table_list();
+	   tbl;
+	   tbl= tbl->next)
+	tbl->shared= 1;
     }
 }
 
@@ -1200,15 +1185,6 @@ TABLE_LIST* st_select_lex_node::get_table_list()     { return 0; }
 List<Item>* st_select_lex_node::get_item_list()      { return 0; }
 List<String>* st_select_lex_node::get_use_index()    { return 0; }
 List<String>* st_select_lex_node::get_ignore_index() { return 0; }
-TABLE_LIST *st_select_lex_node::add_table_to_list(THD *thd, Table_ident *table,
-						  LEX_STRING *alias,
-						  ulong table_join_options,
-						  thr_lock_type flags,
-						  List<String> *use_index,
-						  List<String> *ignore_index)
-{
-  return 0;
-}
 
 ulong st_select_lex_node::get_table_join_options()
 {
@@ -1218,7 +1194,7 @@ ulong st_select_lex_node::get_table_join_options()
 /*
   prohibit using LIMIT clause
 */
-bool st_select_lex_node::test_limit()
+bool st_select_lex::test_limit()
 {
   if (select_limit != HA_POS_ERROR)
   {
@@ -1293,22 +1269,39 @@ bool st_select_lex_unit::create_total_list_n_last_return(THD *thd, st_lex *lex,
   TABLE_LIST *slave_list_first=0, **slave_list_last= &slave_list_first;
   TABLE_LIST **new_table_list= *result, *aux;
   SELECT_LEX *sl= (SELECT_LEX*)slave;
-  for (; sl; sl= sl->next_select())
+  
+  /*
+    iterate all inner selects + fake_select (if exists),
+    fake_select->next_select() always is 0
+  */
+  for (;
+       sl;
+       sl= (sl->next_select() ?
+	    sl->next_select() :
+	    (sl == fake_select_lex ?
+	     0 :
+	     fake_select_lex)))
   {
     // check usage of ORDER BY in union
-    if (sl->order_list.first && sl->next_select() && !sl->braces)
+    if (sl->order_list.first && sl->next_select() && !sl->braces &&
+	sl->linkage != GLOBAL_OPTIONS_TYPE)
     {
       net_printf(thd,ER_WRONG_USAGE,"UNION","ORDER BY");
       return 1;
     }
+
     if (sl->linkage == DERIVED_TABLE_TYPE && !check_derived)
-      continue;
+      goto end;
+
     for (SELECT_LEX_UNIT *inner=  sl->first_inner_unit();
 	 inner;
 	 inner= inner->next_unit())
+    {
       if (inner->create_total_list_n_last_return(thd, lex,
 						 &slave_list_last, 0))
 	return 1;
+    }
+
     if ((aux= (TABLE_LIST*) sl->table_list.first))
     {
       TABLE_LIST *next;
@@ -1342,6 +1335,7 @@ bool st_select_lex_unit::create_total_list_n_last_return(THD *thd, st_lex *lex,
       }
     }
   }
+end:
   if (slave_list_first)
   {
     *new_table_list= slave_list_first;
@@ -1361,9 +1355,9 @@ st_select_lex* st_select_lex_unit::outer_select()
   return (st_select_lex*) master;
 }
 
-st_select_lex* st_select_lex::select_lex()
+bool st_select_lex::add_order_to_list(THD *thd, Item *item, bool asc)
 {
-  return this;
+  return add_to_list(thd, order_list, item, asc);
 }
 
 bool st_select_lex::add_item_to_list(THD *thd, Item *item)
@@ -1433,18 +1427,6 @@ ulong st_select_lex::get_table_join_options()
   return table_join_options;
 }
 
-st_select_lex::st_select_lex(struct st_lex *lex)
-  :fake_select(0)
-{
-  select_number= ++lex->thd->select_number;
-  init_query();
-  init_select();
-  include_neighbour(lex->current_select);
-  include_global((st_select_lex_node**)&lex->all_selects_list);
-  lex->current_select= this;
-}
-
-
 /*
   There are st_select_lex::add_table_to_list & 
   st_select_lex::set_lock_for_tables in sql_parse.cc
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index a48aa5721e481824bc88778bf9646f2aa02021df..adf452376a74ddfb674490bddb2060c972a60ada 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -118,6 +118,12 @@ enum olap_type
        subselects or derived tables) for ordinary select_lex
    - list of all select_lex (for group operation like correcting list of opened
      tables)
+   - if unit contain several selects (union) then it have special 
+     select_lex called fake_select_lex. It used for storing global parameters
+     and executing union. subqueries of global ORDER BY clause will be
+     attached to this fake_select_lex, which will allow them correctly
+     resolve fields of 'upper' union and other more outer selects. 
+
    for example for following query:
 
    select *
@@ -138,6 +144,7 @@ enum olap_type
 
 
      main unit
+     fake0
      select1 select2 select3
      |^^     |^
     s|||     ||master
@@ -146,7 +153,8 @@ enum olap_type
     v|||master                         slave   ||
     e||+-------------------------+             ||
      V|            neighbor      |             V|
-     unit 1.1<==================>unit1.2       unit2.1
+     unit1.1<+==================>unit1.2       unit2.1
+     fake1.1                                   fake2.1
      select1.1.1 select 1.1.2    select1.2.1   select2.1.1 select2.1.2
                                                |^
                                                ||
@@ -158,13 +166,14 @@ enum olap_type
    relation in main unit will be following:
                           
          main unit
-         |^^^
-         ||||
-         |||+------------------------------+
-         ||+--------------+                |
-    slave||master         |                |
-         V|      neighbor |       neighbor |
-         select1<========>select2<========>select3
+         |^^^^|fake_select_lex
+         |||||+--------------------------------------------+
+         ||||+--------------------------------------------+|
+         |||+------------------------------+              ||
+         ||+--------------+                |              ||
+    slave||master         |                |              ||
+         V|      neighbor |       neighbor |        master|V
+         select1<========>select2<========>select3        fake0
 
     list of all select_lex will be following (as it will be constructed by
     parser):
@@ -199,17 +208,6 @@ public:
 
   ulong options;
   enum sub_select_type linkage;
-  SQL_LIST order_list;                /* ORDER clause */
-  List<List_item>     expr_list;
-  List<List_item>     when_list;      /* WHEN clause (expression) */
-  ha_rows select_limit, offset_limit; /* LIMIT clause parameters */
-  // Arrays of pointers to top elements of all_fields list
-  Item **ref_pointer_array;
-
-  uint select_items;    /* number of items in select_list */
-  uint cond_count;      /* number of arguments of and/or/xor in where/having */
-  enum_parsing_place parsing_place; /* where we are parsing expression */
-  bool with_sum_func;   /* sum function indicator */
   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 */
@@ -226,18 +224,13 @@ public:
   virtual void init_select();
   void include_down(st_select_lex_node *upper);
   void include_neighbour(st_select_lex_node *before);
+  void include_standalone(st_select_lex_node *sel, st_select_lex_node **ref);
   void include_global(st_select_lex_node **plink);
   void exclude();
 
-  virtual st_select_lex* select_lex();
-  virtual bool add_item_to_list(THD *thd, Item *item);
-  bool add_order_to_list(THD *thd, Item *item, bool asc);
-  virtual bool add_group_to_list(THD *thd, Item *item, bool asc);
-  virtual bool add_ftfunc_to_list(Item_func_match *func);
-
   virtual st_select_lex_unit* master_unit()= 0;
   virtual st_select_lex* outer_select()= 0;
-  virtual st_select_lex_node* return_after_parsing()= 0;
+  virtual st_select_lex* return_after_parsing()= 0;
 
   virtual bool set_braces(bool value);
   virtual bool inc_in_sum_expr();
@@ -247,16 +240,7 @@ public:
   virtual List<String>* get_use_index();
   virtual List<String>* get_ignore_index();
   virtual ulong get_table_join_options();
-  virtual TABLE_LIST *add_table_to_list(THD *thd, Table_ident *table,
-					LEX_STRING *alias,
-					ulong table_options,
-					thr_lock_type flags= TL_UNLOCK,
-					List<String> *use_index= 0,
-					List<String> *ignore_index= 0);
   virtual void set_lock_for_tables(thr_lock_type lock_type) {}
-  void mark_as_dependent(st_select_lex *last);
-
-  bool test_limit();
 
   friend class st_select_lex_unit;
   friend bool mysql_new_select(struct st_lex *lex, bool move_down);
@@ -293,14 +277,17 @@ public:
     Pointer to 'last' select or pointer to unit where stored
     global parameters for union
   */
-  st_select_lex_node *global_parameters;
+  st_select_lex *global_parameters;
   //node on wich we should return current_select pointer after parsing subquery
-  st_select_lex_node *return_to;
+  st_select_lex *return_to;
   /* LIMIT clause runtime counters */
   ha_rows select_limit_cnt, offset_limit_cnt;
   /* not NULL if union used in subselect, point to subselect item */
   Item_subselect *item;
+  /* thread handler */
   THD *thd;
+  /* fake SELECT_LEX for union processing */
+  st_select_lex *fake_select_lex;
 
   uint union_option;
 
@@ -312,11 +299,10 @@ public:
   st_select_lex* first_select() { return (st_select_lex*) slave; }
   st_select_lex* first_select_in_union() 
   { 
-    return (slave && slave->linkage == GLOBAL_OPTIONS_TYPE) ?
-      (st_select_lex*) slave->next : (st_select_lex*) slave;
+    return (st_select_lex*) slave;
   }
   st_select_lex_unit* next_unit() { return (st_select_lex_unit*) next; }
-  st_select_lex_node* return_after_parsing() { return return_to; }
+  st_select_lex* return_after_parsing() { return return_to; }
   void exclude_level();
 
   /* UNION methods */
@@ -354,6 +340,19 @@ public:
   List<Item_func_match> ftfunc_list_alloc;
   JOIN *join; /* after JOIN::prepare it is pointer to corresponding JOIN */
   const char *type; /* type of select for EXPLAIN */
+
+  SQL_LIST order_list;                /* ORDER clause */
+  List<List_item>     expr_list;
+  List<List_item>     when_list;      /* WHEN clause (expression) */
+  ha_rows select_limit, offset_limit; /* LIMIT clause parameters */
+  // Arrays of pointers to top elements of all_fields list
+  Item **ref_pointer_array;
+
+  uint select_items;    /* number of items in select_list */
+  uint cond_count;      /* number of arguments of and/or/xor in where/having */
+  enum_parsing_place parsing_place; /* where we are parsing expression */
+  bool with_sum_func;   /* sum function indicator */
+
   ulong table_join_options;
   uint in_sum_expr;
   uint select_number; /* number of select (used for EXPLAIN) */
@@ -369,8 +368,6 @@ public:
      before passing to handle_select)
   */
   bool insert_select;
-  /* TRUE for fake select, which used in UNION processing */
-  bool fake_select;
 
   void init_query();
   void init_select();
@@ -389,31 +386,33 @@ public:
   {
     return &link_next;
   }
-  st_select_lex_node* return_after_parsing()
+  st_select_lex* return_after_parsing()
   {
     return master_unit()->return_after_parsing();
   }
 
+  void mark_as_dependent(st_select_lex *last);
+
   bool set_braces(bool value);
   bool inc_in_sum_expr();
   uint get_in_sum_expr();
 
-  st_select_lex* select_lex();
   bool add_item_to_list(THD *thd, Item *item);
   bool add_group_to_list(THD *thd, Item *item, bool asc);
   bool add_ftfunc_to_list(Item_func_match *func);
-
-  TABLE_LIST* get_table_list();
-  List<Item>* get_item_list();
-  List<String>* get_use_index();
-  List<String>* get_ignore_index();
-  ulong get_table_join_options();
+  bool add_order_to_list(THD *thd, Item *item, bool asc);
   TABLE_LIST* add_table_to_list(THD *thd, Table_ident *table,
 				LEX_STRING *alias,
 				ulong table_options,
 				thr_lock_type flags= TL_UNLOCK,
 				List<String> *use_index= 0,
 				List<String> *ignore_index= 0);
+
+  TABLE_LIST* get_table_list();
+  List<Item>* get_item_list();
+  List<String>* get_use_index();
+  List<String>* get_ignore_index();
+  ulong get_table_join_options();
   void set_lock_for_tables(thr_lock_type lock_type);
   inline void init_order()
   {
@@ -422,15 +421,14 @@ public:
     order_list.next= (byte**) &order_list.first;
   }
   
+  bool test_limit();
+
   friend void mysql_init_query(THD *thd);
-  st_select_lex(struct st_lex *lex);
-  st_select_lex() :fake_select(0) {}
-  void make_empty_select(st_select_lex *last_select)
+  st_select_lex() {}
+  void make_empty_select()
   {
-    select_number=INT_MAX;
     init_query();
     init_select();
-    include_neighbour(last_select);
   }
 };
 typedef class st_select_lex SELECT_LEX;
@@ -445,7 +443,7 @@ typedef struct st_lex
   SELECT_LEX_UNIT unit;                         /* most upper unit */
   SELECT_LEX select_lex;                        /* first SELECT_LEX */
   /* current SELECT_LEX in parsing */
-  SELECT_LEX_NODE *current_select;
+  SELECT_LEX *current_select;
   /* list of all SELECT_LEX */
   SELECT_LEX *all_selects_list;
   uchar *ptr,*tok_start,*tok_end,*end_of_query;
@@ -517,7 +515,7 @@ typedef struct st_lex
       but we should merk all subselects as uncacheable from current till
       most upper
     */
-    SELECT_LEX_NODE *sl;
+    SELECT_LEX *sl;
     SELECT_LEX_UNIT *un;
     for (sl= current_select, un= sl->master_unit();
 	 un != &unit;
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 5070466007e8f41270a6cfe2db82900d49fa0e97..915bed8ae9c84ee684591a6693019e32ba630e36 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -3474,10 +3474,10 @@ mysql_init_query(THD *thd)
   lex->select_lex.init_query();
   lex->value_list.empty();
   lex->param_list.empty();
-  lex->unit.next= lex->unit.master= lex->unit.return_to= 
-    lex->unit.link_next= 0;
+  lex->unit.next= lex->unit.master= 
+    lex->unit.link_next= lex->unit.return_to=0;
   lex->unit.prev= lex->unit.link_prev= 0;
-  lex->unit.global_parameters= lex->unit.slave= lex->current_select=
+  lex->unit.slave= lex->unit.global_parameters= lex->current_select=
     lex->all_selects_list= &lex->select_lex;
   lex->select_lex.master= &lex->unit;
   lex->select_lex.prev= &lex->unit.slave;
@@ -3506,10 +3506,9 @@ mysql_init_query(THD *thd)
 void
 mysql_init_select(LEX *lex)
 {
-  SELECT_LEX *select_lex= lex->current_select->select_lex();
+  SELECT_LEX *select_lex= lex->current_select;
   select_lex->init_select();
-  select_lex->master_unit()->select_limit= select_lex->select_limit=
-    lex->thd->variables.select_limit;
+  select_lex->select_limit= lex->thd->variables.select_limit;
   if (select_lex == &lex->select_lex)
   {
     lex->exchange= 0;
@@ -3537,17 +3536,32 @@ mysql_new_select(LEX *lex, bool move_down)
     unit->init_query();
     unit->init_select();
     unit->thd= lex->thd;
-    if (lex->current_select->linkage == GLOBAL_OPTIONS_TYPE)
-      unit->include_neighbour(lex->current_select);
-    else
-      unit->include_down(lex->current_select);
+    unit->include_down(lex->current_select);
     unit->link_next= 0;
     unit->link_prev= 0;
     unit->return_to= lex->current_select;
     select_lex->include_down(unit);
   }
   else
+  {
     select_lex->include_neighbour(lex->current_select);
+    SELECT_LEX_UNIT *unit= select_lex->master_unit();
+    SELECT_LEX *fake= unit->fake_select_lex;
+    if (!fake)
+    {
+      /*
+	as far as we included SELECT_LEX for UNION unit should have
+	fake SELECT_LEX for UNION processing
+      */
+      fake= unit->fake_select_lex= new SELECT_LEX();
+      fake->include_standalone(unit,
+			       (SELECT_LEX_NODE**)&unit->fake_select_lex);
+      fake->select_number= INT_MAX;
+      fake->make_empty_select();
+      fake->linkage= GLOBAL_OPTIONS_TYPE;
+      fake->select_limit= lex->thd->variables.select_limit;
+    }
+  }
 
   select_lex->master_unit()->global_parameters= select_lex;
   select_lex->include_global((st_select_lex_node**)&lex->all_selects_list);
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index ca0f673954e88227b2c063277b90381387e5d0de..38c8cffdd22c2031262109d6853e8c6a84f82f5d 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -318,7 +318,7 @@ JOIN::prepare(Item ***rref_pointer_array,
   {
     Item_subselect *subselect;
     if ((subselect= select_lex->master_unit()->item) &&
-	!select_lex->fake_select)
+	select_lex->linkage != GLOBAL_OPTIONS_TYPE)
     {
       Item_subselect::trans_res res;
       if ((res= subselect->select_transformer(this)) !=
@@ -5713,7 +5713,8 @@ end_send(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
 	else 
 	{
 	  join->do_send_rows= 0;
-	  join->unit->select_limit= HA_POS_ERROR;
+	  if (join->unit->fake_select_lex)
+	    join->unit->fake_select_lex->select_limit= HA_POS_ERROR;
 	  DBUG_RETURN(0);
 	}
       }
diff --git a/sql/sql_union.cc b/sql/sql_union.cc
index 79e1e9843a86727604a7c19de9906748a3b7a789..7c9e6f0a24e4a183bd5804bcfa7d0d5a610d1cd2 100644
--- a/sql/sql_union.cc
+++ b/sql/sql_union.cc
@@ -115,7 +115,7 @@ bool select_union::flush()
 int st_select_lex_unit::prepare(THD *thd, select_result *sel_result,
 				bool tables_and_fields_initied)
 {
-  SELECT_LEX_NODE *lex_select_save= thd->lex.current_select;
+  SELECT_LEX *lex_select_save= thd->lex.current_select;
   SELECT_LEX *select_cursor;
   DBUG_ENTER("st_select_lex_unit::prepare");
 
@@ -241,7 +241,7 @@ err:
 int st_select_lex_unit::exec()
 {
   int do_print_slow= 0;
-  SELECT_LEX_NODE *lex_select_save= thd->lex.current_select;
+  SELECT_LEX *lex_select_save= thd->lex.current_select;
   SELECT_LEX *select_cursor=first_select_in_union();
   DBUG_ENTER("st_select_lex_unit::exec");
 
@@ -318,8 +318,7 @@ int st_select_lex_unit::exec()
 
   /* Send result to 'result' */
 
-  // to correct ORDER BY reference resolving
-  thd->lex.current_select= select_cursor;
+
   res= -1;
   {
     List<Item_func_match> empty_list;
@@ -327,8 +326,7 @@ int st_select_lex_unit::exec()
 
     if (!thd->is_fatal_error)			// Check if EOM
     {
-      SELECT_LEX *fake_select  = new SELECT_LEX(&thd->lex);
-      fake_select->fake_select= 1;
+      thd->lex.current_select= fake_select_lex;
       offset_limit_cnt= (select_cursor->braces ?
 			 global_parameters->offset_limit : 0);
       select_limit_cnt= (select_cursor->braces ?
@@ -338,19 +336,19 @@ int st_select_lex_unit::exec()
 	select_limit_cnt= HA_POS_ERROR;		// no limit
       if (select_limit_cnt == HA_POS_ERROR)
 	thd->options&= ~OPTION_FOUND_ROWS;
-      fake_select->ftfunc_list= &empty_list;
-      fake_select->table_list.link_in_list((byte *)&result_table_list,
-					   (byte **)&result_table_list.next);
-      res= mysql_select(thd, &ref_pointer_array, &result_table_list,
+      fake_select_lex->ftfunc_list= &empty_list;
+      fake_select_lex->table_list.link_in_list((byte *)&result_table_list,
+					       (byte **)
+					       &result_table_list.next);
+      res= mysql_select(thd, &fake_select_lex->ref_pointer_array,
+			&result_table_list,
 			0, item_list, NULL,
 			global_parameters->order_list.elements,
 			(ORDER*)global_parameters->order_list.first,
 			(ORDER*) NULL, NULL, (ORDER*) NULL,
-			thd->options, result, this, fake_select, 0);
+			thd->options, result, this, fake_select_lex, 0);
       if (found_rows_for_union && !res)
 	thd->limit_found_rows = (ulonglong)table->file->records;
-      fake_select->exclude();
-      delete fake_select;
       /*
 	Mark for slow query log if any of the union parts didn't use
 	indexes efficiently
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 659744ce677cc6767f07e403de163b5b5ce8988d..23ce607040d92a7aa26d7282f6e7d17427bcd577 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -1835,7 +1835,7 @@ table_to_table:
 	table_ident TO_SYM table_ident
 	{
 	  LEX *lex=Lex;	  
-	  SELECT_LEX_NODE *sl= lex->current_select;
+	  SELECT_LEX *sl= lex->current_select;
 	  if (!sl->add_table_to_list(lex->thd, $1,NULL,TL_OPTION_UPDATING,
 				     TL_IGNORE) ||
 	      !sl->add_table_to_list(lex->thd, $3,NULL,TL_OPTION_UPDATING,
@@ -1871,7 +1871,7 @@ preload_keys:
 	;
 
 preload_keys_spec:
-	keys_or_index { Select->select_lex()->interval_list.empty(); }
+	keys_or_index { Select->interval_list.empty(); }
 	preload_key_list_or_empty 
 	{
 	  LEX *lex=Lex;
@@ -1907,7 +1907,7 @@ select_init:
 	'(' SELECT_SYM select_part2 ')'
 	  {
 	    LEX *lex= Lex;
-            SELECT_LEX * sel= lex->current_select->select_lex();
+            SELECT_LEX * sel= lex->current_select;
 	    if (sel->set_braces(1))
 	    {
 	      send_error(lex->thd, ER_SYNTAX_ERROR);
@@ -1921,14 +1921,14 @@ select_init:
 	  }
             /* select in braces, can't contain global parameters */
             sel->master_unit()->global_parameters=
-               sel->master_unit();
+               sel->master_unit()->fake_select_lex;
           } union_opt;
 
 select_init2:
 	select_part2
         {
 	  LEX *lex= Lex;
-          SELECT_LEX * sel= lex->current_select->select_lex();
+          SELECT_LEX * sel= lex->current_select;
           if (lex->current_select->set_braces(0))
 	  {
 	    send_error(lex->thd, ER_SYNTAX_ERROR);
@@ -1947,7 +1947,7 @@ select_init2:
 select_part2:
 	{
 	  LEX *lex=Lex;
-	  SELECT_LEX * sel= lex->current_select->select_lex();
+	  SELECT_LEX * sel= lex->current_select;
 	  if (lex->current_select == &lex->select_lex)
 	    lex->lock_option= TL_READ; /* Only for global SELECT */
 	  if (sel->linkage != UNION_TYPE)
@@ -2038,7 +2038,7 @@ select_item_list:
 	    THD *thd= YYTHD;
 	    if (add_item_to_list(thd, new Item_field(NULL, NULL, "*")))
 	      YYABORT;
-	    (thd->lex.current_select->select_lex()->with_wild)++;
+	    (thd->lex.current_select->with_wild)++;
 	  };
 
 
@@ -2668,9 +2668,9 @@ sum_expr:
 	| COUNT_SYM '(' in_sum_expr ')'
 	  { $$=new Item_sum_count($3); }
 	| COUNT_SYM '(' DISTINCT
-	  { Select->select_lex()->in_sum_expr++; }
+	  { Select->in_sum_expr++; }
 	   expr_list
-	  { Select->select_lex()->in_sum_expr--; }
+	  { Select->in_sum_expr--; }
 	  ')'
 	  { $$=new Item_sum_count_distinct(* $5); }
 	| GROUP_UNIQUE_USERS '(' text_literal ',' NUM ',' NUM ',' in_sum_expr ')'
@@ -2726,7 +2726,7 @@ in_sum_expr:
 	}
 	expr
 	{
-	  Select->select_lex()->in_sum_expr--;
+	  Select->in_sum_expr--;
 	  $$= $3;
 	};
 
@@ -2780,13 +2780,13 @@ when_list:
 when_list2:
 	expr THEN_SYM expr
 	  {
-	    SELECT_LEX_NODE *sel=Select;
+	    SELECT_LEX *sel=Select;
 	    sel->when_list.head()->push_back($1);
 	    sel->when_list.head()->push_back($3);
 	}
 	| when_list2 WHEN_SYM expr THEN_SYM expr
 	  {
-	    SELECT_LEX_NODE *sel=Select;
+	    SELECT_LEX *sel=Select;
 	    sel->when_list.head()->push_back($3);
 	    sel->when_list.head()->push_back($5);
 	  };
@@ -2803,7 +2803,7 @@ join_table_list:
 	| join_table_list normal_join join_table_list
 	  USING 
 	  {
-	    SELECT_LEX *sel= Select->select_lex();
+	    SELECT_LEX *sel= Select;
 	    sel->db1=$1->db; sel->table1=$1->alias;
 	    sel->db2=$3->db; sel->table2=$3->alias;
 	  }
@@ -2814,7 +2814,7 @@ join_table_list:
 	  { add_join_on($5,$7); $5->outer_join|=JOIN_TYPE_LEFT; $$=$5; }
 	| join_table_list LEFT opt_outer JOIN_SYM join_table_list
 	  {
-	    SELECT_LEX *sel= Select->select_lex();
+	    SELECT_LEX *sel= Select;
 	    sel->db1=$1->db; sel->table1=$1->alias;
 	    sel->db2=$5->db; sel->table2=$5->alias;
 	  }
@@ -2830,7 +2830,7 @@ join_table_list:
 	  { add_join_on($1,$7); $1->outer_join|=JOIN_TYPE_RIGHT; $$=$5; }
 	| join_table_list RIGHT opt_outer JOIN_SYM join_table_list
 	  {
-	    SELECT_LEX *sel= Select->select_lex();
+	    SELECT_LEX *sel= Select;
 	    sel->db1=$1->db; sel->table1=$1->alias;
 	    sel->db2=$5->db; sel->table2=$5->alias;
 	  }
@@ -2853,14 +2853,14 @@ normal_join:
 
 join_table:
 	{
-	  SELECT_LEX *sel= Select->select_lex();
+	  SELECT_LEX *sel= Select;
 	  sel->use_index_ptr=sel->ignore_index_ptr=0;
 	  sel->table_join_options= 0;
 	}
         table_ident opt_table_alias opt_key_definition
 	{
 	  LEX *lex= Lex;
-	  SELECT_LEX_NODE *sel= lex->current_select;
+	  SELECT_LEX *sel= lex->current_select;
 	  if (!($$= sel->add_table_to_list(lex->thd, $2, $3,
 					   sel->get_table_join_options(),
 					   lex->lock_option,
@@ -2910,28 +2910,28 @@ opt_key_definition:
 	/* empty */	{}
 	| USE_SYM    key_usage_list
           {
-	    SELECT_LEX *sel= Select->select_lex();
+	    SELECT_LEX *sel= Select;
 	    sel->use_index= *$2;
 	    sel->use_index_ptr= &sel->use_index;
 	  }
 	| FORCE_SYM key_usage_list
           {
-	    SELECT_LEX *sel= Select->select_lex();
+	    SELECT_LEX *sel= Select;
 	    sel->use_index= *$2;
 	    sel->use_index_ptr= &sel->use_index;
 	    sel->table_join_options|= TL_OPTION_FORCE_INDEX;
 	  }
 	| IGNORE_SYM key_usage_list
 	  {
-	    SELECT_LEX *sel= Select->select_lex();
+	    SELECT_LEX *sel= Select;
 	    sel->ignore_index= *$2;
 	    sel->ignore_index_ptr= &sel->ignore_index;
 	  };
 
 key_usage_list:
-	key_or_index { Select->select_lex()->interval_list.empty(); }
+	key_or_index { Select->interval_list.empty(); }
         '(' key_list_or_empty ')'
-        { $$= &Select->select_lex()->interval_list; }
+        { $$= &Select->interval_list; }
 	;
 
 key_list_or_empty:
@@ -2941,22 +2941,22 @@ key_list_or_empty:
 
 key_usage_list2:
 	key_usage_list2 ',' ident
-        { Select->select_lex()->
+        { Select->
 	    interval_list.push_back(new String((const char*) $3.str, $3.length,
 				    system_charset_info)); }
 	| ident
-        { Select->select_lex()->
+        { Select->
 	    interval_list.push_back(new String((const char*) $1.str, $1.length,
 				    system_charset_info)); }
 	| PRIMARY_SYM
-        { Select->select_lex()->
+        { Select->
 	    interval_list.push_back(new String("PRIMARY", 7,
 				    system_charset_info)); };
 
 using_list:
 	ident
 	  {
-	    SELECT_LEX *sel= Select->select_lex();
+	    SELECT_LEX *sel= Select;
 	    if (!($$= new Item_func_eq(new Item_field(sel->db1, sel->table1,
 						      $1.str),
 				       new Item_field(sel->db2, sel->table2,
@@ -2965,7 +2965,7 @@ using_list:
 	  }
 	| using_list ',' ident
 	  {
-	    SELECT_LEX *sel= Select->select_lex();
+	    SELECT_LEX *sel= Select;
 	    if (!($$= new Item_cond_and(new Item_func_eq(new Item_field(sel->db1,sel->table1,$3.str), new Item_field(sel->db2,sel->table2,$3.str)), $1)))
 	      YYABORT;
 	  };
@@ -3001,10 +3001,10 @@ opt_all:
 	;
 
 where_clause:
-	/* empty */  { Select->select_lex()->where= 0; }
+	/* empty */  { Select->where= 0; }
 	| WHERE expr
 	  {
-	    Select->select_lex()->where= $2;
+	    Select->where= $2;
 	    if ($2)
 	      $2->top_level_item();
 	  }
@@ -3014,11 +3014,11 @@ having_clause:
 	/* empty */
 	| HAVING
 	  {
-	    Select->select_lex()->parsing_place= SELECT_LEX_NODE::IN_HAVING;
+	    Select->parsing_place= SELECT_LEX_NODE::IN_HAVING;
           }
 	  expr
 	  {
-	    SELECT_LEX *sel= Select->select_lex();
+	    SELECT_LEX *sel= Select;
 	    sel->having= $3;
 	    sel->parsing_place= SELECT_LEX_NODE::NO_MATTER;
 	    if ($3)
@@ -3056,7 +3056,7 @@ olap_opt:
 		       "global union parameters");
 	      YYABORT;
 	    }
-	    lex->current_select->select_lex()->olap= CUBE_TYPE;
+	    lex->current_select->olap= CUBE_TYPE;
 	    net_printf(lex->thd, ER_NOT_SUPPORTED_YET, "CUBE");
 	    YYABORT;	/* To be deleted in 5.1 */
 	  }
@@ -3069,7 +3069,7 @@ olap_opt:
 		       "global union parameters");
 	      YYABORT;
 	    }
-	    lex->current_select->select_lex()->olap= ROLLUP_TYPE;
+	    lex->current_select->olap= ROLLUP_TYPE;
 	  }
 	;
 
@@ -3086,7 +3086,7 @@ order_clause:
         {
 	  LEX *lex=Lex;
 	  if (lex->current_select->linkage != GLOBAL_OPTIONS_TYPE &&
-	      lex->current_select->select_lex()->olap !=
+	      lex->current_select->olap !=
 	      UNSPECIFIED_OLAP_TYPE)
 	  {
 	    net_printf(lex->thd, ER_WRONG_USAGE,
@@ -3111,7 +3111,7 @@ order_dir:
 opt_limit_clause_init:
 	/* empty */
 	{
-	  SELECT_LEX_NODE *sel= Select;
+	  SELECT_LEX *sel= Select;
           sel->offset_limit= 0L;
           sel->select_limit= Lex->thd->variables.select_limit;
 	}
@@ -3130,19 +3130,19 @@ limit_clause:
 limit_options:
 	ULONG_NUM
 	  {
-            SELECT_LEX_NODE *sel= Select;
+            SELECT_LEX *sel= Select;
             sel->select_limit= $1;
             sel->offset_limit= 0L;
 	  }
 	| ULONG_NUM ',' ULONG_NUM
 	  {
-	    SELECT_LEX_NODE *sel= Select;
+	    SELECT_LEX *sel= Select;
 	    sel->select_limit= $3;
 	    sel->offset_limit= $1;
 	  }
 	| ULONG_NUM OFFSET_SYM ULONG_NUM
 	  {
-	    SELECT_LEX_NODE *sel= Select;
+	    SELECT_LEX *sel= Select;
 	    sel->select_limit= $1;
 	    sel->offset_limit= $3;
 	  }
@@ -4117,14 +4117,14 @@ table_wild:
 	ident '.' '*' 
 	{
 	  $$ = new Item_field(NullS,$1.str,"*");
-	  Lex->current_select->select_lex()->with_wild++;
+	  Lex->current_select->with_wild++;
 	}
 	| ident '.' ident '.' '*'
 	{
 	  $$ = new Item_field((YYTHD->client_capabilities &
    			     CLIENT_NO_SCHEMA ? NullS : $1.str),
 			     $3.str,"*");
-	  Lex->current_select->select_lex()->with_wild++;
+	  Lex->current_select->with_wild++;
 	}
 	;
 
@@ -4134,7 +4134,7 @@ order_ident:
 simple_ident:
 	ident
 	{
-	  SELECT_LEX_NODE *sel=Select;
+	  SELECT_LEX *sel=Select;
 	  $$= (sel->parsing_place != SELECT_LEX_NODE::IN_HAVING ||
 	       sel->get_in_sum_expr() > 0) ?
               (Item*) new Item_field(NullS,NullS,$1.str) :
@@ -4144,7 +4144,7 @@ simple_ident:
 	{
 	  THD *thd= YYTHD;
 	  LEX *lex= &thd->lex;
-	  SELECT_LEX_NODE *sel= lex->current_select;
+	  SELECT_LEX *sel= lex->current_select;
 	  if (sel->no_table_names_allowed)
 	  {
 	    my_printf_error(ER_TABLENAME_NOT_ALLOWED_HERE, 
@@ -4160,7 +4160,7 @@ simple_ident:
 	{
 	  THD *thd= YYTHD;
 	  LEX *lex= &thd->lex;
-	  SELECT_LEX_NODE *sel= lex->current_select;
+	  SELECT_LEX *sel= lex->current_select;
 	  if (sel->no_table_names_allowed)
 	  {
 	    my_printf_error(ER_TABLENAME_NOT_ALLOWED_HERE, 
@@ -4176,7 +4176,7 @@ simple_ident:
 	{
 	  THD *thd= YYTHD;
 	  LEX *lex= &thd->lex;
-	  SELECT_LEX_NODE *sel= lex->current_select;
+	  SELECT_LEX *sel= lex->current_select;
 	  if (sel->no_table_names_allowed)
 	  {
 	    my_printf_error(ER_TABLENAME_NOT_ALLOWED_HERE, 
@@ -4858,7 +4858,7 @@ opt_table:
 	'*'
 	  {
 	    LEX *lex= Lex;
-	    lex->current_select->select_lex()->db= lex->thd->db;
+	    lex->current_select->db= lex->thd->db;
 	    if (lex->grant == GLOBAL_ACLS)
 	      lex->grant = DB_ACLS & ~GRANT_ACL;
 	    else if (lex->columns.elements)
@@ -4870,7 +4870,7 @@ opt_table:
 	| ident '.' '*'
 	  {
 	    LEX *lex= Lex;
-	    lex->current_select->select_lex()->db = $1.str;
+	    lex->current_select->db = $1.str;
 	    if (lex->grant == GLOBAL_ACLS)
 	      lex->grant = DB_ACLS & ~GRANT_ACL;
 	    else if (lex->columns.elements)
@@ -4882,7 +4882,7 @@ opt_table:
 	| '*' '.' '*'
 	  {
 	    LEX *lex= Lex;
-	    lex->current_select->select_lex()->db = NULL;
+	    lex->current_select->db = NULL;
 	    if (lex->grant == GLOBAL_ACLS)
 	      lex->grant= GLOBAL_ACLS & ~GRANT_ACL;
 	    else if (lex->columns.elements)
@@ -5077,11 +5077,12 @@ optional_order_or_limit:
 	    THD *thd= YYTHD;
 	    LEX *lex= &thd->lex;
 	    DBUG_ASSERT(lex->current_select->linkage != GLOBAL_OPTIONS_TYPE);
-	    SELECT_LEX *sel= lex->current_select->select_lex();
+	    SELECT_LEX *sel= lex->current_select;
 	    SELECT_LEX_UNIT *unit= sel->master_unit();
-	    unit->global_parameters= unit;
-	    unit->no_table_names_allowed= 1;
-	    lex->current_select= unit;
+	    SELECT_LEX *fake= unit->fake_select_lex;
+	    unit->global_parameters= fake;
+	    fake->no_table_names_allowed= 1;
+	    lex->current_select= fake;
 	    thd->where= "global ORDER clause";
 	  }
 	order_or_limit