diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index f939709f7435a770067f99ee5fe8098637341298..053eb9e6fef8e11413690272414792ff6ea1dbce 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -385,7 +385,7 @@ bool Item_in_optimizer::fix_left(THD *thd,
   cache->store(args[0]);
   if (cache->cols() == 1)
   {
-    if (args[0]->used_tables())
+    if ((used_tables_cache= args[0]->used_tables()))
       cache->set_used_tables(OUTER_REF_TABLE_BIT);
     else
       cache->set_used_tables(0);
@@ -400,7 +400,11 @@ bool Item_in_optimizer::fix_left(THD *thd,
       else
 	((Item_cache *)cache->el(i))->set_used_tables(0);
     }
+    used_tables_cache= args[0]->used_tables();
   }
+  not_null_tables_cache= args[0]->not_null_tables();
+  with_sum_func= args[0]->with_sum_func;
+  const_item_cache= args[0]->const_item();
   return 0;
 }
 
@@ -414,9 +418,6 @@ bool Item_in_optimizer::fix_fields(THD *thd, struct st_table_list *tables,
   if (args[0]->maybe_null)
     maybe_null=1;
 
-  with_sum_func= args[0]->with_sum_func;
-  used_tables_cache= args[0]->used_tables();
-  const_item_cache= args[0]->const_item();
   if (!args[1]->fixed && args[1]->fix_fields(thd, tables, args))
     return 1;
   Item_in_subselect * sub= (Item_in_subselect *)args[1];
@@ -429,6 +430,7 @@ bool Item_in_optimizer::fix_fields(THD *thd, struct st_table_list *tables,
     maybe_null=1;
   with_sum_func= with_sum_func || args[1]->with_sum_func;
   used_tables_cache|= args[1]->used_tables();
+  not_null_tables_cache|= args[1]->not_null_tables();
   const_item_cache&= args[1]->const_item();
   return 0;
 }
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index 36b65ef486ea2b49ede50b366ed53070120c5f58..cbda995504c4a1b525f6d23077ef1a4eea04ffce 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -148,7 +148,7 @@ void Item_subselect::fix_length_and_dec()
 inline table_map Item_subselect::used_tables() const
 {
   return (table_map) (engine->dependent() ? 1L :
-		      (engine->uncacheable() ? OUTER_REF_TABLE_BIT : 0L));
+		      (engine->uncacheable() ? RAND_TABLE_BIT : 0L));
 }
 
 Item_singlerow_subselect::Item_singlerow_subselect(THD *thd,
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index 9787f9f208d04b0f46b16eaa898ebdfbe0ff4c3c..a5d9ce5bce372ab69d199471795927bd32182468 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -983,7 +983,7 @@ inline void setup_table_map(TABLE *table, TABLE_LIST *table_list, uint tablenr)
 {
   table->used_fields= 0;
   table->const_table= 0;
-  table->outer_join= table->null_row= 0;
+  table->null_row= 0;
   table->status= STATUS_NO_RECORD;
   table->keys_in_use_for_query= table->keys_in_use;
   table->maybe_null= test(table->outer_join= table_list->outer_join);
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index d8ee525760e97f127a3478f33b4ab4ad4932f8e6..573ca724fe24b016230a0d0aca52dbcf113b4f69 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -3614,7 +3614,7 @@ mysql_new_select(LEX *lex, bool move_down)
   if (move_down)
   {
     /* first select_lex of subselect or derived table */
-    SELECT_LEX_UNIT *unit= new SELECT_LEX_UNIT();
+    SELECT_LEX_UNIT *unit= new(&lex->thd->mem_root) SELECT_LEX_UNIT();
     if (!unit)
       return 1;
     unit->init_query();
@@ -3638,7 +3638,7 @@ mysql_new_select(LEX *lex, bool move_down)
 	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= unit->fake_select_lex= new(&lex->thd->mem_root) SELECT_LEX();
       fake->include_standalone(unit,
 			       (SELECT_LEX_NODE**)&unit->fake_select_lex);
       fake->select_number= INT_MAX;
diff --git a/sql/sql_union.cc b/sql/sql_union.cc
index 2a657e9d20de436f779d77f09825766403d5501e..5e9a50d038e8667604dfa4a01eb2154585865283 100644
--- a/sql/sql_union.cc
+++ b/sql/sql_union.cc
@@ -349,6 +349,11 @@ int st_select_lex_unit::exec()
 	  mysql_select automatic allocation)
 	*/
 	fake_select_lex->join= new JOIN(thd, item_list, thd->options, result);
+	/*
+	  Fake st_select_lex should have item list for correctref_array
+	  allocation.
+	*/
+	fake_select_lex->item_list= item_list;
       }
       else
       {
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index ed46be78d9ac23370281201cce424e842149273c..e27279c148fc9e1d21559ccad147236003d61eb4 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -965,7 +965,7 @@ create_select:
 	      lex->sql_command= SQLCOM_INSERT_SELECT;
 	    else if (lex->sql_command == SQLCOM_REPLACE)
 	      lex->sql_command= SQLCOM_REPLACE_SELECT;
-	    lex->current_select->select_lex()->table_list.save_and_clear(&lex->save_list);
+	    lex->current_select->table_list.save_and_clear(&lex->save_list);
 	    mysql_init_select(lex);
 	    lex->current_select->parsing_place= SELECT_LEX_NODE::SELECT_LIST;
           }
@@ -974,7 +974,7 @@ create_select:
 	    Select->parsing_place= SELECT_LEX_NODE::NO_MATTER;
 	  }
 	  opt_select_from
-	  { Lex->current_select->select_lex()->table_list.push_front(&Lex->save_list); }
+	  { Lex->current_select->table_list.push_front(&Lex->save_list); }
         ;
 
 opt_as: